[BACK]Return to tunerctl.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tunerctl

Annotation of src/usr.bin/tunerctl/tunerctl.c, Revision 1.1

1.1     ! jakemsr     1: /*
        !             2:  * Copyright (c) 2005 Jacob Meuser <jakemsr@jakemsr.com>
        !             3:  *
        !             4:  * Permission to use, copy, modify, and distribute this software for any
        !             5:  * purpose with or without fee is hereby granted, provided that the above
        !             6:  * copyright notice and this permission notice appear in all copies.
        !             7:  *
        !             8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !             9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            15:  */
        !            16:
        !            17: /*
        !            18:  *  $OpenBSD$
        !            19:  */
        !            20:
        !            21:
        !            22: #include <sys/param.h>
        !            23: #include <sys/ioctl.h>
        !            24: #include <sys/stat.h>
        !            25:
        !            26: #include <dev/ic/bt8xx.h>
        !            27:
        !            28: #include <err.h>
        !            29: #include <fcntl.h>
        !            30: #include <stdio.h>
        !            31: #include <stdlib.h>
        !            32: #include <string.h>
        !            33: #include <unistd.h>
        !            34:
        !            35: #define DEFAULT_TUNER_DEVICE "/dev/tuner0"
        !            36:
        !            37: struct fields {
        !            38:        char    *name;
        !            39:        int      type;
        !            40: #define INT    1
        !            41: #define ASRC   2
        !            42: #define CSET   3
        !            43: #define MUTE   4
        !            44: #define OFFON  5
        !            45: #define FREQ   6
        !            46: #define VSAT   7
        !            47: #define USAT   8
        !            48: #define HUE    9
        !            49: #define BRIGHT 10
        !            50: #define CONTR  11
        !            51:        int      val;
        !            52:        long     io_set;
        !            53:        long     io_get;
        !            54:        int      valmin;
        !            55:        int      valmax;
        !            56: } fields[] = {
        !            57: { "chanset",   CSET,   0, TVTUNER_SETTYPE, TVTUNER_GETTYPE,    0, 0 },
        !            58: { "channel",   INT,    0, TVTUNER_SETCHNL, TVTUNER_GETCHNL,    0, 150 },
        !            59: { "freq",      FREQ,   0, TVTUNER_SETFREQ, TVTUNER_GETFREQ,    608, 14240 },
        !            60: { "afc",       OFFON,  0, TVTUNER_SETAFC,  TVTUNER_GETAFC,     0, 1 },
        !            61: { "audio",     ASRC,   0, BT848_SAUDIO,    BT848_GAUDIO,       0, 0 },
        !            62: { "mute",      MUTE,   0, BT848_SAUDIO,    BT848_GAUDIO,       0, 1 },
        !            63: { "bright",    BRIGHT, 0, BT848_SBRIG,     BT848_GBRIG,
        !            64:     BT848_BRIGHTMIN, BT848_BRIGHTMAX },
        !            65: { "contrast",  CONTR,  0, BT848_SCONT,     BT848_GCONT,
        !            66:     BT848_CONTRASTMIN, BT848_CONTRASTMAX },
        !            67: { "hue",       HUE,    0, BT848_SHUE,      BT848_GHUE,         BT848_HUEMIN,
        !            68:     BT848_HUEMAX },
        !            69: { "usat",      USAT,   0, BT848_SUSAT,     BT848_GUSAT,        BT848_SATUMIN,
        !            70:     BT848_SATUMAX },
        !            71: { "vsat",      VSAT,   0, BT848_SVSAT,     BT848_GVSAT,        BT848_SATVMIN,
        !            72:     BT848_SATVMAX },
        !            73: { 0, 0, 0, 0, 0, 0, 0}
        !            74: };
        !            75:
        !            76: struct chansets {
        !            77:        int value;
        !            78:        char *name;
        !            79: } chansets[] = {
        !            80: { CHNLSET_NABCST,      "nabcst",       },
        !            81: { CHNLSET_CABLEIRC,    "cableirc",     },
        !            82: { CHNLSET_CABLEHRC,    "cablehrc",     },
        !            83: { CHNLSET_WEUROPE,     "weurope",      },
        !            84: { CHNLSET_JPNBCST,     "jpnbcst",      },
        !            85: { CHNLSET_JPNCABLE,    "jpncable",     },
        !            86: { CHNLSET_XUSSR,       "xussr",        },
        !            87: { CHNLSET_AUSTRALIA,   "australia",    },
        !            88: { CHNLSET_FRANCE,      "france",       },
        !            89: { 0, 0 }
        !            90: };
        !            91:
        !            92: struct audiosources {
        !            93:        int value;
        !            94:        char *name;
        !            95: } audiosources[] = {
        !            96: { AUDIO_TUNER,         "tuner",        },
        !            97: { AUDIO_EXTERN,                "extern",       },
        !            98: { AUDIO_INTERN,                "intern",       },
        !            99: { 0, 0 }
        !           100: };
        !           101:
        !           102: int     tuner_fd;
        !           103: int     print_choices;
        !           104: int     print_name;
        !           105: int     print_value;
        !           106:
        !           107: __dead void usage(void);
        !           108: int     run(int, char *);
        !           109: int     findfield(char *);
        !           110: int     prfield(int);
        !           111: int     do_ioctls(int, char *);
        !           112: #define OFF    0
        !           113: #define        ON      1
        !           114: int     isoffon(const char *);
        !           115:
        !           116:
        !           117: /* getopt externs */
        !           118: extern char *optarg;
        !           119: extern int opterr;
        !           120: extern int optind;
        !           121: extern int optopt;
        !           122: extern int optreset;
        !           123:
        !           124:
        !           125: __dead void
        !           126: usage(void)
        !           127: {
        !           128:        extern char *__progname;
        !           129:
        !           130:        fprintf(stderr,
        !           131:                "usage: %s [-nv] [-f file] -a\n"
        !           132:                "       %s [-nv] [-f file] name [...]\n"
        !           133:                "       %s [-q]  [-f file] name=value [...]\n",
        !           134:                        __progname, __progname, __progname);
        !           135:
        !           136:        exit (1);
        !           137: }
        !           138:
        !           139: int
        !           140: isoffon(const char *offon)
        !           141: {
        !           142:        if (strncmp(offon, "off", 3) == 0)
        !           143:                return (OFF);
        !           144:        else if (strncmp(offon, "on", 2) == 0)
        !           145:                return (ON);
        !           146:
        !           147:        return (-1);
        !           148: }
        !           149:
        !           150: int
        !           151: findfield(char *name)
        !           152: {
        !           153:        int i, found = 0;
        !           154:
        !           155:        for (i = 0; fields[i].name; i++) {
        !           156:                if (strncmp(fields[i].name, name, strlen(fields[i].name)) ==0) {
        !           157:                        found = 1;
        !           158:                        break;
        !           159:                }
        !           160:        }
        !           161:        if (found == 1)
        !           162:                return (i);
        !           163:        else
        !           164:                return (-1);
        !           165: }
        !           166:
        !           167: int
        !           168: prfield(int index)
        !           169: {
        !           170:        int     switchval;
        !           171:        int     i;
        !           172:
        !           173:        if (print_name == 1)
        !           174:                printf("%s=", fields[index].name);
        !           175:
        !           176:        if (ioctl(tuner_fd, fields[index].io_get, &fields[index].val) < 0) {
        !           177:                warn("%s", fields[index].name);
        !           178:                return (1);
        !           179:        }
        !           180:
        !           181:        switchval = fields[index].type;
        !           182:        switch (switchval) {
        !           183:        case ASRC:
        !           184:                for (i = 0; audiosources[i].name; i++)
        !           185:                        if (audiosources[i].value ==
        !           186:                            (fields[index].val & ~AUDIO_MUTE))
        !           187:                                break;
        !           188:                printf("%s", audiosources[i].name);
        !           189:                if (print_choices == 1) {
        !           190:                        printf("  [ ");
        !           191:                        for (i = 0; audiosources[i].name; i++)
        !           192:                                printf("%s ", audiosources[i].name);
        !           193:                        printf("]");
        !           194:                }
        !           195:                break;
        !           196:        case CSET:
        !           197:                for (i = 0; chansets[i].name; i++)
        !           198:                        if (chansets[i].value == fields[index].val)
        !           199:                                break;
        !           200:                printf("%s", chansets[i].name);
        !           201:                if (print_choices == 1) {
        !           202:                        printf("  [ ");
        !           203:                        for (i = 0; chansets[i].name; i++)
        !           204:                                printf("%s ", chansets[i].name);
        !           205:                        printf("]");
        !           206:                }
        !           207:                break;
        !           208:        case FREQ:
        !           209:                printf("%0.2f", (double)fields[index].val / 16);
        !           210:                if (print_choices == 1)
        !           211:                        printf("  ( %0.2f - %0.2f )",
        !           212:                            (double)fields[index].valmin / 16,
        !           213:                            (double)fields[index].valmax / 16);
        !           214:                break;
        !           215:        case INT:
        !           216:        case BRIGHT:
        !           217:        case CONTR:
        !           218:        case HUE:
        !           219:        case VSAT:
        !           220:        case USAT:
        !           221:                i = fields[index].val;
        !           222:                if (switchval == BRIGHT) {
        !           223:                        i = (i - BT848_BRIGHTREGMIN) *
        !           224:                            BT848_BRIGHTRANGE / BT848_BRIGHTSTEPS +
        !           225:                            BT848_BRIGHTMIN + (i < 0 ? -0.5 : 0.5);
        !           226:                } else if (switchval == CONTR) {
        !           227:                        i = (i - BT848_CONTRASTREGMIN) *
        !           228:                            BT848_CONTRASTRANGE / BT848_CONTRASTSTEPS +
        !           229:                            BT848_CONTRASTMIN + (i < 0 ? -0.5 : 0.5);
        !           230:                } else if (switchval == HUE) {
        !           231:                        i = (i - BT848_HUEREGMIN) *
        !           232:                            BT848_HUERANGE / BT848_HUESTEPS +
        !           233:                            BT848_HUEMIN + (i < 0 ? -0.5 : 0.5);
        !           234:                } else if (switchval == USAT) {
        !           235:                        i = (i - BT848_SATUREGMIN) *
        !           236:                            BT848_SATURANGE / BT848_SATUSTEPS +
        !           237:                            BT848_SATUMIN + (i < 0 ? -0.5 : 0.5);
        !           238:                } else if (switchval == VSAT) {
        !           239:                        i = (i - BT848_SATVREGMIN) *
        !           240:                            BT848_SATVRANGE / BT848_SATVSTEPS +
        !           241:                            BT848_SATVMIN + (i < 0 ? -0.5 : 0.5);
        !           242:                }
        !           243:                printf("%d", i);
        !           244:                if (print_choices == 1)
        !           245:                        printf("  ( %d - %d )", fields[index].valmin,
        !           246:                            fields[index].valmax);
        !           247:                break;
        !           248:        case MUTE:
        !           249:        case OFFON:
        !           250:                if (((switchval == MUTE) && (fields[index].val & AUDIO_MUTE)) ||
        !           251:                    ((switchval != MUTE) && (fields[index].val == 1)))
        !           252:                        printf("on");
        !           253:                else
        !           254:                        printf("off");
        !           255:                if (print_choices == 1)
        !           256:                        printf("  [ off on ]");
        !           257:                break;
        !           258:        default:
        !           259:                warnx("internal error: prfield");
        !           260:                break;
        !           261:        }
        !           262:        printf("\n");
        !           263:
        !           264:        return (0);
        !           265: }
        !           266:
        !           267: int
        !           268: do_ioctls(int index, char *arg)
        !           269: {
        !           270:        const char *errstr;
        !           271:        int      i;
        !           272:        int      switchval;
        !           273:
        !           274:        switchval = fields[index].type;
        !           275:
        !           276:        if (arg != NULL) {
        !           277:                switch(switchval) {
        !           278:                case ASRC:
        !           279:                        for (i = 0; audiosources[i].name; i++)
        !           280:                                if (strncmp(audiosources[i].name, arg,
        !           281:                                    strlen(audiosources[i].name)) == 0)
        !           282:                                        break;
        !           283:                        if (audiosources[i].name[0] != '\0')
        !           284:                                fields[index].val = audiosources[i].value;
        !           285:                        else {
        !           286:                                warnx("%s is invalid: %s", fields[index].name,
        !           287:                                    arg);
        !           288:                                return (1);
        !           289:                        }
        !           290:                        break;
        !           291:                case CSET:
        !           292:                        for (i = 0; chansets[i].name; i++)
        !           293:                                if (strncmp(chansets[i].name, arg,
        !           294:                                    strlen(chansets[i].name)) == 0)
        !           295:                                        break;
        !           296:                        if (chansets[i].name[0] != '\0')
        !           297:                                fields[index].val = chansets[i].value;
        !           298:                        else {
        !           299:                                warnx("%s is invalid: %s", fields[index].name,
        !           300:                                    arg);
        !           301:                                return (1);
        !           302:                        }
        !           303:                        break;
        !           304:                case FREQ:
        !           305:                        fields[index].val = strtod(arg, (char **)NULL) * 16;
        !           306:                        if ((fields[index].val < fields[index].valmin) ||
        !           307:                            (fields[index].val > fields[index].valmax)) {
        !           308:                                warnx("%s is invalid: %s", fields[index].name,
        !           309:                                    arg);
        !           310:                                return (1);
        !           311:                        }
        !           312:                        break;
        !           313:                case INT:
        !           314:                case BRIGHT:
        !           315:                case CONTR:
        !           316:                case HUE:
        !           317:                case USAT:
        !           318:                case VSAT:
        !           319:                        i = strtonum(arg, fields[index].valmin,
        !           320:                            fields[index].valmax, &errstr);
        !           321:                        if (errstr != NULL) {
        !           322:                                warnx("%s is %s: %s", fields[index].name,
        !           323:                                    errstr, arg);
        !           324:                                return (1);
        !           325:                        }
        !           326:                        if (switchval == BRIGHT) {
        !           327:                                i = (i - BT848_BRIGHTMIN) *
        !           328:                                    BT848_BRIGHTSTEPS / BT848_BRIGHTRANGE +
        !           329:                                    BT848_BRIGHTREGMIN + (i < 0 ? -0.5 : 0.5);
        !           330:                                if (i > BT848_BRIGHTREGMAX)
        !           331:                                        i = BT848_BRIGHTREGMAX;
        !           332:                        } else if (switchval == CONTR) {
        !           333:                                i = (i - BT848_CONTRASTMIN) *
        !           334:                                    BT848_CONTRASTSTEPS / BT848_CONTRASTRANGE +
        !           335:                                    BT848_CONTRASTREGMIN + (i < 0 ? -0.5 : 0.5);
        !           336:                                if (i > BT848_CONTRASTREGMAX)
        !           337:                                        i = BT848_CONTRASTREGMAX;
        !           338:                        } else if (switchval == HUE) {
        !           339:                                i = (i - BT848_HUEMIN) *
        !           340:                                    BT848_HUESTEPS / BT848_HUERANGE +
        !           341:                                    BT848_HUEREGMIN + (i < 0 ? -0.5 : 0.5);
        !           342:                                if (i > BT848_HUEREGMAX)
        !           343:                                        i = BT848_HUEREGMAX;
        !           344:                        } else if (switchval == USAT) {
        !           345:                                i = (i - BT848_SATUMIN) *
        !           346:                                    BT848_SATUSTEPS / BT848_SATURANGE +
        !           347:                                    BT848_SATUREGMIN + (i < 0 ? -0.5 : 0.5);
        !           348:                                if (i > BT848_SATUREGMAX)
        !           349:                                        i = BT848_SATUREGMAX;
        !           350:                        } else if (switchval == VSAT) {
        !           351:                                i = (i - BT848_SATVMIN) *
        !           352:                                    BT848_SATVSTEPS / BT848_SATVRANGE +
        !           353:                                    BT848_SATVREGMIN + (i < 0 ? -0.5 : 0.5);
        !           354:                                if (i > BT848_SATVREGMAX)
        !           355:                                        i = BT848_SATVREGMAX;
        !           356:                        }
        !           357:                        fields[index].val = i;
        !           358:                        break;
        !           359:                case MUTE:
        !           360:                case OFFON:
        !           361:                        fields[index].val = isoffon(arg);
        !           362:                        if (fields[index].val < 0) {
        !           363:                                warnx("%s is invalid: %s", fields[index].name,
        !           364:                                    optarg);
        !           365:                                return (1);
        !           366:                        }
        !           367:                        if (switchval == MUTE) {
        !           368:                                if (fields[index].val == 1)
        !           369:                                        fields[index].val = AUDIO_MUTE;
        !           370:                                else
        !           371:                                        fields[index].val = AUDIO_UNMUTE;
        !           372:                        }
        !           373:                        break;
        !           374:                default:
        !           375:                        warnx("internal error: do_ioctls: set");
        !           376:                        break;
        !           377:                }
        !           378:                if (ioctl(tuner_fd, fields[index].io_set,&fields[index].val)<0){
        !           379:                        warn("%s", fields[index].name);
        !           380:                        return (1);
        !           381:                }
        !           382:        } else {
        !           383:                /* nothing is being set, so the -q option is meaningless */
        !           384:                print_value = 1;
        !           385:        }
        !           386:
        !           387:        if (print_value == 1)
        !           388:                if (prfield(index) > 0)
        !           389:                        return (1);
        !           390:
        !           391:        return (0);
        !           392: }
        !           393:
        !           394:
        !           395: int
        !           396: main(int argc, char *argv[])
        !           397: {
        !           398:        char    *device = DEFAULT_TUNER_DEVICE;
        !           399:        int      aflag = 0;
        !           400:        int      err = 0;
        !           401:        int      ch, i;
        !           402:
        !           403:        print_choices = 0;
        !           404:        print_name = 1;
        !           405:        print_value = 1;
        !           406:
        !           407:        while ((ch = getopt(argc, argv, "af:nqv")) != -1) {
        !           408:                switch (ch) {
        !           409:                case 'a':
        !           410:                        aflag++;
        !           411:                        break;
        !           412:                case 'f':
        !           413:                        device = optarg;
        !           414:                        break;
        !           415:                case 'n':
        !           416:                        print_name = 0;
        !           417:                        break;
        !           418:                case 'q':
        !           419:                        print_value = 0;
        !           420:                        break;
        !           421:                case 'v':
        !           422:                        print_choices = 1;
        !           423:                        break;
        !           424:                default:
        !           425:                        usage();
        !           426:                }
        !           427:        }
        !           428:        argc -= optind;
        !           429:        argv += optind;
        !           430:
        !           431:        if ((argc == 0) && (aflag == 0))
        !           432:                usage();
        !           433:
        !           434:        if ((tuner_fd = open(device, O_RDONLY)) < 0) {
        !           435:                warn("%s", device);
        !           436:                close(tuner_fd);
        !           437:                exit (1);
        !           438:        }
        !           439:
        !           440:        if (aflag > 0) {
        !           441:                for (i = 0; fields[i].name; i++) {
        !           442:                        if (do_ioctls(i, NULL) > 0) {
        !           443:                                err++;
        !           444:                                break;
        !           445:                        }
        !           446:                }
        !           447:        } else {
        !           448:                for (; argc--; argv++) {
        !           449:                        char *q;
        !           450:
        !           451:                        q = strchr(*argv, '=');
        !           452:                        i = findfield(*argv);
        !           453:                        if (i < 0) {
        !           454:                                warnx("field '%s' does not exist", *argv);
        !           455:                                err++;
        !           456:                                break;
        !           457:                        } else {
        !           458:                                if (q != NULL)
        !           459:                                        *q++ = 0;
        !           460:                                if (do_ioctls(i, q) > 0) {
        !           461:                                        err++;
        !           462:                                        break;
        !           463:                                }
        !           464:                        }
        !           465:                }
        !           466:        }
        !           467:        close(tuner_fd);
        !           468:        exit (err);
        !           469: }