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

Annotation of src/usr.bin/radioctl/radioctl.c, Revision 1.18

1.18    ! deraadt     1: /* $OpenBSD: radioctl.c,v 1.17 2010/06/29 05:00:05 tedu Exp $ */
1.3       mickey      2: /* $RuOBSD: radioctl.c,v 1.4 2001/10/20 18:09:10 pva Exp $ */
1.1       gluk        3:
                      4: /*
                      5:  * Copyright (c) 2001 Vladimir Popov <jumbo@narod.ru>
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     21:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     22:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     23:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     24:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     25:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     26:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29: #include <sys/ioctl.h>
                     30: #include <sys/radioio.h>
                     31:
1.12      robert     32: #include <dev/ic/bt8xx.h>
                     33:
1.1       gluk       34: #include <err.h>
                     35: #include <fcntl.h>
                     36: #include <stdio.h>
                     37: #include <stdlib.h>
                     38: #include <string.h>
                     39: #include <unistd.h>
1.17      tedu       40: #include <ctype.h>
1.1       gluk       41:
                     42: #define RADIO_ENV      "RADIODEVICE"
                     43: #define RADIODEVICE    "/dev/radio"
                     44:
                     45: const char *varname[] = {
                     46:        "search",
                     47: #define OPTION_SEARCH          0x00
                     48:        "volume",
                     49: #define OPTION_VOLUME          0x01
                     50:        "frequency",
                     51: #define OPTION_FREQUENCY       0x02
                     52:        "mute",
                     53: #define OPTION_MUTE            0x03
                     54:        "reference",
                     55: #define OPTION_REFERENCE       0x04
                     56:        "mono",
                     57: #define OPTION_MONO            0x05
                     58:        "stereo",
                     59: #define        OPTION_STEREO           0x06
1.12      robert     60:        "sensitivity",
1.1       gluk       61: #define        OPTION_SENSITIVITY      0x07
1.12      robert     62:        "channel",
                     63: #define OPTION_CHANNEL         0x08
                     64:        "chnlset"
                     65: #define OPTION_CHNLSET         0x09
1.1       gluk       66: };
                     67:
                     68: #define OPTION_NONE            ~0u
1.4       mickey     69: #define VALUE_NONE             ~0u
1.1       gluk       70:
1.3       mickey     71: struct opt_t {
                     72:        char *string;
                     73:        int option;
                     74:        int sign;
                     75: #define SIGN_NONE      0
                     76: #define SIGN_PLUS      1
                     77: #define SIGN_MINUS     -1
                     78:        u_int32_t value;
                     79: };
                     80:
1.12      robert     81: struct chansets {
                     82:        int value;
                     83:        char *name;
                     84: } chansets[] = {
                     85: { CHNLSET_NABCST,      "nabcst",       },
                     86: { CHNLSET_CABLEIRC,    "cableirc",     },
                     87: { CHNLSET_CABLEHRC,    "cablehrc",     },
                     88: { CHNLSET_WEUROPE,     "weurope",      },
                     89: { CHNLSET_JPNBCST,     "jpnbcst",      },
                     90: { CHNLSET_JPNCABLE,    "jpncable",     },
                     91: { CHNLSET_XUSSR,       "xussr",        },
                     92: { CHNLSET_AUSTRALIA,   "australia",    },
                     93: { CHNLSET_FRANCE,      "france",       },
                     94: { 0, NULL }
                     95: };
                     96:
1.1       gluk       97: extern char *__progname;
                     98: const char *onchar = "on";
                     99: #define ONCHAR_LEN     2
                    100: const char *offchar = "off";
                    101: #define OFFCHAR_LEN    3
                    102:
1.8       mickey    103: struct radio_info ri;
1.12      robert    104: unsigned int i = 0;
1.3       mickey    105:
1.8       mickey    106: int    parse_opt(char *, struct opt_t *);
1.3       mickey    107:
1.12      robert    108: void   print_vars(int, int);
1.8       mickey    109: void   do_ioctls(int, struct opt_t *, int);
1.1       gluk      110:
1.12      robert    111: void   print_value(int, int);
1.8       mickey    112: void   change_value(const struct opt_t);
1.11      robert    113: void   update_value(int, int *, int);
1.8       mickey    114:
1.10      deraadt   115: void   warn_unsupported(int);
1.8       mickey    116: void   usage(void);
                    117:
                    118: void   show_verbose(const char *, int);
1.11      robert    119: void   show_int_val(int, const char *, char *, int);
1.8       mickey    120: void   show_float_val(float, const char *, char *, int);
                    121: void   show_char_val(const char *, const char *, int);
                    122: int    str_to_opt(const char *);
1.11      robert    123: u_int  str_to_int(char *, int);
1.1       gluk      124:
                    125: /*
                    126:  * Control behavior of a FM tuner - set frequency, volume etc
                    127:  */
                    128: int
                    129: main(int argc, char **argv)
                    130: {
1.3       mickey    131:        struct opt_t opt;
1.9       jaredy    132:        char **avp;
1.3       mickey    133:
1.1       gluk      134:        char *radiodev = NULL;
1.3       mickey    135:        int rd = -1;
1.7       mickey    136:        int optchar;
1.1       gluk      137:        int show_vars = 0;
1.12      robert    138:        int show_choices = 0;
1.1       gluk      139:        int silent = 0;
1.8       mickey    140:        int mode = O_RDONLY;
1.3       mickey    141:
1.1       gluk      142:        radiodev = getenv(RADIO_ENV);
                    143:        if (radiodev == NULL)
                    144:                radiodev = RADIODEVICE;
                    145:
1.12      robert    146:        while ((optchar = getopt(argc, argv, "af:nvw")) != -1) {
1.1       gluk      147:                switch (optchar) {
                    148:                case 'a':
                    149:                        show_vars = 1;
                    150:                        break;
                    151:                case 'f':
                    152:                        radiodev = optarg;
                    153:                        break;
                    154:                case 'n':
                    155:                        silent = 1;
                    156:                        break;
1.12      robert    157:                case 'v':
                    158:                        show_choices = 1;
                    159:                        break;
1.1       gluk      160:                case 'w':
1.9       jaredy    161:                        /* backwards compatibility */
1.1       gluk      162:                        break;
                    163:                default:
                    164:                        usage();
                    165:                        /* NOTREACHED */
                    166:                }
1.8       mickey    167:        }
1.1       gluk      168:
1.8       mickey    169:        argc -= optind;
                    170:        argv += optind;
1.15      jakemsr   171:
                    172:        if (argc == 0)
                    173:                show_vars = 1;
1.1       gluk      174:
1.9       jaredy    175:        /*
                    176:         * Scan the options for `name=value` so the
                    177:         * device can be opened in the proper mode.
                    178:         */
                    179:        for (avp = argv; *avp != NULL; avp++)
                    180:                if (strchr(*avp, '=') != NULL) {
                    181:                        mode = O_RDWR;
                    182:                        break;
1.10      deraadt   183:                }
1.9       jaredy    184:
1.8       mickey    185:        rd = open(radiodev, mode);
1.1       gluk      186:        if (rd < 0)
                    187:                err(1, "%s open error", radiodev);
                    188:
1.3       mickey    189:        if (ioctl(rd, RIOCGINFO, &ri) < 0)
                    190:                err(1, "RIOCGINFO");
1.1       gluk      191:
1.9       jaredy    192:        if (!argc && show_vars)
1.12      robert    193:                print_vars(silent, show_choices);
1.8       mickey    194:        else if (argc > 0 && !show_vars) {
1.9       jaredy    195:                if (mode == O_RDWR) {
1.14      sobrado   196:                        for (; argc--; argv++)
1.8       mickey    197:                                if (parse_opt(*argv, &opt))
                    198:                                        do_ioctls(rd, &opt, silent);
                    199:                } else {
1.14      sobrado   200:                        for (; argc--; argv++)
1.8       mickey    201:                                if (parse_opt(*argv, &opt)) {
                    202:                                        show_verbose(varname[opt.option],
                    203:                                            silent);
1.12      robert    204:                                        print_value(opt.option, show_choices);
1.8       mickey    205:                                        free(opt.string);
                    206:                                        putchar('\n');
                    207:                                }
1.3       mickey    208:                }
1.8       mickey    209:        }
1.1       gluk      210:
                    211:        if (close(rd) < 0)
                    212:                warn("%s close error", radiodev);
                    213:
                    214:        return 0;
                    215: }
                    216:
1.8       mickey    217: void
1.1       gluk      218: usage(void)
                    219: {
1.9       jaredy    220:        fprintf(stderr,
1.16      jmc       221:            "usage: %s [-anv] [-f file]\n"
1.14      sobrado   222:            "       %s [-nv] [-f file] name\n"
                    223:            "       %s [-n] [-f file] name=value\n",
1.7       mickey    224:            __progname, __progname, __progname);
                    225:        exit(1);
1.1       gluk      226: }
                    227:
1.8       mickey    228: void
1.3       mickey    229: show_verbose(const char *nick, int silent)
1.1       gluk      230: {
1.3       mickey    231:        if (!silent)
                    232:                printf("%s=", nick);
                    233: }
1.1       gluk      234:
1.8       mickey    235: void
1.3       mickey    236: warn_unsupported(int optval)
                    237: {
                    238:        warnx("driver does not support `%s'", varname[optval]);
1.1       gluk      239: }
                    240:
1.8       mickey    241: void
1.3       mickey    242: do_ioctls(int fd, struct opt_t *o, int silent)
1.1       gluk      243: {
1.3       mickey    244:        int oval;
1.1       gluk      245:
1.3       mickey    246:        if (fd < 0 || o == NULL)
1.1       gluk      247:                return;
                    248:
1.3       mickey    249:        if (o->option == OPTION_SEARCH && !(ri.caps & RADIO_CAPS_HW_SEARCH)) {
                    250:                warn_unsupported(o->option);
1.1       gluk      251:                return;
                    252:        }
                    253:
1.3       mickey    254:        oval = o->option == OPTION_SEARCH ? OPTION_FREQUENCY : o->option;
                    255:        if (!silent)
                    256:                printf("%s: ", varname[oval]);
                    257:
1.12      robert    258:        print_value(o->option, 0);
1.3       mickey    259:        printf(" -> ");
                    260:
                    261:        if (o->option == OPTION_SEARCH) {
                    262:
                    263:                if (ioctl(fd, RIOCSSRCH, &o->value) < 0) {
                    264:                        warn("RIOCSSRCH");
                    265:                        return;
                    266:                }
                    267:
                    268:        } else {
                    269:
                    270:                change_value(*o);
                    271:                if (ioctl(fd, RIOCSINFO, &ri) < 0) {
                    272:                        warn("RIOCSINFO");
                    273:                        return;
                    274:                }
1.1       gluk      275:
                    276:        }
                    277:
1.3       mickey    278:        if (ioctl(fd, RIOCGINFO, &ri) < 0) {
                    279:                warn("RIOCGINFO");
1.1       gluk      280:                return;
                    281:        }
                    282:
1.12      robert    283:        print_value(o->option, 0);
1.3       mickey    284:        putchar('\n');
                    285: }
                    286:
1.8       mickey    287: void
1.3       mickey    288: change_value(const struct opt_t o)
                    289: {
                    290:        int unsupported = 0;
1.1       gluk      291:
1.3       mickey    292:        if (o.value == VALUE_NONE)
                    293:                return;
1.1       gluk      294:
1.3       mickey    295:        switch (o.option) {
                    296:        case OPTION_VOLUME:
1.11      robert    297:                update_value(o.sign, &ri.volume, o.value);
1.3       mickey    298:                break;
                    299:        case OPTION_FREQUENCY:
1.13      jakemsr   300:                ri.tuner_mode = RADIO_TUNER_MODE_RADIO;
1.11      robert    301:                update_value(o.sign, &ri.freq, o.value);
1.3       mickey    302:                break;
                    303:        case OPTION_REFERENCE:
                    304:                if (ri.caps & RADIO_CAPS_REFERENCE_FREQ)
1.11      robert    305:                        update_value(o.sign, &ri.rfreq, o.value);
1.1       gluk      306:                else
1.3       mickey    307:                        unsupported++;
1.1       gluk      308:                break;
1.3       mickey    309:        case OPTION_MONO:
                    310:                /* FALLTHROUGH */
                    311:        case OPTION_STEREO:
                    312:                if (ri.caps & RADIO_CAPS_SET_MONO)
                    313:                        ri.stereo = o.option == OPTION_MONO ? !o.value : o.value;
1.1       gluk      314:                else
1.3       mickey    315:                        unsupported++;
1.1       gluk      316:                break;
1.3       mickey    317:        case OPTION_SENSITIVITY:
                    318:                if (ri.caps & RADIO_CAPS_LOCK_SENSITIVITY)
1.11      robert    319:                        update_value(o.sign, &ri.lock, o.value);
1.3       mickey    320:                else
                    321:                        unsupported++;
1.1       gluk      322:                break;
1.3       mickey    323:        case OPTION_MUTE:
                    324:                ri.mute = o.value;
1.1       gluk      325:                break;
1.12      robert    326:        case OPTION_CHANNEL:
1.13      jakemsr   327:                ri.tuner_mode = RADIO_TUNER_MODE_TV;
1.12      robert    328:                update_value(o.sign, &ri.chan, o.value);
                    329:                break;
                    330:        case OPTION_CHNLSET:
                    331:                ri.chnlset = o.value;
                    332:                break;
1.1       gluk      333:        }
                    334:
1.6       deraadt   335:        if (unsupported)
1.3       mickey    336:                warn_unsupported(o.option);
1.1       gluk      337: }
                    338:
                    339: /*
                    340:  * Convert string to integer representation of a parameter
                    341:  */
1.8       mickey    342: int
1.3       mickey    343: str_to_opt(const char *topt)
1.1       gluk      344: {
1.3       mickey    345:        int res, toptlen, varlen, len, varsize;
1.1       gluk      346:
                    347:        if (topt == NULL || *topt == '\0')
                    348:                return OPTION_NONE;
                    349:
                    350:        varsize = sizeof(varname) / sizeof(varname[0]);
                    351:        toptlen = strlen(topt);
                    352:
                    353:        for (res = 0; res < varsize; res++) {
                    354:                varlen = strlen(varname[res]);
                    355:                len = toptlen > varlen ? toptlen : varlen;
                    356:                if (strncmp(topt, varname[res], len) == 0)
                    357:                        return res;
                    358:        }
                    359:
                    360:        warnx("bad name `%s'", topt);
                    361:        return OPTION_NONE;
                    362: }
                    363:
1.8       mickey    364: void
1.11      robert    365: update_value(int sign, int *value, int update)
1.1       gluk      366: {
1.3       mickey    367:        switch (sign) {
                    368:        case SIGN_NONE:
                    369:                *value  = update;
1.1       gluk      370:                break;
1.3       mickey    371:        case SIGN_PLUS:
                    372:                *value += update;
1.1       gluk      373:                break;
1.3       mickey    374:        case SIGN_MINUS:
                    375:                *value -= update;
1.1       gluk      376:                break;
                    377:        }
                    378: }
                    379:
                    380: /*
1.3       mickey    381:  * Convert string to unsigned integer
1.1       gluk      382:  */
1.11      robert    383: u_int
                    384: str_to_int(char *str, int optval)
1.1       gluk      385: {
1.11      robert    386:        int val;
1.1       gluk      387:
                    388:        if (str == NULL || *str == '\0')
                    389:                return VALUE_NONE;
                    390:
                    391:        if (optval == OPTION_FREQUENCY)
1.11      robert    392:                val = (int)(1000 * atof(str));
1.1       gluk      393:        else
1.11      robert    394:                val = (int)strtol(str, (char **)NULL, 10);
1.1       gluk      395:
                    396:        return val;
                    397: }
                    398:
                    399: /*
1.3       mickey    400:  * parse string s into struct opt_t
                    401:  * return true on success, false on failure
                    402:  */
1.8       mickey    403: int
1.3       mickey    404: parse_opt(char *s, struct opt_t *o) {
                    405:        const char *badvalue = "bad value `%s'";
                    406:        char *topt = NULL;
                    407:        int slen, optlen;
1.12      robert    408:
1.3       mickey    409:        if (s == NULL || *s == '\0' || o == NULL)
                    410:                return 0;
                    411:
                    412:        o->string = NULL;
                    413:        o->option = OPTION_NONE;
                    414:        o->value = VALUE_NONE;
                    415:        o->sign = SIGN_NONE;
                    416:
                    417:        slen = strlen(s);
                    418:        optlen = strcspn(s, "=");
                    419:
                    420:        /* Set only o->optval, the rest is missing */
                    421:        if (slen == optlen) {
                    422:                o->option = str_to_opt(s);
                    423:                return o->option == OPTION_NONE ? 0 : 1;
                    424:        }
                    425:
                    426:        if (optlen > slen - 2) {
                    427:                warnx(badvalue, s);
                    428:                return 0;
                    429:        }
                    430:
                    431:        slen -= ++optlen;
                    432:
1.17      tedu      433:        if ((topt = malloc(optlen)) == NULL) {
1.3       mickey    434:                warn("memory allocation error");
                    435:                return 0;
                    436:        }
                    437:        strlcpy(topt, s, optlen);
                    438:
                    439:        if ((o->option = str_to_opt(topt)) == OPTION_NONE) {
                    440:                free(topt);
                    441:                return 0;
                    442:        }
                    443:        o->string = topt;
                    444:
                    445:        topt = &s[optlen];
1.12      robert    446:
                    447:        if (strcmp(o->string, "chnlset") == 0) {
                    448:                for (i = 0; chansets[i].name; i++)
                    449:                        if (strncmp(chansets[i].name, topt,
                    450:                                strlen(chansets[i].name)) == 0)
                    451:                                        break;
                    452:                if (chansets[i].name != NULL) {
                    453:                        o->value = chansets[i].value;
                    454:                        return 1;
                    455:                } else {
                    456:                        warnx(badvalue, topt);
                    457:                        return 0;
                    458:                }
                    459:        }
                    460:
1.3       mickey    461:        switch (*topt) {
                    462:        case '+':
                    463:        case '-':
                    464:                o->sign = (*topt == '+') ? SIGN_PLUS : SIGN_MINUS;
1.11      robert    465:                o->value = str_to_int(&topt[1], o->option);
1.3       mickey    466:                break;
                    467:        case 'o':
                    468:                if (strncmp(topt, offchar,
1.17      tedu      469:                    slen > OFFCHAR_LEN ? slen : OFFCHAR_LEN) == 0)
1.3       mickey    470:                        o->value = 0;
                    471:                else if (strncmp(topt, onchar,
1.17      tedu      472:                    slen > ONCHAR_LEN ? slen : ONCHAR_LEN) == 0)
                    473:                        o->value = 1;
1.3       mickey    474:                break;
                    475:        case 'u':
                    476:                if (strncmp(topt, "up", slen > 2 ? slen : 2) == 0)
                    477:                        o->value = 1;
                    478:                break;
                    479:        case 'd':
                    480:                if (strncmp(topt, "down", slen > 4 ? slen : 4) == 0)
                    481:                        o->value = 0;
                    482:                break;
                    483:        default:
1.18    ! deraadt   484:                if (isdigit((unsigned char)*topt))
1.11      robert    485:                        o->value = str_to_int(topt, o->option);
1.3       mickey    486:                break;
                    487:        }
                    488:
                    489:        if (o->value == VALUE_NONE) {
                    490:                warnx(badvalue, topt);
                    491:                return 0;
                    492:        }
                    493:
                    494:        return 1;
                    495: }
                    496:
                    497: /*
1.1       gluk      498:  * Print current value of the parameter.
                    499:  */
1.8       mickey    500: void
1.12      robert    501: print_value(int optval, int show_choices)
1.1       gluk      502: {
                    503:        if (optval == OPTION_NONE)
                    504:                return;
                    505:
                    506:        switch (optval) {
                    507:        case OPTION_SEARCH:
                    508:                /* FALLTHROUGH */
                    509:        case OPTION_FREQUENCY:
1.3       mickey    510:                printf("%.2fMHz", (float)ri.freq / 1000.);
1.1       gluk      511:                break;
                    512:        case OPTION_REFERENCE:
1.3       mickey    513:                printf("%ukHz", ri.rfreq);
1.1       gluk      514:                break;
                    515:        case OPTION_SENSITIVITY:
1.3       mickey    516:                printf("%umkV", ri.lock);
1.1       gluk      517:                break;
                    518:        case OPTION_MUTE:
1.3       mickey    519:                printf(ri.mute ? onchar : offchar);
                    520:                break;
1.1       gluk      521:        case OPTION_MONO:
1.3       mickey    522:                printf(ri.stereo ? offchar : onchar);
1.1       gluk      523:                break;
                    524:        case OPTION_STEREO:
1.3       mickey    525:                printf(ri.stereo ? onchar : offchar);
1.1       gluk      526:                break;
1.12      robert    527:        case OPTION_CHANNEL:
                    528:                printf("%u", ri.chan);
                    529:                break;
                    530:        case OPTION_CHNLSET:
                    531:                for (i = 0; chansets[i].name; i++) {
                    532:                        if (chansets[i].value == ri.chnlset)
                    533:                                printf("%s", chansets[i].name);
                    534:                }
                    535:                if (show_choices) {
                    536:                        printf("\n\t[");
                    537:                        for (i = 0; chansets[i].name; i++)
                    538:                                printf("%s ", chansets[i].name);
                    539:                        printf("]");
                    540:                }
                    541:                break;
1.3       mickey    542:        case OPTION_VOLUME:
1.1       gluk      543:        default:
1.3       mickey    544:                printf("%u", ri.volume);
1.1       gluk      545:                break;
                    546:        }
                    547: }
                    548:
1.8       mickey    549: void
1.11      robert    550: show_int_val(int val, const char *nick, char *append, int silent)
1.3       mickey    551: {
                    552:        show_verbose(nick, silent);
1.11      robert    553:        printf("%u%s\n", val, append);
1.3       mickey    554: }
                    555:
1.8       mickey    556: void
1.3       mickey    557: show_float_val(float val, const char *nick, char *append, int silent)
                    558: {
                    559:        show_verbose(nick, silent);
                    560:        printf("%.2f%s\n", val, append);
                    561: }
                    562:
1.8       mickey    563: void
1.3       mickey    564: show_char_val(const char *val, const char *nick, int silent)
1.1       gluk      565: {
1.3       mickey    566:        show_verbose(nick, silent);
                    567:        printf("%s\n", val);
1.1       gluk      568: }
                    569:
1.3       mickey    570: /*
                    571:  * Print all available parameters
                    572:  */
1.8       mickey    573: void
1.12      robert    574: print_vars(int silent, int show_choices)
1.1       gluk      575: {
1.3       mickey    576:        show_int_val(ri.volume, varname[OPTION_VOLUME], "", silent);
1.12      robert    577:        show_int_val(ri.chan, varname[OPTION_CHANNEL], "", silent);
                    578:        for (i = 0; chansets[i].name; i++) {
                    579:                if (chansets[i].value == ri.chnlset)
                    580:                        show_char_val(chansets[i].name, varname[OPTION_CHNLSET], silent);
                    581:        }
                    582:        if (show_choices) {
                    583:                printf("\t[ ");
                    584:                for (i = 0; chansets[i].name; i++)
                    585:                        printf("%s ", chansets[i].name);
                    586:                printf("]\n");
                    587:        }
1.3       mickey    588:        show_float_val((float)ri.freq / 1000., varname[OPTION_FREQUENCY],
1.6       deraadt   589:            "MHz", silent);
1.3       mickey    590:        show_char_val(ri.mute ? onchar : offchar, varname[OPTION_MUTE], silent);
                    591:
                    592:        if (ri.caps & RADIO_CAPS_REFERENCE_FREQ)
                    593:                show_int_val(ri.rfreq, varname[OPTION_REFERENCE], "kHz", silent);
                    594:        if (ri.caps & RADIO_CAPS_LOCK_SENSITIVITY)
                    595:                show_int_val(ri.lock, varname[OPTION_SENSITIVITY], "mkV", silent);
                    596:
                    597:        if (ri.caps & RADIO_CAPS_DETECT_SIGNAL) {
                    598:                show_verbose("signal", silent);
                    599:                printf("%s\n", ri.info & RADIO_INFO_SIGNAL ? onchar : offchar);
                    600:        }
                    601:        if (ri.caps & RADIO_CAPS_DETECT_STEREO) {
                    602:                show_verbose(varname[OPTION_STEREO], silent);
                    603:                printf("%s\n", ri.info & RADIO_INFO_STEREO ? onchar : offchar);
                    604:        }
1.1       gluk      605:
1.13      jakemsr   606:        if (!silent) {
                    607:                printf("mode: %s\n",
                    608:                    ri.tuner_mode == RADIO_TUNER_MODE_TV ? "TV" : "radio");
                    609:
1.3       mickey    610:                puts("card capabilities:");
1.13      jakemsr   611:        }
                    612:
1.3       mickey    613:        if (ri.caps & RADIO_CAPS_SET_MONO)
                    614:                puts("\tmanageable mono/stereo");
                    615:        if (ri.caps & RADIO_CAPS_HW_SEARCH)
                    616:                puts("\thardware search");
                    617:        if (ri.caps & RADIO_CAPS_HW_AFC)
                    618:                puts("\thardware AFC");
1.1       gluk      619: }