]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.bin/setchannel/setchannel.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.bin / setchannel / setchannel.c
1 /*-
2  * Copyright (c) 2003, 2004, 2005
3  *      John Wehle <john@feith.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *  $FreeBSD$
27  */
28
29 /* Set the channel of the tuner card. */
30
31 #include <sys/ioctl.h>
32 #include <sys/param.h>
33
34 #include <ctype.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #include <dev/bktr/ioctl_meteor.h>
43 #include <dev/bktr/ioctl_bt848.h>
44
45 static void
46 usage(void)
47 {
48         printf
49             ("Usage: setchannel [-a {on|off}] [-c | -r | -s | -t] "
50             "[-g geom] [-m chnl_set] [chnl | freq]\n"
51             "  -a    Enable / disable AFC.\n"
52             "  -c    Select composite input.\n"
53             "  -d    Select tuner unit number.\n"
54             "  -r    Select radio input.\n"
55             "  -s    Select svideo input.\n"
56             "  -t    Select tuner.\n"
57             "  -g    Select geometry.\n"
58             "          352x240 or 352x288 = VCD\n"
59             "          480x480 or 480x576 = SVCD\n"
60             "          352x480 or 352x576 = DVD (half D1)\n"
61             "          720x480 or 720x576 = DVD (full D1)\n"
62             "  -m    Select channel set / system.\n"
63             "          0 = Tuner Default\n"
64             "          %u = US Broadcast / NTSC\n"
65             "          %u = US Cable / NTSC\n"
66             "          %u = Western Europe / PAL\n"
67             "          %u = Japan Broadcast / NTSC\n"
68             "          %u = Japan Cable / NTSC\n"
69             "          %u = Australia / PAL\n"
70             "          %u = France / SECAM\n"
71             "  chnl  Channel\n"
72             "  freq  Frequency in MHz (must include decimal point).\n",
73             CHNLSET_NABCST, CHNLSET_CABLEIRC, CHNLSET_WEUROPE, CHNLSET_JPNBCST,
74             CHNLSET_JPNCABLE, CHNLSET_AUSTRALIA, CHNLSET_FRANCE);
75 }
76
77 #define DEVNAME_BASE "/dev/cxm"
78 char dev_name[16];
79
80 int
81 main(int argc, char *argv[])
82 {
83         char *ptr;
84         char *endptr;
85         int afc;
86         int audio;
87         int c;
88         int channel_set;
89         int i;
90         int status;
91         int unit;
92         int tfd;
93         unsigned int channel;
94         unsigned int fraction;
95         unsigned int freq;
96         unsigned int x_size;
97         unsigned int y_size;
98         unsigned long device;
99         struct bktr_capture_area cap;
100
101         afc = -1;
102         audio = -1;
103         channel = 0;
104         channel_set = -1;
105         device = 0;
106         freq = 0;
107         status = 0;
108         unit = 0;
109         x_size = 0;
110         y_size = 0;
111
112         while ((c = getopt(argc, argv, "a:cd:rg:m:st")) != -1)
113                 switch (c) {
114
115                 case 'a':
116                         if (strcasecmp(optarg, "on") == 0)
117                                 afc = 1;
118                         else if (strcasecmp(optarg, "off") == 0)
119                                 afc = 0;
120                         else {
121                                 usage();
122                                 exit(1);
123                         }
124                         break;
125
126                 case 'c':
127                         device = METEOR_INPUT_DEV2;
128                         audio = -1;
129                         break;
130
131                 case 'd':
132                         unit = atoi(optarg);
133                         break;
134
135                 case 'r':
136                         device = 0;
137                         audio = AUDIO_INTERN;
138                         break;
139
140                 case 's':
141                         device = METEOR_INPUT_DEV_SVIDEO;
142                         audio = -1;
143                         break;
144
145                 case 't':
146                         device = METEOR_INPUT_DEV1;
147                         audio = -1;
148                         break;
149
150                 case 'g':
151                         if (sscanf(optarg, "%ux%u", &x_size, &y_size) != 2
152                             || x_size == 0 || y_size == 0) {
153                                 usage();
154                                 exit(1);
155                         }
156                         break;
157
158                 case 'm':
159                         channel_set = atoi(optarg);
160                         if (channel_set < 0 || channel_set > CHNLSET_MAX) {
161                                 usage();
162                                 exit(1);
163                         }
164                         break;
165
166                 default:
167                         usage();
168                         exit(1);
169                 }
170
171         if (optind < argc) {
172
173                 /*
174                  * A number containing a decimal point is the frequency in MHz.
175                  */
176
177                 if ((ptr = strchr(argv[optind], '.')) != NULL) {
178                         freq = strtol(argv[optind], &endptr, 10) * 1000;
179                         if (ptr != endptr) {
180                                 usage();
181                                 exit(1);
182                         }
183
184                         ptr++;
185
186                         fraction = strtol(ptr, &endptr, 10);
187                         if (!isdigit(*ptr) || *endptr != '\0') {
188                                 usage();
189                                 exit(1);
190                         }
191
192                         for (i = endptr - ptr; i > 3; i--)
193                                 fraction /= 10;
194                         for (; i < 3; i++)
195                                 fraction *= 10;
196
197                         freq += fraction;
198                 }
199
200                 /* An integer is the channel. */
201                 else
202                         channel = atoi(argv[optind]);
203         }
204
205         if (afc == -1 && audio == -1 && !device && x_size == 0 && y_size == 0
206             && channel_set == -1 && !channel && !freq) {
207                 usage();
208                 exit(1);
209         }
210
211         sprintf(dev_name, DEVNAME_BASE "%d", unit);
212         tfd = open(dev_name, O_RDONLY);
213         if (tfd < 0) {
214                 fprintf(stderr, "Can't open %s: %s (%d)\n", dev_name,
215                     strerror(errno), errno);
216                 exit(1);
217         }
218
219         if (afc != -1)
220                 if (ioctl(tfd, TVTUNER_SETAFC, &afc) < 0) {
221                         perror("ioctl(tfd, TVTUNER_SETAFC) failed.");
222                         status = 1;
223                 }
224
225         if (device)
226                 if (ioctl(tfd, METEORSINPUT, &device) < 0) {
227                         perror("ioctl(tfd, METEORSINPUT) failed.");
228                         status = 1;
229                 }
230
231         if (audio != -1)
232                 if (ioctl(tfd, BT848_SAUDIO, &audio) < 0) {
233                         perror("ioctl(tfd, BT848_SAUDIO) failed.");
234                         status = 1;
235                 }
236
237         if (ioctl(tfd, BT848_GAUDIO, &audio) < 0) {
238                 perror("ioctl(tfd, BT848_GAUDIO) failed.");
239                 status = 1;
240         }
241
242         if (x_size && y_size) {
243                 memset(&cap, 0, sizeof(cap));
244                 cap.x_size = x_size;
245                 cap.y_size = y_size;
246                 if (ioctl(tfd, BT848_SCAPAREA, &cap) < 0) {
247                         perror("ioctl(tfd, BT848_SCAPAREA) failed.");
248                         status = 1;
249                 }
250         }
251
252         if (channel_set != -1)
253                 if (ioctl(tfd, TVTUNER_SETTYPE, &channel_set) < 0) {
254                         perror("ioctl(tfd, TVTUNER_SETTYPE) failed.");
255                         status = 1;
256                 }
257
258         if (channel) {
259                 if (ioctl(tfd, TVTUNER_SETCHNL, &channel) < 0) {
260                         perror("ioctl(tfd, TVTUNER_SETCHNL) failed.");
261                         status = 1;
262                 }
263         } else if (freq) {
264                 if (audio == AUDIO_INTERN) {
265                         /* Convert from kHz to MHz * 100 */
266                         freq = freq / 10;
267
268                         if (ioctl(tfd, RADIO_SETFREQ, &freq) < 0) {
269                                 perror("ioctl(tfd, RADIO_SETFREQ) failed.");
270                                 status = 1;
271                         }
272                 } else {
273                         /* Convert from kHz to MHz * 16 */
274                         freq = (freq * 16) / 1000;
275
276                         if (ioctl(tfd, TVTUNER_SETFREQ, &freq) < 0) {
277                                 perror("ioctl(tfd, TVTUNER_SETFREQ) failed.");
278                                 status = 1;
279                         }
280                 }
281         }
282
283         close(tfd);
284         exit(status);
285 }