]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.bin/setchannel/setchannel.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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 <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/ioctl.h>
40 #include <unistd.h>
41
42 #if __FreeBSD_version < 503001
43 #  include <machine/ioctl_meteor.h>
44 #  include <machine/ioctl_bt848.h>
45 #else
46 #  include <dev/bktr/ioctl_meteor.h>
47 #  include <dev/bktr/ioctl_bt848.h>
48 #endif
49
50
51 static void
52 usage()
53 {
54         printf
55             ("Usage: setchannel [-a {on|off}] [-c | -r | -s | -t] "
56             "[-g geom] [-m chnl_set] [chnl | freq]\n"
57             "  -a    Enable / disable AFC.\n"
58             "  -c    Select composite input.\n"
59             "  -d    Select tuner unit number.\n"
60             "  -r    Select radio input.\n"
61             "  -s    Select svideo input.\n"
62             "  -t    Select tuner.\n"
63             "  -g    Select geometry.\n"
64             "          352x240 or 352x288 = VCD\n"
65             "          480x480 or 480x576 = SVCD\n"
66             "          352x480 or 352x576 = DVD (half D1)\n"
67             "          720x480 or 720x576 = DVD (full D1)\n"
68             "  -m    Select channel set / system.\n"
69             "          0 = Tuner Default\n"
70             "          %u = US Broadcast / NTSC\n"
71             "          %u = US Cable / NTSC\n"
72             "          %u = Western Europe / PAL\n"
73             "          %u = Japan Broadcast / NTSC\n"
74             "          %u = Japan Cable / NTSC\n"
75             "          %u = Australia / PAL\n"
76             "          %u = France / SECAM\n"
77             "  chnl  Channel\n"
78             "  freq  Frequency in MHz (must include decimal point).\n",
79             CHNLSET_NABCST, CHNLSET_CABLEIRC, CHNLSET_WEUROPE, CHNLSET_JPNBCST,
80             CHNLSET_JPNCABLE, CHNLSET_AUSTRALIA, CHNLSET_FRANCE);
81 }
82
83 #define DEVNAME_BASE "/dev/cxm"
84 char dev_name[16];
85
86 int
87 main(int argc, char *argv[])
88 {
89         char *ptr;
90         char *endptr;
91         int afc;
92         int audio;
93         int c;
94         int channel_set;
95         int i;
96         int status;
97         int unit;
98         int tfd;
99         unsigned int channel;
100         unsigned int fraction;
101         unsigned int freq;
102         unsigned int x_size;
103         unsigned int y_size;
104         unsigned long device;
105         struct bktr_capture_area cap;
106
107         afc = -1;
108         audio = -1;
109         channel = 0;
110         channel_set = -1;
111         device = 0;
112         freq = 0;
113         status = 0;
114         unit = 0;
115         x_size = 0;
116         y_size = 0;
117
118         while ((c = getopt(argc, argv, "a:cd:rg:m:st")) != -1)
119                 switch (c) {
120
121                 case 'a':
122                         if (strcasecmp(optarg, "on") == 0)
123                                 afc = 1;
124                         else if (strcasecmp(optarg, "off") == 0)
125                                 afc = 0;
126                         else {
127                                 usage();
128                                 exit(1);
129                         }
130                         break;
131
132                 case 'c':
133                         device = METEOR_INPUT_DEV2;
134                         audio = -1;
135                         break;
136
137                 case 'd':
138                         unit = atoi(optarg);
139                         break;
140
141                 case 'r':
142                         device = 0;
143                         audio = AUDIO_INTERN;
144                         break;
145
146                 case 's':
147                         device = METEOR_INPUT_DEV_SVIDEO;
148                         audio = -1;
149                         break;
150
151                 case 't':
152                         device = METEOR_INPUT_DEV1;
153                         audio = -1;
154                         break;
155
156                 case 'g':
157                         if (sscanf(optarg, "%ux%u", &x_size, &y_size) != 2
158                             || x_size == 0 || y_size == 0) {
159                                 usage();
160                                 exit(1);
161                         }
162                         break;
163
164                 case 'm':
165                         channel_set = atoi(optarg);
166                         if (channel_set < 0 || channel_set > CHNLSET_MAX) {
167                                 usage();
168                                 exit(1);
169                         }
170                         break;
171
172                 default:
173                         usage();
174                         exit(1);
175                 }
176
177         if (optind < argc) {
178
179                 /*
180                  * A number containing a decimal point is the frequency in MHz.
181                  */
182
183                 if ((ptr = strchr(argv[optind], '.')) != NULL) {
184                         freq = strtol(argv[optind], &endptr, 10) * 1000;
185                         if (ptr != endptr) {
186                                 usage();
187                                 exit(1);
188                         }
189
190                         ptr++;
191
192                         fraction = strtol(ptr, &endptr, 10);
193                         if (!isdigit(*ptr) || *endptr != '\0') {
194                                 usage();
195                                 exit(1);
196                         }
197
198                         for (i = endptr - ptr; i > 3; i--)
199                                 fraction /= 10;
200                         for (; i < 3; i++)
201                                 fraction *= 10;
202
203                         freq += fraction;
204                 }
205
206                 /* An integer is the channel. */
207                 else
208                         channel = atoi(argv[optind]);
209         }
210
211         if (afc == -1 && audio == -1 && !device && x_size == 0 && y_size == 0
212             && channel_set == -1 && !channel && !freq) {
213                 usage();
214                 exit(1);
215         }
216
217         sprintf(dev_name, DEVNAME_BASE "%d", unit);
218         tfd = open(dev_name, O_RDONLY);
219         if (tfd < 0) {
220                 fprintf(stderr, "Can't open %s: %s (%d)\n", dev_name,
221                         strerror(errno), errno);
222                 exit(1);
223         }
224
225         if (afc != -1)
226                 if (ioctl(tfd, TVTUNER_SETAFC, &afc) < 0) {
227                         perror("ioctl(tfd, TVTUNER_SETAFC) failed.");
228                         status = 1;
229                 }
230
231         if (device)
232                 if (ioctl(tfd, METEORSINPUT, &device) < 0) {
233                         perror("ioctl(tfd, METEORSINPUT) failed.");
234                         status = 1;
235                 }
236
237         if (audio != -1)
238                 if (ioctl(tfd, BT848_SAUDIO, &audio) < 0) {
239                         perror("ioctl(tfd, BT848_SAUDIO) failed.");
240                         status = 1;
241                 }
242
243         if (ioctl(tfd, BT848_GAUDIO, &audio) < 0) {
244                 perror("ioctl(tfd, BT848_GAUDIO) failed.");
245                 status = 1;
246         }
247
248         if (x_size && y_size) {
249                 memset(&cap, 0, sizeof(cap));
250                 cap.x_size = x_size;
251                 cap.y_size = y_size;
252                 if (ioctl(tfd, BT848_SCAPAREA, &cap) < 0) {
253                         perror("ioctl(tfd, BT848_SCAPAREA) failed.");
254                         status = 1;
255                 }
256         }
257
258         if (channel_set != -1)
259                 if (ioctl(tfd, TVTUNER_SETTYPE, &channel_set) < 0) {
260                         perror("ioctl(tfd, TVTUNER_SETTYPE) failed.");
261                         status = 1;
262                 }
263
264         if (channel) {
265                 if (ioctl(tfd, TVTUNER_SETCHNL, &channel) < 0) {
266                         perror("ioctl(tfd, TVTUNER_SETCHNL) failed.");
267                         status = 1;
268                 }
269         } else if (freq) {
270                 if (audio == AUDIO_INTERN) {
271                         /* Convert from kHz to MHz * 100 */
272                         freq = freq / 10;
273
274                         if (ioctl(tfd, RADIO_SETFREQ, &freq) < 0) {
275                                 perror("ioctl(tfd, RADIO_SETFREQ) failed.");
276                                 status = 1;
277                         }
278                 } else {
279                         /* Convert from kHz to MHz * 16 */
280                         freq = (freq * 16) / 1000;
281
282                         if (ioctl(tfd, TVTUNER_SETFREQ, &freq) < 0) {
283                                 perror("ioctl(tfd, TVTUNER_SETFREQ) failed.");
284                                 status = 1;
285                         }
286                 }
287         }
288
289         close(tfd);
290         exit(status);
291 }