xref: /dflybsd-src/tools/multimedia/cxm/setchannel/cxm_setchannel.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*-
2*86d7f5d3SJohn Marino  * Copyright (c) 2003, 2004, 2005
3*86d7f5d3SJohn Marino  *	John Wehle <john@feith.com>.  All rights reserved.
4*86d7f5d3SJohn Marino  *
5*86d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
6*86d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
7*86d7f5d3SJohn Marino  * are met:
8*86d7f5d3SJohn Marino  * 1. Redistributions of source code must retain the above copyright
9*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer.
10*86d7f5d3SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
11*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
12*86d7f5d3SJohn Marino  *    documentation and/or other materials provided with the distribution.
13*86d7f5d3SJohn Marino  * 3. All advertising materials mentioning features or use of this software
14*86d7f5d3SJohn Marino  *    must display the following acknowledgement:
15*86d7f5d3SJohn Marino  *	This product includes software developed by John Wehle.
16*86d7f5d3SJohn Marino  * 4. The name of the author may not be used to endorse or promote products
17*86d7f5d3SJohn Marino  *    derived from this software without specific prior written permission.
18*86d7f5d3SJohn Marino  *
19*86d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20*86d7f5d3SJohn Marino  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21*86d7f5d3SJohn Marino  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22*86d7f5d3SJohn Marino  * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23*86d7f5d3SJohn Marino  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24*86d7f5d3SJohn Marino  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25*86d7f5d3SJohn Marino  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*86d7f5d3SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27*86d7f5d3SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28*86d7f5d3SJohn Marino  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*86d7f5d3SJohn Marino  * POSSIBILITY OF SUCH DAMAGE.
30*86d7f5d3SJohn Marino  *
31*86d7f5d3SJohn Marino  * Set the channel of the tuner card.
32*86d7f5d3SJohn Marino  */
33*86d7f5d3SJohn Marino 
34*86d7f5d3SJohn Marino #include <sys/types.h>
35*86d7f5d3SJohn Marino #include <sys/param.h>
36*86d7f5d3SJohn Marino #include <sys/ioctl.h>
37*86d7f5d3SJohn Marino 
38*86d7f5d3SJohn Marino #include <ctype.h>
39*86d7f5d3SJohn Marino #include <err.h>
40*86d7f5d3SJohn Marino #include <fcntl.h>
41*86d7f5d3SJohn Marino #include <stdio.h>
42*86d7f5d3SJohn Marino #include <stdlib.h>
43*86d7f5d3SJohn Marino #include <string.h>
44*86d7f5d3SJohn Marino #include <unistd.h>
45*86d7f5d3SJohn Marino 
46*86d7f5d3SJohn Marino #include <dev/video/meteor/ioctl_meteor.h>
47*86d7f5d3SJohn Marino #include <dev/video/bktr/ioctl_bt848.h>
48*86d7f5d3SJohn Marino 
49*86d7f5d3SJohn Marino static void
usage(void)50*86d7f5d3SJohn Marino usage(void)
51*86d7f5d3SJohn Marino {
52*86d7f5d3SJohn Marino 	fprintf(stderr,
53*86d7f5d3SJohn Marino 	    "usage: cxm_setchannel [-a {on|off}] [-c | -r | -s | -t] [-d unit] [-g geom]\n"
54*86d7f5d3SJohn Marino 	    "                      [-m chnl_set] [chnl | freq]\n");
55*86d7f5d3SJohn Marino }
56*86d7f5d3SJohn Marino 
57*86d7f5d3SJohn Marino int
main(int argc,char * argv[])58*86d7f5d3SJohn Marino main(int argc, char *argv[])
59*86d7f5d3SJohn Marino {
60*86d7f5d3SJohn Marino 	char *ptr;
61*86d7f5d3SJohn Marino 	char *endptr;
62*86d7f5d3SJohn Marino 	char buf[255];
63*86d7f5d3SJohn Marino 	int afc;
64*86d7f5d3SJohn Marino 	int audio;
65*86d7f5d3SJohn Marino 	int c;
66*86d7f5d3SJohn Marino 	int channel_set;
67*86d7f5d3SJohn Marino 	int i;
68*86d7f5d3SJohn Marino 	int status;
69*86d7f5d3SJohn Marino 	int tfd;
70*86d7f5d3SJohn Marino 	int unit;
71*86d7f5d3SJohn Marino 	unsigned int channel;
72*86d7f5d3SJohn Marino 	unsigned int fraction;
73*86d7f5d3SJohn Marino 	unsigned int freq;
74*86d7f5d3SJohn Marino 	unsigned int x_size;
75*86d7f5d3SJohn Marino 	unsigned int y_size;
76*86d7f5d3SJohn Marino 	unsigned long device;
77*86d7f5d3SJohn Marino 	struct bktr_capture_area cap;
78*86d7f5d3SJohn Marino 
79*86d7f5d3SJohn Marino 	afc = -1;
80*86d7f5d3SJohn Marino 	audio = -1;
81*86d7f5d3SJohn Marino 	channel = 0;
82*86d7f5d3SJohn Marino 	channel_set = -1;
83*86d7f5d3SJohn Marino 	device = 0;
84*86d7f5d3SJohn Marino 	unit = 0;
85*86d7f5d3SJohn Marino 	freq = 0;
86*86d7f5d3SJohn Marino 	status = 0;
87*86d7f5d3SJohn Marino 	x_size = 0;
88*86d7f5d3SJohn Marino 	y_size = 0;
89*86d7f5d3SJohn Marino 
90*86d7f5d3SJohn Marino 	while ((c = getopt(argc, argv, "a:crstg:m:d:")) != -1)
91*86d7f5d3SJohn Marino 		switch (c) {
92*86d7f5d3SJohn Marino 		case 'a':
93*86d7f5d3SJohn Marino 			if (strcasecmp(optarg, "on") == 0)
94*86d7f5d3SJohn Marino 				afc = 1;
95*86d7f5d3SJohn Marino 			else if (strcasecmp(optarg, "off") == 0)
96*86d7f5d3SJohn Marino 				afc = 0;
97*86d7f5d3SJohn Marino 			else {
98*86d7f5d3SJohn Marino 				usage();
99*86d7f5d3SJohn Marino 				exit(1);
100*86d7f5d3SJohn Marino 			}
101*86d7f5d3SJohn Marino 			break;
102*86d7f5d3SJohn Marino 
103*86d7f5d3SJohn Marino 		case 'c':
104*86d7f5d3SJohn Marino 			device = METEOR_INPUT_DEV2;
105*86d7f5d3SJohn Marino 			audio = -1;
106*86d7f5d3SJohn Marino 			break;
107*86d7f5d3SJohn Marino 
108*86d7f5d3SJohn Marino 		case 'd':
109*86d7f5d3SJohn Marino 			unit = atoi(optarg);
110*86d7f5d3SJohn Marino 			break;
111*86d7f5d3SJohn Marino 
112*86d7f5d3SJohn Marino 		case 'r':
113*86d7f5d3SJohn Marino 			device = 0;
114*86d7f5d3SJohn Marino 			audio = AUDIO_INTERN;
115*86d7f5d3SJohn Marino 			break;
116*86d7f5d3SJohn Marino 
117*86d7f5d3SJohn Marino 		case 's':
118*86d7f5d3SJohn Marino 			device = METEOR_INPUT_DEV_SVIDEO;
119*86d7f5d3SJohn Marino 			audio = -1;
120*86d7f5d3SJohn Marino 			break;
121*86d7f5d3SJohn Marino 
122*86d7f5d3SJohn Marino 		case 't':
123*86d7f5d3SJohn Marino 			device = METEOR_INPUT_DEV1;
124*86d7f5d3SJohn Marino 			audio = -1;
125*86d7f5d3SJohn Marino 			break;
126*86d7f5d3SJohn Marino 
127*86d7f5d3SJohn Marino 		case 'g':
128*86d7f5d3SJohn Marino 			if (sscanf(optarg, "%ux%u", &x_size, &y_size) != 2 ||
129*86d7f5d3SJohn Marino 			    x_size == 0 || y_size == 0) {
130*86d7f5d3SJohn Marino 				usage();
131*86d7f5d3SJohn Marino 				exit(1);
132*86d7f5d3SJohn Marino 			}
133*86d7f5d3SJohn Marino 			break;
134*86d7f5d3SJohn Marino 
135*86d7f5d3SJohn Marino 		case 'm':
136*86d7f5d3SJohn Marino 			channel_set = atoi(optarg);
137*86d7f5d3SJohn Marino 			if (channel_set < 0 || channel_set > CHNLSET_MAX) {
138*86d7f5d3SJohn Marino 				usage();
139*86d7f5d3SJohn Marino 				exit(1);
140*86d7f5d3SJohn Marino 			}
141*86d7f5d3SJohn Marino 			break;
142*86d7f5d3SJohn Marino 
143*86d7f5d3SJohn Marino 		default:
144*86d7f5d3SJohn Marino 			usage();
145*86d7f5d3SJohn Marino 			exit(1);
146*86d7f5d3SJohn Marino 		}
147*86d7f5d3SJohn Marino 
148*86d7f5d3SJohn Marino 	if (optind < argc) {
149*86d7f5d3SJohn Marino 
150*86d7f5d3SJohn Marino 		/*
151*86d7f5d3SJohn Marino 		 * A number containing a decimal point is the frequency in
152*86d7f5d3SJohn Marino 		 * MHz.
153*86d7f5d3SJohn Marino 		 */
154*86d7f5d3SJohn Marino 
155*86d7f5d3SJohn Marino 		if ((ptr = strchr(argv[optind], '.')) != NULL) {
156*86d7f5d3SJohn Marino 			freq = strtol(argv[optind], &endptr, 10) * 1000;
157*86d7f5d3SJohn Marino 			if (ptr != endptr) {
158*86d7f5d3SJohn Marino 				usage();
159*86d7f5d3SJohn Marino 				exit(1);
160*86d7f5d3SJohn Marino 			}
161*86d7f5d3SJohn Marino 			ptr++;
162*86d7f5d3SJohn Marino 
163*86d7f5d3SJohn Marino 			fraction = strtol(ptr, &endptr, 10);
164*86d7f5d3SJohn Marino 			if (!isdigit(*ptr) || *endptr != '\0') {
165*86d7f5d3SJohn Marino 				usage();
166*86d7f5d3SJohn Marino 				exit(1);
167*86d7f5d3SJohn Marino 			}
168*86d7f5d3SJohn Marino 			for (i = endptr - ptr; i > 3; i--)
169*86d7f5d3SJohn Marino 				fraction /= 10;
170*86d7f5d3SJohn Marino 			for (; i < 3; i++)
171*86d7f5d3SJohn Marino 				fraction *= 10;
172*86d7f5d3SJohn Marino 
173*86d7f5d3SJohn Marino 			freq += fraction;
174*86d7f5d3SJohn Marino 		}
175*86d7f5d3SJohn Marino 		/*
176*86d7f5d3SJohn Marino 		 * An integer is the channel.
177*86d7f5d3SJohn Marino 		 */
178*86d7f5d3SJohn Marino 
179*86d7f5d3SJohn Marino 		else
180*86d7f5d3SJohn Marino 			channel = atoi(argv[optind]);
181*86d7f5d3SJohn Marino 	}
182*86d7f5d3SJohn Marino 	if (afc == -1 && audio == -1 && !device && x_size == 0 &&
183*86d7f5d3SJohn Marino 	    y_size == 0 && channel_set == -1 && !channel && !freq) {
184*86d7f5d3SJohn Marino 		usage();
185*86d7f5d3SJohn Marino 		exit(1);
186*86d7f5d3SJohn Marino 	}
187*86d7f5d3SJohn Marino 
188*86d7f5d3SJohn Marino 	sprintf(buf, "/dev/cxm%d", unit);
189*86d7f5d3SJohn Marino 
190*86d7f5d3SJohn Marino 	tfd = open(buf, O_RDONLY);
191*86d7f5d3SJohn Marino 	if (tfd < 0) {
192*86d7f5d3SJohn Marino 		warn("open() of /dev/cxm%d failed.", unit);
193*86d7f5d3SJohn Marino 		exit(1);
194*86d7f5d3SJohn Marino 	}
195*86d7f5d3SJohn Marino 
196*86d7f5d3SJohn Marino 	if (afc != -1) {
197*86d7f5d3SJohn Marino 		if (ioctl(tfd, TVTUNER_SETAFC, &afc) < 0) {
198*86d7f5d3SJohn Marino 			warn("ioctl( tfd, TVTUNER_SETAFC ) failed.");
199*86d7f5d3SJohn Marino 			status = 1;
200*86d7f5d3SJohn Marino 		}
201*86d7f5d3SJohn Marino 	}
202*86d7f5d3SJohn Marino 	if (device) {
203*86d7f5d3SJohn Marino 		if (ioctl(tfd, METEORSINPUT, &device) < 0) {
204*86d7f5d3SJohn Marino 			warn("ioctl( tfd, METEORSINPUT ) failed.");
205*86d7f5d3SJohn Marino 			status = 1;
206*86d7f5d3SJohn Marino 		}
207*86d7f5d3SJohn Marino 	}
208*86d7f5d3SJohn Marino 	if (audio != -1) {
209*86d7f5d3SJohn Marino 		if (ioctl(tfd, BT848_SAUDIO, &audio) < 0) {
210*86d7f5d3SJohn Marino 			warn("ioctl( tfd, BT848_SAUDIO ) failed.");
211*86d7f5d3SJohn Marino 			status = 1;
212*86d7f5d3SJohn Marino 		}
213*86d7f5d3SJohn Marino 	}
214*86d7f5d3SJohn Marino 	if (ioctl(tfd, BT848_GAUDIO, &audio) < 0) {
215*86d7f5d3SJohn Marino 		warn("ioctl( tfd, BT848_GAUDIO ) failed.");
216*86d7f5d3SJohn Marino 		status = 1;
217*86d7f5d3SJohn Marino 	}
218*86d7f5d3SJohn Marino 	if (x_size && y_size) {
219*86d7f5d3SJohn Marino 		memset(&cap, 0, sizeof(cap));
220*86d7f5d3SJohn Marino 		cap.x_size = x_size;
221*86d7f5d3SJohn Marino 		cap.y_size = y_size;
222*86d7f5d3SJohn Marino 		if (ioctl(tfd, BT848_SCAPAREA, &cap) < 0) {
223*86d7f5d3SJohn Marino 			warn("ioctl( tfd, BT848_SCAPAREA ) failed.");
224*86d7f5d3SJohn Marino 			status = 1;
225*86d7f5d3SJohn Marino 		}
226*86d7f5d3SJohn Marino 	}
227*86d7f5d3SJohn Marino 	if (channel_set != -1) {
228*86d7f5d3SJohn Marino 		if (ioctl(tfd, TVTUNER_SETTYPE, &channel_set) < 0) {
229*86d7f5d3SJohn Marino 			warn("ioctl( tfd, TVTUNER_SETTYPE ) failed.");
230*86d7f5d3SJohn Marino 			status = 1;
231*86d7f5d3SJohn Marino 		}
232*86d7f5d3SJohn Marino 	}
233*86d7f5d3SJohn Marino 	if (channel) {
234*86d7f5d3SJohn Marino 		if (ioctl(tfd, TVTUNER_SETCHNL, &channel) < 0) {
235*86d7f5d3SJohn Marino 			warn("ioctl( tfd, TVTUNER_SETCHNL ) failed.");
236*86d7f5d3SJohn Marino 			status = 1;
237*86d7f5d3SJohn Marino 		}
238*86d7f5d3SJohn Marino 	} else if (freq) {
239*86d7f5d3SJohn Marino 		if (audio == AUDIO_INTERN) {
240*86d7f5d3SJohn Marino 			/* Convert from kHz to MHz * 100 */
241*86d7f5d3SJohn Marino 			freq = freq / 10;
242*86d7f5d3SJohn Marino 
243*86d7f5d3SJohn Marino 			if (ioctl(tfd, RADIO_SETFREQ, &freq) < 0) {
244*86d7f5d3SJohn Marino 				warn("ioctl( tfd, RADIO_SETFREQ ) failed.");
245*86d7f5d3SJohn Marino 				status = 1;
246*86d7f5d3SJohn Marino 			}
247*86d7f5d3SJohn Marino 		} else {
248*86d7f5d3SJohn Marino 			/* Convert from kHz to MHz * 16 */
249*86d7f5d3SJohn Marino 			freq = (freq * 16) / 1000;
250*86d7f5d3SJohn Marino 
251*86d7f5d3SJohn Marino 			if (ioctl(tfd, TVTUNER_SETFREQ, &freq) < 0) {
252*86d7f5d3SJohn Marino 				warn("ioctl( tfd, TVTUNER_SETFREQ ) failed.");
253*86d7f5d3SJohn Marino 				status = 1;
254*86d7f5d3SJohn Marino 			}
255*86d7f5d3SJohn Marino 		}
256*86d7f5d3SJohn Marino 	}
257*86d7f5d3SJohn Marino 	close(tfd);
258*86d7f5d3SJohn Marino 	exit(status);
259*86d7f5d3SJohn Marino }
260