/* * tunerctl.c: Switch frequency/program on tuner * * $Id: tunerctl.c,v 1.5 1999/10/04 22:58:12 mb Exp mb $ * * Copyright (c) 1994-98 Martin Buck * Read COPYING for more information * */ #include #include #include #include #include #include #include #include "tvchannels.h" #include "safe_malloc.h" #include "vtx_assert.h" #include "misc.h" #include "tuner.h" typedef enum { TM_FREQ, TM_PROG, TM_CHAN } tun_method_t; int main(int argc, char *argv[]) { tuner_info_t tuner_info; char *tmpptr, *tv_system = NULL; int optchr, new_freq, freq = -1, new_prog, prog = -1, source = -1, new_source; tun_method_t method = TM_FREQ; smalloc_init(argv[0]); if ((tmpptr = getenv("TUNER_DEVICE"))) { tuner_device = tmpptr; } while ((optchr = getopt(argc, argv, "fcps:v:D:?")) != -1) { switch (optchr) { case 'f': method = TM_FREQ; break; case 'c': method = TM_CHAN; break; case 'p': method = TM_PROG; break; case 's': tv_system = optarg; if (tvch_chan2freq(tv_system, NULL, NULL, NULL) < 0) { fprintf(stderr, "%s: unknown TV system: %s\n", smalloc_progname, tv_system); exit(1); } break; case 'v': source = strtol(optarg, &tmpptr, 0); if (*tmpptr || source < 0) { fprintf(stderr, "%s: invalid video source: %s\n", smalloc_progname, optarg); exit(1); } break; case 'D': tuner_device = optarg; break; case '?': printf("tunerctl version " VTXVERSION ", Copyright 1994-98 Martin Buck\n\n" "Usage: %s [options] [||]\n" "Frequency syntax:\n" " xxx[.yyy][M[Hz]]\n" " xxxk[Hz]\n" "Options:\n" " -f Set tuner's frequency directly (default)\n" " -c Set tuner's frequency to channel\n" " -p Set tuner's program\n" " -s Set TV system for channel selection\n" " -v Set video source\n" " -D Set device to use (default: /dev/vttuner)\n" " -\\? Show this help\n", smalloc_progname); exit(1); break; default: assert(0); break; } } if (optind < argc - 1) { fprintf(stderr, "%s: too many arguments (try `%s -\\?' to get help)\n", smalloc_progname, smalloc_progname); exit(1); } if (optind == argc - 1) { char unit[16] = ""; int count; double tmp_freq; switch (method) { case TM_FREQ: if ((count = sscanf(argv[optind], " %lf %15s ", &tmp_freq, unit)) >= 1) { if (unit[0] != '\0' && strcasecmp(unit, "m") && strcasecmp(unit, "mhz") && strcasecmp(unit, "k") && strcasecmp(unit, "khz")) { fprintf(stderr, "%s: invalid frequency unit: %s\n", smalloc_progname, unit); exit(1); } freq = (tolower(unit[0]) == 'k' ? (int)tmp_freq : (int)(tmp_freq * 1000)); if (freq < 0) { fprintf(stderr, "%s: frequency out of range: %.3f MHz\n", smalloc_progname, freq / 1000.0); exit(1); } } else { fprintf(stderr, "%s: invalid argument: %s\n", smalloc_progname, argv[optind]); exit(1); } break; case TM_CHAN: { const char *chan_name, *sys_name; freq = tvch_chan2freq(tv_system, argv[optind], &sys_name, &chan_name); if (freq < 0) { fprintf(stderr, "%s: unknown channel: %s\n", smalloc_progname, argv[optind]); exit(1); } printf("tuning frequency for channel %s, %s: %.3f MHz\n", chan_name, sys_name, freq / 1000.0); } break; case TM_PROG: if ((count = sscanf(argv[optind], " %d ", &prog)) == 1) { if (prog < 0) { fprintf(stderr, "%s: program out of range: %d\n", smalloc_progname, prog); exit(1); } } else { fprintf(stderr, "%s: invalid argument: %s\n", smalloc_progname, argv[optind]); exit(1); } break; default: assert(0); break; } } switch (tuner_open(REQ_MAJOR, REQ_MINOR, &tuner_info)) { case TUNOK: break; case TUNEVERSION: fprintf(stderr, "%s: can't open tuner-device: incompatible driver version (need %d.%d)\n", smalloc_progname, REQ_MAJOR, REQ_MINOR); exit(1); break; default: fprintf(stderr, "%s: can't open tuner-device %s: %s\n", smalloc_progname, tuner_device, strerror(errno)); exit(1); break; } if (source >= 0) { if (tuner_info.vidsrccount) { switch (tuner_setsrc(source)) { case TUNOK: break; case TUNEINVAL: fprintf(stderr, "%s: video source out of range: %d\n", smalloc_progname, source); exit(1); break; default: fprintf(stderr, "%s: can't set video source: %s\n", smalloc_progname, strerror(errno)); exit(1); break; } } else { fprintf(stderr, "%s: tuner/driver doesn't support selecting video source\n", smalloc_progname); exit(1); } } switch (method) { case TM_FREQ: case TM_CHAN: if (freq < 0) { break; } if (!tuner_info.freq) { fprintf(stderr, "%s: tuner/driver doesn't support setting frequency\n", smalloc_progname); exit(1); } tuner_reset(); /* Ignore failure */ switch (tuner_setfreq(freq)) { case TUNOK: break; case TUNEINVAL: fprintf(stderr, "%s: frequency out of range: %.3f MHz\n", smalloc_progname, freq / 1000.0); exit(1); break; default: fprintf(stderr, "%s: can't set frequency: %s\n", smalloc_progname, strerror(errno)); exit(1); break; } break; case TM_PROG: if (prog < 0) { break; } if (!tuner_info.prog) { fprintf(stderr, "%s: tuner/driver doesn't support setting program\n", smalloc_progname); exit(1); } tuner_reset(); /* Ignore failure */ switch (tuner_setprog(prog)) { case TUNOK: break; case TUNEINVAL: fprintf(stderr, "%s: program out of range: %d\n", smalloc_progname, prog); exit(1); break; default: fprintf(stderr, "%s: can't set program: %s\n", smalloc_progname, strerror(errno)); exit(1); break; } break; default: assert(0); break; } if (tuner_info.freq) { if ((new_freq = tuner_getfreq()) < 0) { fprintf(stderr, "%s: can't read%s frequency: %s\n", smalloc_progname, (freq >= 0 ? " new" : ""), strerror(errno)); } else { printf("%s tuning frequency: ", (freq >= 0 ? "new" : "current")); if (!new_freq) { printf("unknown\n"); } else { printf("%.3f MHz\n", new_freq / 1000.0); } } } if (tuner_info.prog) { if ((new_prog = tuner_getprog()) < 0) { fprintf(stderr, "%s: can't read%s program: %s\n", smalloc_progname, (prog >= 0 ? " new" : ""), strerror(errno)); } else { printf("%s program: %d\n", (prog >= 0 ? "new" : "current"), new_prog); } } if (tuner_info.vidsrccount) { if ((new_source = tuner_getsrc()) < 0) { fprintf(stderr, "%s: can't read%s video source: %s\n", smalloc_progname, (source >= 0 ? " new" : ""), strerror(errno)); } else { printf("%s video source: %d\n", (source >= 0 ? "new" : "current"), new_source); } } exit(0); }