[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.13

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