2 mxb - v4l2 driver for the Multimedia eXtension Board
4 Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
6 Visit http://www.mihu.de/linux/saa7146/mxb/
7 for further details about this card.
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.
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.
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.
24 #define DEBUG_VARIABLE debug
26 #include <media/saa7146_vv.h>
27 #include <media/tuner.h>
28 #include <linux/video_decoder.h>
29 #include <media/v4l2-common.h>
36 #define I2C_SAA7111 0x24
38 #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
41 static int mxb_num = 0;
43 /* initial frequence the tuner will be tuned to.
44 in verden (lower saxony, germany) 4148 is a
45 channel called "phoenix" */
46 static int freq = 4148;
47 module_param(freq, int, 0644);
48 MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
51 module_param(debug, int, 0644);
52 MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
55 enum { TUNER, AUX1, AUX3, AUX3_YC };
57 static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
58 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
59 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
60 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
61 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
64 /* this array holds the information, which port of the saa7146 each
65 input actually uses. the mxb uses port 0 for every input */
69 } input_port_selection[MXB_INPUTS] = {
70 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
71 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
72 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
73 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
76 /* this array holds the information of the audio source (mxb_audios),
77 which has to be switched corresponding to the video source (mxb_channels) */
78 static int video_audio_connect[MXB_INPUTS] =
81 /* these are the necessary input-output-pins for bringing one audio source
82 (see above) to the CD-output */
83 static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
85 {{1,1,0},{1,1,0}}, /* Tuner */
86 {{5,1,0},{6,1,0}}, /* AUX 1 */
87 {{4,1,0},{6,1,0}}, /* AUX 2 */
88 {{3,1,0},{6,1,0}}, /* AUX 3 */
89 {{1,1,0},{3,1,0}}, /* Radio */
90 {{1,1,0},{2,1,0}}, /* CD-Rom */
91 {{6,1,0},{6,1,0}} /* Mute */
94 /* these are the necessary input-output-pins for bringing one audio source
95 (see above) to the line-output */
96 static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
104 {{6,3,0},{6,2,0}} /* Mute */
107 #define MAXCONTROLS 1
108 static struct v4l2_queryctrl mxb_controls[] = {
109 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
112 static struct saa7146_extension_ioctls ioctls[] = {
113 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
114 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
115 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
116 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
117 { VIDIOC_G_CTRL, SAA7146_BEFORE },
118 { VIDIOC_S_CTRL, SAA7146_BEFORE },
119 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
120 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
121 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
122 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
123 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
124 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
125 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
126 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
132 struct video_device *video_dev;
133 struct video_device *vbi_dev;
135 struct i2c_adapter i2c_adapter;
137 struct i2c_client* saa7111a;
138 struct i2c_client* tda9840;
139 struct i2c_client* tea6415c;
140 struct i2c_client* tuner;
141 struct i2c_client* tea6420_1;
142 struct i2c_client* tea6420_2;
144 int cur_mode; /* current audio mode (mono, stereo, ...) */
145 int cur_input; /* current input */
146 int cur_mute; /* current mute status */
147 struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
150 static struct saa7146_extension extension;
152 static int mxb_check_clients(struct device *dev, void *data)
154 struct mxb* mxb = data;
155 struct i2c_client *client = i2c_verify_client(dev);
160 if( I2C_ADDR_TEA6420_1 == client->addr )
161 mxb->tea6420_1 = client;
162 if( I2C_ADDR_TEA6420_2 == client->addr )
163 mxb->tea6420_2 = client;
164 if( I2C_TEA6415C_2 == client->addr )
165 mxb->tea6415c = client;
166 if( I2C_ADDR_TDA9840 == client->addr )
167 mxb->tda9840 = client;
168 if( I2C_SAA7111 == client->addr )
169 mxb->saa7111a = client;
170 if( 0x60 == client->addr )
176 static int mxb_probe(struct saa7146_dev* dev)
178 struct mxb* mxb = NULL;
181 if ((result = request_module("saa7111")) < 0) {
182 printk("mxb: saa7111 i2c module not available.\n");
185 if ((result = request_module("tea6420")) < 0) {
186 printk("mxb: tea6420 i2c module not available.\n");
189 if ((result = request_module("tea6415c")) < 0) {
190 printk("mxb: tea6415c i2c module not available.\n");
193 if ((result = request_module("tda9840")) < 0) {
194 printk("mxb: tda9840 i2c module not available.\n");
197 if ((result = request_module("tuner")) < 0) {
198 printk("mxb: tuner i2c module not available.\n");
202 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
204 DEB_D(("not enough kernel memory.\n"));
208 mxb->i2c_adapter = (struct i2c_adapter) {
209 .class = I2C_CLASS_TV_ANALOG,
213 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
214 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
215 DEB_S(("cannot register i2c-device. skipping.\n"));
220 /* loop through all i2c-devices on the bus and look who is there */
221 device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
223 /* check if all devices are present */
224 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
225 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
227 printk("mxb: did not find all i2c devices. aborting\n");
228 i2c_del_adapter(&mxb->i2c_adapter);
233 /* all devices are present, probe was successful */
235 /* we store the pointer in our private data field */
241 /* some init data for the saa7740, the so-called 'sound arena module'.
242 there are no specs available, so we simply use some init values */
246 } mxb_saa7740_init[] = {
247 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
248 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
249 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
250 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
251 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
252 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
253 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
254 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
255 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
256 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
257 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
258 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
259 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
260 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
261 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
262 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
263 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
264 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
265 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
266 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
267 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
268 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
269 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
270 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
271 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
272 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
273 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
274 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
275 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
276 { 3, { 0x48, 0x00, 0x01 } },
277 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
278 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
279 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
280 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
281 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
282 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
283 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
284 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
285 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
286 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
287 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
288 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
289 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
290 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
291 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
292 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
293 { 3, { 0x80, 0xb3, 0x0a } },
297 static const unsigned char mxb_saa7111_init[] = {
298 0x00, 0x00, /* 00 - ID byte */
299 0x01, 0x00, /* 01 - reserved */
302 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
303 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
304 0x04, 0x00, /* 04 - GAI1=256 */
305 0x05, 0x00, /* 05 - GAI2=256 */
308 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
309 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
310 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
311 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
312 0x0a, 0x80, /* 0a - BRIG=128 */
313 0x0b, 0x47, /* 0b - CONT=1.109 */
314 0x0c, 0x40, /* 0c - SATN=1.0 */
315 0x0d, 0x00, /* 0d - HUE=0 */
316 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
317 0x0f, 0x00, /* 0f - reserved */
318 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
319 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
320 0x12, 0x80, /* 12 - xx output control 2 */
321 0x13, 0x30, /* 13 - xx output control 3 */
322 0x14, 0x00, /* 14 - reserved */
323 0x15, 0x15, /* 15 - VBI */
324 0x16, 0x04, /* 16 - VBI */
325 0x17, 0x00, /* 17 - VBI */
328 /* bring hardware to a sane state. this has to be done, just in case someone
329 wants to capture from this device before it has been properly initialized.
330 the capture engine would badly fail, because no valid signal arrives on the
331 saa7146, thus leading to timeouts and stuff. */
332 static int mxb_init_done(struct saa7146_dev* dev)
334 struct mxb* mxb = (struct mxb*)dev->ext_priv;
335 struct video_decoder_init init;
337 struct tuner_setup tun_setup;
338 v4l2_std_id std = V4L2_STD_PAL_BG;
341 struct tea6415c_multiplex vm;
343 /* select video mode in saa7111a */
345 /* fixme: currently pointless: gets overwritten by configuration below */
346 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
348 /* write configuration to saa7111a */
349 init.data = mxb_saa7111_init;
350 init.len = sizeof(mxb_saa7111_init);
351 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
353 /* select tuner-output on saa7111a */
355 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
357 /* enable vbi bypass */
359 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
361 /* select a tuner type */
362 tun_setup.mode_mask = T_ANALOG_TV;
363 tun_setup.addr = ADDR_UNSET;
364 tun_setup.type = TUNER_PHILIPS_PAL;
365 mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
366 /* tune in some frequency on tuner */
367 mxb->cur_freq.tuner = 0;
368 mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
369 mxb->cur_freq.frequency = freq;
370 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
373 /* set a default video standard */
374 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
376 /* mute audio on tea6420s */
377 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
378 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
379 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
380 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
382 /* switch to tuner-channel on tea6415c*/
385 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
387 /* select tuner-output on multicable on tea6415c*/
390 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
392 /* the rest for mxb */
396 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
397 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
399 /* check if the saa7740 (aka 'sound arena module') is present
400 on the mxb. if so, we must initialize it. due to lack of
401 informations about the saa7740, the values were reverse
405 msg.len = mxb_saa7740_init[0].length;
406 msg.buf = &mxb_saa7740_init[0].data[0];
408 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
409 /* the sound arena module is a pos, that's probably the reason
410 philips refuses to hand out a datasheet for the saa7740...
411 it seems to screw up the i2c bus, so we disable fast irq
412 based i2c transactions here and rely on the slow and safe
413 polling method ... */
414 extension.flags &= ~SAA7146_USE_I2C_IRQ;
416 if( -1 == mxb_saa7740_init[i].length ) {
420 msg.len = mxb_saa7740_init[i].length;
421 msg.buf = &mxb_saa7740_init[i].data[0];
422 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
423 DEB_D(("failed to initialize 'sound arena module'.\n"));
427 INFO(("'sound arena module' detected.\n"));
430 /* the rest for saa7146: you should definitely set some basic values
431 for the input-port handling of the saa7146. */
433 /* ext->saa has been filled by the core driver */
435 /* some stuff is done via variables */
436 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
438 /* some stuff is done via direct write to the registers */
440 /* this is ugly, but because of the fact that this is completely
441 hardware dependend, it should be done directly... */
442 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
443 saa7146_write(dev, DD1_INIT, 0x02000200);
444 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
449 /* interrupt-handler. this gets called when irq_mask is != 0.
450 it must clear the interrupt-bits in irq_mask it has handled */
452 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
454 struct mxb* mxb = (struct mxb*)dev->ext_priv;
458 static struct saa7146_ext_vv vv_data;
460 /* this function only gets called when the probing was successful */
461 static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
463 struct mxb* mxb = (struct mxb*)dev->ext_priv;
465 DEB_EE(("dev:%p\n",dev));
467 /* checking for i2c-devices can be omitted here, because we
468 already did this in "mxb_vl42_probe" */
470 saa7146_vv_init(dev,&vv_data);
471 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
472 ERR(("cannot register capture v4l2 device. skipping.\n"));
476 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
477 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
478 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
479 ERR(("cannot register vbi v4l2 device. skipping.\n"));
483 i2c_use_client(mxb->tea6420_1);
484 i2c_use_client(mxb->tea6420_2);
485 i2c_use_client(mxb->tea6415c);
486 i2c_use_client(mxb->tda9840);
487 i2c_use_client(mxb->saa7111a);
488 i2c_use_client(mxb->tuner);
490 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
497 static int mxb_detach(struct saa7146_dev* dev)
499 struct mxb* mxb = (struct mxb*)dev->ext_priv;
501 DEB_EE(("dev:%p\n",dev));
503 i2c_release_client(mxb->tea6420_1);
504 i2c_release_client(mxb->tea6420_2);
505 i2c_release_client(mxb->tea6415c);
506 i2c_release_client(mxb->tda9840);
507 i2c_release_client(mxb->saa7111a);
508 i2c_release_client(mxb->tuner);
510 saa7146_unregister_device(&mxb->video_dev,dev);
511 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
512 saa7146_unregister_device(&mxb->vbi_dev,dev);
514 saa7146_vv_release(dev);
518 i2c_del_adapter(&mxb->i2c_adapter);
524 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
526 struct saa7146_dev *dev = fh->dev;
527 struct mxb* mxb = (struct mxb*)dev->ext_priv;
528 struct saa7146_vv *vv = dev->vv_data;
531 case VIDIOC_ENUMINPUT:
533 struct v4l2_input *i = arg;
535 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
536 if( i->index < 0 || i->index >= MXB_INPUTS) {
539 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
543 /* the saa7146 provides some controls (brightness, contrast, saturation)
544 which gets registered *after* this function. because of this we have
545 to return with a value != 0 even if the function succeded.. */
546 case VIDIOC_QUERYCTRL:
548 struct v4l2_queryctrl *qc = arg;
551 for (i = MAXCONTROLS - 1; i >= 0; i--) {
552 if (mxb_controls[i].id == qc->id) {
553 *qc = mxb_controls[i];
554 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
562 struct v4l2_control *vc = arg;
565 for (i = MAXCONTROLS - 1; i >= 0; i--) {
566 if (mxb_controls[i].id == vc->id) {
576 case V4L2_CID_AUDIO_MUTE: {
577 vc->value = mxb->cur_mute;
578 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
583 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
589 struct v4l2_control *vc = arg;
592 for (i = MAXCONTROLS - 1; i >= 0; i--) {
593 if (mxb_controls[i].id == vc->id) {
603 case V4L2_CID_AUDIO_MUTE: {
604 mxb->cur_mute = vc->value;
605 if( 0 == vc->value ) {
606 /* switch the audio-source */
607 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
608 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
610 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
611 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
613 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
621 int *input = (int *)arg;
622 *input = mxb->cur_input;
624 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
629 int input = *(int *)arg;
630 struct tea6415c_multiplex vm;
633 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
635 if (input < 0 || input >= MXB_INPUTS) {
639 /* fixme: locke das setzen des inputs mit hilfe des mutexes
640 mutex_lock(&dev->lock);
642 mutex_unlock(&dev->lock);
645 /* fixme: check if streaming capture
646 if ( 0 != dev->streaming ) {
647 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
652 mxb->cur_input = input;
654 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
656 /* prepare switching of tea6415c and saa7111a;
657 have a look at the 'background'-file for further informations */
666 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
667 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
670 /* connect tuner-output always to multicable */
677 /* nothing to be done here. aux3_yc is
678 directly connected to the saa711a */
684 /* nothing to be done here. aux3 is
685 directly connected to the saa711a */
698 /* switch video in tea6415c only if necessary */
703 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
704 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
715 /* switch video in saa7111a */
716 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
717 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
720 /* switch the audio-source only if necessary */
721 if( 0 == mxb->cur_mute ) {
722 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
723 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
730 struct v4l2_tuner *t = arg;
733 if( 0 != t->index ) {
734 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
738 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
740 memset(t,0,sizeof(*t));
741 strcpy(t->name, "Television");
743 t->type = V4L2_TUNER_ANALOG_TV;
744 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
745 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
746 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
747 /* FIXME: add the real signal strength here */
751 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
752 t->audmode = mxb->cur_mode;
755 t->rxsubchans = V4L2_TUNER_SUB_MONO;
758 case TDA9840_MONO_DETECT: {
759 t->rxsubchans = V4L2_TUNER_SUB_MONO;
760 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
763 case TDA9840_DUAL_DETECT: {
764 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
765 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
768 case TDA9840_STEREO_DETECT: {
769 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
770 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
773 default: { /* TDA9840_INCORRECT_DETECT */
774 t->rxsubchans = V4L2_TUNER_MODE_MONO;
775 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
785 struct v4l2_tuner *t = arg;
789 if( 0 != t->index ) {
790 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
795 case V4L2_TUNER_MODE_STEREO: {
796 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
797 byte = TDA9840_SET_STEREO;
798 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
801 case V4L2_TUNER_MODE_LANG1_LANG2: {
802 mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2;
803 byte = TDA9840_SET_BOTH;
804 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"));
807 case V4L2_TUNER_MODE_LANG1: {
808 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
809 byte = TDA9840_SET_LANG1;
810 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
813 case V4L2_TUNER_MODE_LANG2: {
814 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
815 byte = TDA9840_SET_LANG2;
816 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
819 default: { /* case V4L2_TUNER_MODE_MONO: {*/
820 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
821 byte = TDA9840_SET_MONO;
822 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
827 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
828 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
833 case VIDIOC_G_FREQUENCY:
835 struct v4l2_frequency *f = arg;
837 if(0 != mxb->cur_input) {
838 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
844 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
847 case VIDIOC_S_FREQUENCY:
849 struct v4l2_frequency *f = arg;
854 if (V4L2_TUNER_ANALOG_TV != f->type)
857 if(0 != mxb->cur_input) {
858 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
863 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
865 /* tune in desired frequency */
866 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
868 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
869 spin_lock(&dev->slock);
870 vv->vbi_fieldcount = 0;
871 spin_unlock(&dev->slock);
879 if( i < 0 || i >= MXB_AUDIOS ) {
880 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
884 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
886 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
887 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
891 case MXB_S_AUDIO_LINE:
895 if( i < 0 || i >= MXB_AUDIOS ) {
896 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
900 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
901 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
902 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
908 struct v4l2_audio *a = arg;
910 if( a->index < 0 || a->index > MXB_INPUTS ) {
911 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
915 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
916 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
922 struct v4l2_audio *a = arg;
923 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
928 DEB2(printk("does not handle this ioctl.\n"));
935 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
937 struct mxb* mxb = (struct mxb*)dev->ext_priv;
941 if(V4L2_STD_PAL_I == std->id ) {
942 v4l2_std_id std = V4L2_STD_PAL_I;
943 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
944 /* set the 7146 gpio register -- I don't know what this does exactly */
945 saa7146_write(dev, GPIO_CTRL, 0x00404050);
946 /* unset the 7111 gpio register -- I don't know what this does exactly */
947 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
948 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
950 v4l2_std_id std = V4L2_STD_PAL_BG;
951 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
952 /* set the 7146 gpio register -- I don't know what this does exactly */
953 saa7146_write(dev, GPIO_CTRL, 0x00404050);
954 /* set the 7111 gpio register -- I don't know what this does exactly */
955 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
956 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
961 static struct saa7146_standard standard[] = {
963 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
964 .v_offset = 0x17, .v_field = 288,
965 .h_offset = 0x14, .h_pixels = 680,
966 .v_max_out = 576, .h_max_out = 768,
968 .name = "PAL-I", .id = V4L2_STD_PAL_I,
969 .v_offset = 0x17, .v_field = 288,
970 .h_offset = 0x14, .h_pixels = 680,
971 .v_max_out = 576, .h_max_out = 768,
973 .name = "NTSC", .id = V4L2_STD_NTSC,
974 .v_offset = 0x16, .v_field = 240,
975 .h_offset = 0x06, .h_pixels = 708,
976 .v_max_out = 480, .h_max_out = 640,
978 .name = "SECAM", .id = V4L2_STD_SECAM,
979 .v_offset = 0x14, .v_field = 288,
980 .h_offset = 0x14, .h_pixels = 720,
981 .v_max_out = 576, .h_max_out = 768,
985 static struct saa7146_pci_extension_data mxb = {
986 .ext_priv = "Multimedia eXtension Board",
990 static struct pci_device_id pci_tbl[] = {
992 .vendor = PCI_VENDOR_ID_PHILIPS,
993 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
996 .driver_data = (unsigned long)&mxb,
1002 MODULE_DEVICE_TABLE(pci, pci_tbl);
1004 static struct saa7146_ext_vv vv_data = {
1005 .inputs = MXB_INPUTS,
1006 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
1007 .stds = &standard[0],
1008 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
1009 .std_callback = &std_callback,
1010 .ioctls = &ioctls[0],
1014 static struct saa7146_extension extension = {
1015 .name = MXB_IDENTIFIER,
1016 .flags = SAA7146_USE_I2C_IRQ,
1018 .pci_tbl = &pci_tbl[0],
1019 .module = THIS_MODULE,
1022 .attach = mxb_attach,
1023 .detach = mxb_detach,
1029 static int __init mxb_init_module(void)
1031 if( 0 != saa7146_register_extension(&extension)) {
1032 DEB_S(("failed to register extension.\n"));
1039 static void __exit mxb_cleanup_module(void)
1041 saa7146_unregister_extension(&extension);
1044 module_init(mxb_init_module);
1045 module_exit(mxb_cleanup_module);
1047 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1048 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1049 MODULE_LICENSE("GPL");