• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     mxb - v4l2 driver for the Multimedia eXtension Board
3 
4     Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
5 
6     Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
7     for further details about this card.
8 
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 2 of the License, or
12     (at your option) any later version.
13 
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with this program; if not, write to the Free Software
21     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23 
24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25 
26 #define DEBUG_VARIABLE debug
27 
28 #include <media/saa7146_vv.h>
29 #include <media/tuner.h>
30 #include <media/v4l2-common.h>
31 #include <media/saa7115.h>
32 #include <linux/module.h>
33 
34 #include "mxb.h"
35 #include "tea6415c.h"
36 #include "tea6420.h"
37 
38 #define I2C_SAA7111A  0x24
39 #define	I2C_TDA9840   0x42
40 #define	I2C_TEA6415C  0x43
41 #define	I2C_TEA6420_1 0x4c
42 #define	I2C_TEA6420_2 0x4d
43 #define	I2C_TUNER     0x60
44 
45 #define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0)
46 
47 /* global variable */
48 static int mxb_num;
49 
50 /* initial frequence the tuner will be tuned to.
51    in verden (lower saxony, germany) 4148 is a
52    channel called "phoenix" */
53 static int freq = 4148;
54 module_param(freq, int, 0644);
55 MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
56 
57 static int debug;
58 module_param(debug, int, 0644);
59 MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
60 
61 #define MXB_INPUTS 4
62 enum { TUNER, AUX1, AUX3, AUX3_YC };
63 
64 static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
65 	{ TUNER,	"Tuner",		V4L2_INPUT_TYPE_TUNER,	1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
66 	{ AUX1,		"AUX1",			V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
67 	{ AUX3,		"AUX3 Composite",	V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
68 	{ AUX3_YC,	"AUX3 S-Video",		V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
69 };
70 
71 /* this array holds the information, which port of the saa7146 each
72    input actually uses. the mxb uses port 0 for every input */
73 static struct {
74 	int hps_source;
75 	int hps_sync;
76 } input_port_selection[MXB_INPUTS] = {
77 	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
78 	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
79 	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
80 	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
81 };
82 
83 /* this array holds the information of the audio source (mxb_audios),
84    which has to be switched corresponding to the video source (mxb_channels) */
85 static int video_audio_connect[MXB_INPUTS] =
86 	{ 0, 1, 3, 3 };
87 
88 struct mxb_routing {
89 	u32 input;
90 	u32 output;
91 };
92 
93 /* These are the necessary input-output-pins for bringing one audio source
94    (see above) to the CD-output. Note that gain is set to 0 in this table. */
95 static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
96 	{ { 1, 1 }, { 1, 1 } },	/* Tuner */
97 	{ { 5, 1 }, { 6, 1 } },	/* AUX 1 */
98 	{ { 4, 1 }, { 6, 1 } },	/* AUX 2 */
99 	{ { 3, 1 }, { 6, 1 } },	/* AUX 3 */
100 	{ { 1, 1 }, { 3, 1 } },	/* Radio */
101 	{ { 1, 1 }, { 2, 1 } },	/* CD-Rom */
102 	{ { 6, 1 }, { 6, 1 } }	/* Mute */
103 };
104 
105 /* These are the necessary input-output-pins for bringing one audio source
106    (see above) to the line-output. Note that gain is set to 0 in this table. */
107 static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
108 	{ { 2, 3 }, { 1, 2 } },
109 	{ { 5, 3 }, { 6, 2 } },
110 	{ { 4, 3 }, { 6, 2 } },
111 	{ { 3, 3 }, { 6, 2 } },
112 	{ { 2, 3 }, { 3, 2 } },
113 	{ { 2, 3 }, { 2, 2 } },
114 	{ { 6, 3 }, { 6, 2 } }	/* Mute */
115 };
116 
117 #define MAXCONTROLS	1
118 static struct v4l2_queryctrl mxb_controls[] = {
119 	{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
120 };
121 
122 struct mxb
123 {
124 	struct video_device	*video_dev;
125 	struct video_device	*vbi_dev;
126 
127 	struct i2c_adapter	i2c_adapter;
128 
129 	struct v4l2_subdev	*saa7111a;
130 	struct v4l2_subdev	*tda9840;
131 	struct v4l2_subdev	*tea6415c;
132 	struct v4l2_subdev	*tuner;
133 	struct v4l2_subdev	*tea6420_1;
134 	struct v4l2_subdev	*tea6420_2;
135 
136 	int	cur_mode;	/* current audio mode (mono, stereo, ...) */
137 	int	cur_input;	/* current input */
138 	int	cur_mute;	/* current mute status */
139 	struct v4l2_frequency	cur_freq;	/* current frequency the tuner is tuned to */
140 };
141 
142 #define saa7111a_call(mxb, o, f, args...) \
143 	v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
144 #define tda9840_call(mxb, o, f, args...) \
145 	v4l2_subdev_call(mxb->tda9840, o, f, ##args)
146 #define tea6415c_call(mxb, o, f, args...) \
147 	v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
148 #define tuner_call(mxb, o, f, args...) \
149 	v4l2_subdev_call(mxb->tuner, o, f, ##args)
150 #define call_all(dev, o, f, args...) \
151 	v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
152 
tea6420_route_cd(struct mxb * mxb,int idx)153 static inline void tea6420_route_cd(struct mxb *mxb, int idx)
154 {
155 	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
156 		TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
157 	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
158 		TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
159 }
160 
tea6420_route_line(struct mxb * mxb,int idx)161 static inline void tea6420_route_line(struct mxb *mxb, int idx)
162 {
163 	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
164 		TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
165 	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
166 		TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
167 }
168 
169 static struct saa7146_extension extension;
170 
mxb_probe(struct saa7146_dev * dev)171 static int mxb_probe(struct saa7146_dev *dev)
172 {
173 	struct mxb *mxb = NULL;
174 
175 	mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
176 	if (mxb == NULL) {
177 		DEB_D("not enough kernel memory\n");
178 		return -ENOMEM;
179 	}
180 
181 	snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
182 
183 	saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
184 	if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
185 		DEB_S("cannot register i2c-device. skipping.\n");
186 		kfree(mxb);
187 		return -EFAULT;
188 	}
189 
190 	mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
191 			"saa7111", I2C_SAA7111A, NULL);
192 	mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
193 			"tea6420", I2C_TEA6420_1, NULL);
194 	mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
195 			"tea6420", I2C_TEA6420_2, NULL);
196 	mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
197 			"tea6415c", I2C_TEA6415C, NULL);
198 	mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
199 			"tda9840", I2C_TDA9840, NULL);
200 	mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
201 			"tuner", I2C_TUNER, NULL);
202 
203 	/* check if all devices are present */
204 	if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
205 	    !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
206 		pr_err("did not find all i2c devices. aborting\n");
207 		i2c_del_adapter(&mxb->i2c_adapter);
208 		kfree(mxb);
209 		return -ENODEV;
210 	}
211 
212 	/* all devices are present, probe was successful */
213 
214 	/* we store the pointer in our private data field */
215 	dev->ext_priv = mxb;
216 
217 	return 0;
218 }
219 
220 /* some init data for the saa7740, the so-called 'sound arena module'.
221    there are no specs available, so we simply use some init values */
222 static struct {
223 	int	length;
224 	char	data[9];
225 } mxb_saa7740_init[] = {
226 	{ 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
227 	{ 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
228 	{ 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
229 	{ 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
230 	{ 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
231 	{ 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
232 	{ 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
233 	{ 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
234 	{ 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
235 	{ 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
236 	{ 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
237 	{ 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
238 	{ 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
239 	{ 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
240 	{ 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
241 	{ 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
242 	{ 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
243 	{ 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
244 	{ 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
245 	{ 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
246 	{ 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
247 	{ 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
248 	{ 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
249 	{ 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
250 	{ 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
251 	{ 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
252 	{ 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
253 	{ 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
254 	{ 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
255 	{ 3, { 0x48, 0x00, 0x01 } },
256 	{ 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
257 	{ 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
258 	{ 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
259 	{ 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
260 	{ 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
261 	{ 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
262 	{ 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
263 	{ 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
264 	{ 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
265 	{ 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
266 	{ 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
267 	{ 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
268 	{ 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
269 	{ 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
270 	{ 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
271 	{ 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
272 	{ 3, { 0x80, 0xb3, 0x0a } },
273 	{-1, { 0 } }
274 };
275 
276 /* bring hardware to a sane state. this has to be done, just in case someone
277    wants to capture from this device before it has been properly initialized.
278    the capture engine would badly fail, because no valid signal arrives on the
279    saa7146, thus leading to timeouts and stuff. */
mxb_init_done(struct saa7146_dev * dev)280 static int mxb_init_done(struct saa7146_dev* dev)
281 {
282 	struct mxb* mxb = (struct mxb*)dev->ext_priv;
283 	struct i2c_msg msg;
284 	struct tuner_setup tun_setup;
285 	v4l2_std_id std = V4L2_STD_PAL_BG;
286 
287 	int i = 0, err = 0;
288 
289 	/* select video mode in saa7111a */
290 	saa7111a_call(mxb, core, s_std, std);
291 
292 	/* select tuner-output on saa7111a */
293 	i = 0;
294 	saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
295 		SAA7111_FMT_CCIR, 0);
296 
297 	/* select a tuner type */
298 	tun_setup.mode_mask = T_ANALOG_TV;
299 	tun_setup.addr = ADDR_UNSET;
300 	tun_setup.type = TUNER_PHILIPS_PAL;
301 	tuner_call(mxb, tuner, s_type_addr, &tun_setup);
302 	/* tune in some frequency on tuner */
303 	mxb->cur_freq.tuner = 0;
304 	mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
305 	mxb->cur_freq.frequency = freq;
306 	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
307 
308 	/* set a default video standard */
309 	tuner_call(mxb, core, s_std, std);
310 
311 	/* mute audio on tea6420s */
312 	tea6420_route_line(mxb, 6);
313 	tea6420_route_cd(mxb, 6);
314 
315 	/* switch to tuner-channel on tea6415c */
316 	tea6415c_call(mxb, video, s_routing, 3, 17, 0);
317 
318 	/* select tuner-output on multicable on tea6415c */
319 	tea6415c_call(mxb, video, s_routing, 3, 13, 0);
320 
321 	/* the rest for mxb */
322 	mxb->cur_input = 0;
323 	mxb->cur_mute = 1;
324 
325 	mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
326 
327 	/* check if the saa7740 (aka 'sound arena module') is present
328 	   on the mxb. if so, we must initialize it. due to lack of
329 	   informations about the saa7740, the values were reverse
330 	   engineered. */
331 	msg.addr = 0x1b;
332 	msg.flags = 0;
333 	msg.len = mxb_saa7740_init[0].length;
334 	msg.buf = &mxb_saa7740_init[0].data[0];
335 
336 	err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
337 	if (err == 1) {
338 		/* the sound arena module is a pos, that's probably the reason
339 		   philips refuses to hand out a datasheet for the saa7740...
340 		   it seems to screw up the i2c bus, so we disable fast irq
341 		   based i2c transactions here and rely on the slow and safe
342 		   polling method ... */
343 		extension.flags &= ~SAA7146_USE_I2C_IRQ;
344 		for (i = 1; ; i++) {
345 			if (-1 == mxb_saa7740_init[i].length)
346 				break;
347 
348 			msg.len = mxb_saa7740_init[i].length;
349 			msg.buf = &mxb_saa7740_init[i].data[0];
350 			err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
351 			if (err != 1) {
352 				DEB_D("failed to initialize 'sound arena module'\n");
353 				goto err;
354 			}
355 		}
356 		pr_info("'sound arena module' detected\n");
357 	}
358 err:
359 	/* the rest for saa7146: you should definitely set some basic values
360 	   for the input-port handling of the saa7146. */
361 
362 	/* ext->saa has been filled by the core driver */
363 
364 	/* some stuff is done via variables */
365 	saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
366 			input_port_selection[mxb->cur_input].hps_sync);
367 
368 	/* some stuff is done via direct write to the registers */
369 
370 	/* this is ugly, but because of the fact that this is completely
371 	   hardware dependend, it should be done directly... */
372 	saa7146_write(dev, DD1_STREAM_B,	0x00000000);
373 	saa7146_write(dev, DD1_INIT,		0x02000200);
374 	saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
375 
376 	return 0;
377 }
378 
379 /* interrupt-handler. this gets called when irq_mask is != 0.
380    it must clear the interrupt-bits in irq_mask it has handled */
381 /*
382 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
383 {
384 	struct mxb* mxb = (struct mxb*)dev->ext_priv;
385 }
386 */
387 
vidioc_queryctrl(struct file * file,void * fh,struct v4l2_queryctrl * qc)388 static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
389 {
390 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
391 	int i;
392 
393 	for (i = MAXCONTROLS - 1; i >= 0; i--) {
394 		if (mxb_controls[i].id == qc->id) {
395 			*qc = mxb_controls[i];
396 			DEB_D("VIDIOC_QUERYCTRL %d\n", qc->id);
397 			return 0;
398 		}
399 	}
400 	return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
401 }
402 
vidioc_g_ctrl(struct file * file,void * fh,struct v4l2_control * vc)403 static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
404 {
405 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
406 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
407 	int i;
408 
409 	for (i = MAXCONTROLS - 1; i >= 0; i--) {
410 		if (mxb_controls[i].id == vc->id)
411 			break;
412 	}
413 
414 	if (i < 0)
415 		return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
416 
417 	if (vc->id == V4L2_CID_AUDIO_MUTE) {
418 		vc->value = mxb->cur_mute;
419 		DEB_D("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d\n", vc->value);
420 		return 0;
421 	}
422 
423 	DEB_EE("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d\n", vc->value);
424 	return 0;
425 }
426 
vidioc_s_ctrl(struct file * file,void * fh,struct v4l2_control * vc)427 static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
428 {
429 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
430 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
431 	int i = 0;
432 
433 	for (i = MAXCONTROLS - 1; i >= 0; i--) {
434 		if (mxb_controls[i].id == vc->id)
435 			break;
436 	}
437 
438 	if (i < 0)
439 		return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
440 
441 	if (vc->id == V4L2_CID_AUDIO_MUTE) {
442 		mxb->cur_mute = vc->value;
443 		/* switch the audio-source */
444 		tea6420_route_line(mxb, vc->value ? 6 :
445 				video_audio_connect[mxb->cur_input]);
446 		DEB_EE("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d\n", vc->value);
447 	}
448 	return 0;
449 }
450 
vidioc_enum_input(struct file * file,void * fh,struct v4l2_input * i)451 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
452 {
453 	DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
454 	if (i->index >= MXB_INPUTS)
455 		return -EINVAL;
456 	memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
457 	return 0;
458 }
459 
vidioc_g_input(struct file * file,void * fh,unsigned int * i)460 static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
461 {
462 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
463 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
464 	*i = mxb->cur_input;
465 
466 	DEB_EE("VIDIOC_G_INPUT %d\n", *i);
467 	return 0;
468 }
469 
vidioc_s_input(struct file * file,void * fh,unsigned int input)470 static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
471 {
472 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
473 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
474 	int err = 0;
475 	int i = 0;
476 
477 	DEB_EE("VIDIOC_S_INPUT %d\n", input);
478 
479 	if (input >= MXB_INPUTS)
480 		return -EINVAL;
481 
482 	mxb->cur_input = input;
483 
484 	saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
485 			input_port_selection[input].hps_sync);
486 
487 	/* prepare switching of tea6415c and saa7111a;
488 	   have a look at the 'background'-file for further informations  */
489 	switch (input) {
490 	case TUNER:
491 		i = SAA7115_COMPOSITE0;
492 
493 		err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
494 
495 		/* connect tuner-output always to multicable */
496 		if (!err)
497 			err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
498 		break;
499 	case AUX3_YC:
500 		/* nothing to be done here. aux3_yc is
501 		   directly connected to the saa711a */
502 		i = SAA7115_SVIDEO1;
503 		break;
504 	case AUX3:
505 		/* nothing to be done here. aux3 is
506 		   directly connected to the saa711a */
507 		i = SAA7115_COMPOSITE1;
508 		break;
509 	case AUX1:
510 		i = SAA7115_COMPOSITE0;
511 		err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
512 		break;
513 	}
514 
515 	if (err)
516 		return err;
517 
518 	/* switch video in saa7111a */
519 	if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
520 		pr_err("VIDIOC_S_INPUT: could not address saa7111a\n");
521 
522 	/* switch the audio-source only if necessary */
523 	if (0 == mxb->cur_mute)
524 		tea6420_route_line(mxb, video_audio_connect[input]);
525 
526 	return 0;
527 }
528 
vidioc_g_tuner(struct file * file,void * fh,struct v4l2_tuner * t)529 static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
530 {
531 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
532 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
533 
534 	if (t->index) {
535 		DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n",
536 		      t->index);
537 		return -EINVAL;
538 	}
539 
540 	DEB_EE("VIDIOC_G_TUNER: %d\n", t->index);
541 
542 	memset(t, 0, sizeof(*t));
543 	strlcpy(t->name, "TV Tuner", sizeof(t->name));
544 	t->type = V4L2_TUNER_ANALOG_TV;
545 	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
546 			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
547 	t->audmode = mxb->cur_mode;
548 	return call_all(dev, tuner, g_tuner, t);
549 }
550 
vidioc_s_tuner(struct file * file,void * fh,struct v4l2_tuner * t)551 static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
552 {
553 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
554 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
555 
556 	if (t->index) {
557 		DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n",
558 		      t->index);
559 		return -EINVAL;
560 	}
561 
562 	mxb->cur_mode = t->audmode;
563 	return call_all(dev, tuner, s_tuner, t);
564 }
565 
vidioc_g_frequency(struct file * file,void * fh,struct v4l2_frequency * f)566 static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
567 {
568 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
569 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
570 
571 	if (mxb->cur_input) {
572 		DEB_D("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
573 		      mxb->cur_input);
574 		return -EINVAL;
575 	}
576 
577 	*f = mxb->cur_freq;
578 
579 	DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency);
580 	return 0;
581 }
582 
vidioc_s_frequency(struct file * file,void * fh,struct v4l2_frequency * f)583 static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
584 {
585 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
586 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
587 	struct saa7146_vv *vv = dev->vv_data;
588 
589 	if (f->tuner)
590 		return -EINVAL;
591 
592 	if (V4L2_TUNER_ANALOG_TV != f->type)
593 		return -EINVAL;
594 
595 	if (mxb->cur_input) {
596 		DEB_D("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",
597 		      mxb->cur_input);
598 		return -EINVAL;
599 	}
600 
601 	mxb->cur_freq = *f;
602 	DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency);
603 
604 	/* tune in desired frequency */
605 	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
606 
607 	/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
608 	spin_lock(&dev->slock);
609 	vv->vbi_fieldcount = 0;
610 	spin_unlock(&dev->slock);
611 
612 	return 0;
613 }
614 
vidioc_g_audio(struct file * file,void * fh,struct v4l2_audio * a)615 static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
616 {
617 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
618 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
619 
620 	if (a->index > MXB_INPUTS) {
621 		DEB_D("VIDIOC_G_AUDIO %d out of range\n", a->index);
622 		return -EINVAL;
623 	}
624 
625 	DEB_EE("VIDIOC_G_AUDIO %d\n", a->index);
626 	memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
627 	return 0;
628 }
629 
vidioc_s_audio(struct file * file,void * fh,struct v4l2_audio * a)630 static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
631 {
632 	DEB_D("VIDIOC_S_AUDIO %d\n", a->index);
633 	return 0;
634 }
635 
636 #ifdef CONFIG_VIDEO_ADV_DEBUG
vidioc_g_register(struct file * file,void * fh,struct v4l2_dbg_register * reg)637 static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
638 {
639 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
640 
641 	return call_all(dev, core, g_register, reg);
642 }
643 
vidioc_s_register(struct file * file,void * fh,struct v4l2_dbg_register * reg)644 static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
645 {
646 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
647 
648 	return call_all(dev, core, s_register, reg);
649 }
650 #endif
651 
vidioc_default(struct file * file,void * fh,bool valid_prio,int cmd,void * arg)652 static long vidioc_default(struct file *file, void *fh, bool valid_prio,
653 							int cmd, void *arg)
654 {
655 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
656 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
657 
658 	switch (cmd) {
659 	case MXB_S_AUDIO_CD:
660 	{
661 		int i = *(int *)arg;
662 
663 		if (i < 0 || i >= MXB_AUDIOS) {
664 			DEB_D("invalid argument to MXB_S_AUDIO_CD: i:%d\n", i);
665 			return -EINVAL;
666 		}
667 
668 		DEB_EE("MXB_S_AUDIO_CD: i:%d\n", i);
669 
670 		tea6420_route_cd(mxb, i);
671 		return 0;
672 	}
673 	case MXB_S_AUDIO_LINE:
674 	{
675 		int i = *(int *)arg;
676 
677 		if (i < 0 || i >= MXB_AUDIOS) {
678 			DEB_D("invalid argument to MXB_S_AUDIO_LINE: i:%d\n",
679 			      i);
680 			return -EINVAL;
681 		}
682 
683 		DEB_EE("MXB_S_AUDIO_LINE: i:%d\n", i);
684 		tea6420_route_line(mxb, i);
685 		return 0;
686 	}
687 	default:
688 /*
689 		DEB2(pr_err("does not handle this ioctl\n"));
690 */
691 		return -ENOIOCTLCMD;
692 	}
693 	return 0;
694 }
695 
696 static struct saa7146_ext_vv vv_data;
697 
698 /* this function only gets called when the probing was successful */
mxb_attach(struct saa7146_dev * dev,struct saa7146_pci_extension_data * info)699 static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
700 {
701 	struct mxb *mxb;
702 
703 	DEB_EE("dev:%p\n", dev);
704 
705 	saa7146_vv_init(dev, &vv_data);
706 	if (mxb_probe(dev)) {
707 		saa7146_vv_release(dev);
708 		return -1;
709 	}
710 	mxb = (struct mxb *)dev->ext_priv;
711 
712 	vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
713 	vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
714 	vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
715 	vv_data.ops.vidioc_enum_input = vidioc_enum_input;
716 	vv_data.ops.vidioc_g_input = vidioc_g_input;
717 	vv_data.ops.vidioc_s_input = vidioc_s_input;
718 	vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
719 	vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
720 	vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
721 	vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
722 	vv_data.ops.vidioc_g_audio = vidioc_g_audio;
723 	vv_data.ops.vidioc_s_audio = vidioc_s_audio;
724 #ifdef CONFIG_VIDEO_ADV_DEBUG
725 	vv_data.ops.vidioc_g_register = vidioc_g_register;
726 	vv_data.ops.vidioc_s_register = vidioc_s_register;
727 #endif
728 	vv_data.ops.vidioc_default = vidioc_default;
729 	if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
730 		ERR("cannot register capture v4l2 device. skipping.\n");
731 		saa7146_vv_release(dev);
732 		return -1;
733 	}
734 
735 	/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
736 	if (MXB_BOARD_CAN_DO_VBI(dev)) {
737 		if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
738 			ERR("cannot register vbi v4l2 device. skipping.\n");
739 		}
740 	}
741 
742 	pr_info("found Multimedia eXtension Board #%d\n", mxb_num);
743 
744 	mxb_num++;
745 	mxb_init_done(dev);
746 	return 0;
747 }
748 
mxb_detach(struct saa7146_dev * dev)749 static int mxb_detach(struct saa7146_dev *dev)
750 {
751 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
752 
753 	DEB_EE("dev:%p\n", dev);
754 
755 	saa7146_unregister_device(&mxb->video_dev,dev);
756 	if (MXB_BOARD_CAN_DO_VBI(dev))
757 		saa7146_unregister_device(&mxb->vbi_dev, dev);
758 	saa7146_vv_release(dev);
759 
760 	mxb_num--;
761 
762 	i2c_del_adapter(&mxb->i2c_adapter);
763 	kfree(mxb);
764 
765 	return 0;
766 }
767 
std_callback(struct saa7146_dev * dev,struct saa7146_standard * standard)768 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
769 {
770 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
771 
772 	if (V4L2_STD_PAL_I == standard->id) {
773 		v4l2_std_id std = V4L2_STD_PAL_I;
774 
775 		DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n");
776 		/* set the 7146 gpio register -- I don't know what this does exactly */
777 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
778 		/* unset the 7111 gpio register -- I don't know what this does exactly */
779 		saa7111a_call(mxb, core, s_gpio, 0);
780 		tuner_call(mxb, core, s_std, std);
781 	} else {
782 		v4l2_std_id std = V4L2_STD_PAL_BG;
783 
784 		DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n");
785 		/* set the 7146 gpio register -- I don't know what this does exactly */
786 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
787 		/* set the 7111 gpio register -- I don't know what this does exactly */
788 		saa7111a_call(mxb, core, s_gpio, 1);
789 		tuner_call(mxb, core, s_std, std);
790 	}
791 	return 0;
792 }
793 
794 static struct saa7146_standard standard[] = {
795 	{
796 		.name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,
797 		.v_offset	= 0x17,	.v_field 	= 288,
798 		.h_offset	= 0x14,	.h_pixels 	= 680,
799 		.v_max_out	= 576,	.h_max_out	= 768,
800 	}, {
801 		.name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,
802 		.v_offset	= 0x17,	.v_field 	= 288,
803 		.h_offset	= 0x14,	.h_pixels 	= 680,
804 		.v_max_out	= 576,	.h_max_out	= 768,
805 	}, {
806 		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
807 		.v_offset	= 0x16,	.v_field 	= 240,
808 		.h_offset	= 0x06,	.h_pixels 	= 708,
809 		.v_max_out	= 480,	.h_max_out	= 640,
810 	}, {
811 		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
812 		.v_offset	= 0x14,	.v_field 	= 288,
813 		.h_offset	= 0x14,	.h_pixels 	= 720,
814 		.v_max_out	= 576,	.h_max_out	= 768,
815 	}
816 };
817 
818 static struct saa7146_pci_extension_data mxb = {
819 	.ext_priv = "Multimedia eXtension Board",
820 	.ext = &extension,
821 };
822 
823 static struct pci_device_id pci_tbl[] = {
824 	{
825 		.vendor    = PCI_VENDOR_ID_PHILIPS,
826 		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,
827 		.subvendor = 0x0000,
828 		.subdevice = 0x0000,
829 		.driver_data = (unsigned long)&mxb,
830 	}, {
831 		.vendor	= 0,
832 	}
833 };
834 
835 MODULE_DEVICE_TABLE(pci, pci_tbl);
836 
837 static struct saa7146_ext_vv vv_data = {
838 	.inputs		= MXB_INPUTS,
839 	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
840 	.stds		= &standard[0],
841 	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),
842 	.std_callback	= &std_callback,
843 };
844 
845 static struct saa7146_extension extension = {
846 	.name		= MXB_IDENTIFIER,
847 	.flags		= SAA7146_USE_I2C_IRQ,
848 
849 	.pci_tbl	= &pci_tbl[0],
850 	.module		= THIS_MODULE,
851 
852 	.attach		= mxb_attach,
853 	.detach		= mxb_detach,
854 
855 	.irq_mask	= 0,
856 	.irq_func	= NULL,
857 };
858 
mxb_init_module(void)859 static int __init mxb_init_module(void)
860 {
861 	if (saa7146_register_extension(&extension)) {
862 		DEB_S("failed to register extension\n");
863 		return -ENODEV;
864 	}
865 
866 	return 0;
867 }
868 
mxb_cleanup_module(void)869 static void __exit mxb_cleanup_module(void)
870 {
871 	saa7146_unregister_extension(&extension);
872 }
873 
874 module_init(mxb_init_module);
875 module_exit(mxb_cleanup_module);
876 
877 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
878 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
879 MODULE_LICENSE("GPL");
880