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_probe(struct saa7146_dev* dev)
154 struct mxb* mxb = NULL;
155 struct i2c_client *client;
156 struct list_head *item;
159 if ((result = request_module("saa7111")) < 0) {
160 printk("mxb: saa7111 i2c module not available.\n");
163 if ((result = request_module("tuner")) < 0) {
164 printk("mxb: tuner i2c module not available.\n");
167 if ((result = request_module("tea6420")) < 0) {
168 printk("mxb: tea6420 i2c module not available.\n");
171 if ((result = request_module("tea6415c")) < 0) {
172 printk("mxb: tea6415c i2c module not available.\n");
175 if ((result = request_module("tda9840")) < 0) {
176 printk("mxb: tda9840 i2c module not available.\n");
180 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
182 DEB_D(("not enough kernel memory.\n"));
186 mxb->i2c_adapter = (struct i2c_adapter) {
187 .class = I2C_CLASS_TV_ANALOG,
191 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
192 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
193 DEB_S(("cannot register i2c-device. skipping.\n"));
198 /* loop through all i2c-devices on the bus and look who is there */
199 list_for_each(item,&mxb->i2c_adapter.clients) {
200 client = list_entry(item, struct i2c_client, list);
201 if( I2C_ADDR_TEA6420_1 == client->addr )
202 mxb->tea6420_1 = client;
203 if( I2C_ADDR_TEA6420_2 == client->addr )
204 mxb->tea6420_2 = client;
205 if( I2C_TEA6415C_2 == client->addr )
206 mxb->tea6415c = client;
207 if( I2C_ADDR_TDA9840 == client->addr )
208 mxb->tda9840 = client;
209 if( I2C_SAA7111 == client->addr )
210 mxb->saa7111a = client;
211 if( 0x60 == client->addr )
215 /* check if all devices are present */
216 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
217 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
219 printk("mxb: did not find all i2c devices. aborting\n");
220 i2c_del_adapter(&mxb->i2c_adapter);
225 /* all devices are present, probe was successful */
227 /* we store the pointer in our private data field */
233 /* some init data for the saa7740, the so-called 'sound arena module'.
234 there are no specs available, so we simply use some init values */
238 } mxb_saa7740_init[] = {
239 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
240 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
241 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
242 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
243 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
244 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
245 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
246 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
247 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
248 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
249 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
250 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
251 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
252 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
253 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
254 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
255 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
256 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
257 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
258 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
259 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
260 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
261 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
262 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
263 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
264 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
265 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
266 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
267 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
268 { 3, { 0x48, 0x00, 0x01 } },
269 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
270 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
271 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
272 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
273 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
274 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
275 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
276 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
277 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
278 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
279 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
280 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
281 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
282 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
283 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
284 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
285 { 3, { 0x80, 0xb3, 0x0a } },
289 static const unsigned char mxb_saa7111_init[] = {
290 0x00, 0x00, /* 00 - ID byte */
291 0x01, 0x00, /* 01 - reserved */
294 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
295 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
296 0x04, 0x00, /* 04 - GAI1=256 */
297 0x05, 0x00, /* 05 - GAI2=256 */
300 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
301 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
302 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
303 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
304 0x0a, 0x80, /* 0a - BRIG=128 */
305 0x0b, 0x47, /* 0b - CONT=1.109 */
306 0x0c, 0x40, /* 0c - SATN=1.0 */
307 0x0d, 0x00, /* 0d - HUE=0 */
308 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
309 0x0f, 0x00, /* 0f - reserved */
310 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
311 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
312 0x12, 0x80, /* 12 - xx output control 2 */
313 0x13, 0x30, /* 13 - xx output control 3 */
314 0x14, 0x00, /* 14 - reserved */
315 0x15, 0x15, /* 15 - VBI */
316 0x16, 0x04, /* 16 - VBI */
317 0x17, 0x00, /* 17 - VBI */
320 /* bring hardware to a sane state. this has to be done, just in case someone
321 wants to capture from this device before it has been properly initialized.
322 the capture engine would badly fail, because no valid signal arrives on the
323 saa7146, thus leading to timeouts and stuff. */
324 static int mxb_init_done(struct saa7146_dev* dev)
326 struct mxb* mxb = (struct mxb*)dev->ext_priv;
327 struct video_decoder_init init;
329 struct tuner_setup tun_setup;
330 v4l2_std_id std = V4L2_STD_PAL_BG;
333 struct tea6415c_multiplex vm;
335 /* select video mode in saa7111a */
337 /* fixme: currently pointless: gets overwritten by configuration below */
338 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
340 /* write configuration to saa7111a */
341 init.data = mxb_saa7111_init;
342 init.len = sizeof(mxb_saa7111_init);
343 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
345 /* select tuner-output on saa7111a */
347 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
349 /* enable vbi bypass */
351 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
353 /* select a tuner type */
354 tun_setup.mode_mask = T_ANALOG_TV;
355 tun_setup.addr = ADDR_UNSET;
356 tun_setup.type = TUNER_PHILIPS_PAL;
357 mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
358 /* tune in some frequency on tuner */
359 mxb->cur_freq.tuner = 0;
360 mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
361 mxb->cur_freq.frequency = freq;
362 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
365 /* set a default video standard */
366 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
368 /* mute audio on tea6420s */
369 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
370 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
371 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
372 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
374 /* switch to tuner-channel on tea6415c*/
377 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
379 /* select tuner-output on multicable on tea6415c*/
382 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
384 /* the rest for mxb */
388 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
389 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
391 /* check if the saa7740 (aka 'sound arena module') is present
392 on the mxb. if so, we must initialize it. due to lack of
393 informations about the saa7740, the values were reverse
397 msg.len = mxb_saa7740_init[0].length;
398 msg.buf = &mxb_saa7740_init[0].data[0];
400 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
401 /* the sound arena module is a pos, that's probably the reason
402 philips refuses to hand out a datasheet for the saa7740...
403 it seems to screw up the i2c bus, so we disable fast irq
404 based i2c transactions here and rely on the slow and safe
405 polling method ... */
406 extension.flags &= ~SAA7146_USE_I2C_IRQ;
408 if( -1 == mxb_saa7740_init[i].length ) {
412 msg.len = mxb_saa7740_init[i].length;
413 msg.buf = &mxb_saa7740_init[i].data[0];
414 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
415 DEB_D(("failed to initialize 'sound arena module'.\n"));
419 INFO(("'sound arena module' detected.\n"));
422 /* the rest for saa7146: you should definitely set some basic values
423 for the input-port handling of the saa7146. */
425 /* ext->saa has been filled by the core driver */
427 /* some stuff is done via variables */
428 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
430 /* some stuff is done via direct write to the registers */
432 /* this is ugly, but because of the fact that this is completely
433 hardware dependend, it should be done directly... */
434 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
435 saa7146_write(dev, DD1_INIT, 0x02000200);
436 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
441 /* interrupt-handler. this gets called when irq_mask is != 0.
442 it must clear the interrupt-bits in irq_mask it has handled */
444 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
446 struct mxb* mxb = (struct mxb*)dev->ext_priv;
450 static struct saa7146_ext_vv vv_data;
452 /* this function only gets called when the probing was successful */
453 static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
455 struct mxb* mxb = (struct mxb*)dev->ext_priv;
457 DEB_EE(("dev:%p\n",dev));
459 /* checking for i2c-devices can be omitted here, because we
460 already did this in "mxb_vl42_probe" */
462 saa7146_vv_init(dev,&vv_data);
463 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
464 ERR(("cannot register capture v4l2 device. skipping.\n"));
468 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
469 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
470 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
471 ERR(("cannot register vbi v4l2 device. skipping.\n"));
475 i2c_use_client(mxb->tea6420_1);
476 i2c_use_client(mxb->tea6420_2);
477 i2c_use_client(mxb->tea6415c);
478 i2c_use_client(mxb->tda9840);
479 i2c_use_client(mxb->saa7111a);
480 i2c_use_client(mxb->tuner);
482 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
489 static int mxb_detach(struct saa7146_dev* dev)
491 struct mxb* mxb = (struct mxb*)dev->ext_priv;
493 DEB_EE(("dev:%p\n",dev));
495 i2c_release_client(mxb->tea6420_1);
496 i2c_release_client(mxb->tea6420_2);
497 i2c_release_client(mxb->tea6415c);
498 i2c_release_client(mxb->tda9840);
499 i2c_release_client(mxb->saa7111a);
500 i2c_release_client(mxb->tuner);
502 saa7146_unregister_device(&mxb->video_dev,dev);
503 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
504 saa7146_unregister_device(&mxb->vbi_dev,dev);
506 saa7146_vv_release(dev);
510 i2c_del_adapter(&mxb->i2c_adapter);
516 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
518 struct saa7146_dev *dev = fh->dev;
519 struct mxb* mxb = (struct mxb*)dev->ext_priv;
520 struct saa7146_vv *vv = dev->vv_data;
523 case VIDIOC_ENUMINPUT:
525 struct v4l2_input *i = arg;
527 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
528 if( i->index < 0 || i->index >= MXB_INPUTS) {
531 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
535 /* the saa7146 provides some controls (brightness, contrast, saturation)
536 which gets registered *after* this function. because of this we have
537 to return with a value != 0 even if the function succeded.. */
538 case VIDIOC_QUERYCTRL:
540 struct v4l2_queryctrl *qc = arg;
543 for (i = MAXCONTROLS - 1; i >= 0; i--) {
544 if (mxb_controls[i].id == qc->id) {
545 *qc = mxb_controls[i];
546 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
554 struct v4l2_control *vc = arg;
557 for (i = MAXCONTROLS - 1; i >= 0; i--) {
558 if (mxb_controls[i].id == vc->id) {
568 case V4L2_CID_AUDIO_MUTE: {
569 vc->value = mxb->cur_mute;
570 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
575 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
581 struct v4l2_control *vc = arg;
584 for (i = MAXCONTROLS - 1; i >= 0; i--) {
585 if (mxb_controls[i].id == vc->id) {
595 case V4L2_CID_AUDIO_MUTE: {
596 mxb->cur_mute = vc->value;
597 if( 0 == vc->value ) {
598 /* switch the audio-source */
599 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
600 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
602 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
603 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
605 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
613 int *input = (int *)arg;
614 *input = mxb->cur_input;
616 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
621 int input = *(int *)arg;
622 struct tea6415c_multiplex vm;
625 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
627 if (input < 0 || input >= MXB_INPUTS) {
631 /* fixme: locke das setzen des inputs mit hilfe des mutexes
632 mutex_lock(&dev->lock);
634 mutex_unlock(&dev->lock);
637 /* fixme: check if streaming capture
638 if ( 0 != dev->streaming ) {
639 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
644 mxb->cur_input = input;
646 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
648 /* prepare switching of tea6415c and saa7111a;
649 have a look at the 'background'-file for further informations */
658 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
659 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
662 /* connect tuner-output always to multicable */
669 /* nothing to be done here. aux3_yc is
670 directly connected to the saa711a */
676 /* nothing to be done here. aux3 is
677 directly connected to the saa711a */
690 /* switch video in tea6415c only if necessary */
695 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
696 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
707 /* switch video in saa7111a */
708 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
709 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
712 /* switch the audio-source only if necessary */
713 if( 0 == mxb->cur_mute ) {
714 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
715 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
722 struct v4l2_tuner *t = arg;
725 if( 0 != t->index ) {
726 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
730 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
732 memset(t,0,sizeof(*t));
733 strcpy(t->name, "Television");
735 t->type = V4L2_TUNER_ANALOG_TV;
736 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
737 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
738 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
739 /* FIXME: add the real signal strength here */
743 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
744 t->audmode = mxb->cur_mode;
747 t->rxsubchans = V4L2_TUNER_SUB_MONO;
750 case TDA9840_MONO_DETECT: {
751 t->rxsubchans = V4L2_TUNER_SUB_MONO;
752 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
755 case TDA9840_DUAL_DETECT: {
756 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
757 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
760 case TDA9840_STEREO_DETECT: {
761 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
762 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
765 default: { /* TDA9840_INCORRECT_DETECT */
766 t->rxsubchans = V4L2_TUNER_MODE_MONO;
767 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
777 struct v4l2_tuner *t = arg;
781 if( 0 != t->index ) {
782 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
787 case V4L2_TUNER_MODE_STEREO: {
788 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
789 byte = TDA9840_SET_STEREO;
790 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
793 case V4L2_TUNER_MODE_LANG1_LANG2: {
794 mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2;
795 byte = TDA9840_SET_BOTH;
796 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"));
799 case V4L2_TUNER_MODE_LANG1: {
800 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
801 byte = TDA9840_SET_LANG1;
802 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
805 case V4L2_TUNER_MODE_LANG2: {
806 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
807 byte = TDA9840_SET_LANG2;
808 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
811 default: { /* case V4L2_TUNER_MODE_MONO: {*/
812 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
813 byte = TDA9840_SET_MONO;
814 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
819 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
820 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
825 case VIDIOC_G_FREQUENCY:
827 struct v4l2_frequency *f = arg;
829 if(0 != mxb->cur_input) {
830 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
836 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
839 case VIDIOC_S_FREQUENCY:
841 struct v4l2_frequency *f = arg;
846 if (V4L2_TUNER_ANALOG_TV != f->type)
849 if(0 != mxb->cur_input) {
850 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
855 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
857 /* tune in desired frequency */
858 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
860 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
861 spin_lock(&dev->slock);
862 vv->vbi_fieldcount = 0;
863 spin_unlock(&dev->slock);
871 if( i < 0 || i >= MXB_AUDIOS ) {
872 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
876 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
878 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
879 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
883 case MXB_S_AUDIO_LINE:
887 if( i < 0 || i >= MXB_AUDIOS ) {
888 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
892 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
893 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
894 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
900 struct v4l2_audio *a = arg;
902 if( a->index < 0 || a->index > MXB_INPUTS ) {
903 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
907 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
908 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
914 struct v4l2_audio *a = arg;
915 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
920 DEB2(printk("does not handle this ioctl.\n"));
927 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
929 struct mxb* mxb = (struct mxb*)dev->ext_priv;
933 if(V4L2_STD_PAL_I == std->id ) {
934 v4l2_std_id std = V4L2_STD_PAL_I;
935 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
936 /* set the 7146 gpio register -- I don't know what this does exactly */
937 saa7146_write(dev, GPIO_CTRL, 0x00404050);
938 /* unset the 7111 gpio register -- I don't know what this does exactly */
939 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
940 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
942 v4l2_std_id std = V4L2_STD_PAL_BG;
943 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
944 /* set the 7146 gpio register -- I don't know what this does exactly */
945 saa7146_write(dev, GPIO_CTRL, 0x00404050);
946 /* set the 7111 gpio register -- I don't know what this does exactly */
947 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
948 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
953 static struct saa7146_standard standard[] = {
955 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
956 .v_offset = 0x17, .v_field = 288,
957 .h_offset = 0x14, .h_pixels = 680,
958 .v_max_out = 576, .h_max_out = 768,
960 .name = "PAL-I", .id = V4L2_STD_PAL_I,
961 .v_offset = 0x17, .v_field = 288,
962 .h_offset = 0x14, .h_pixels = 680,
963 .v_max_out = 576, .h_max_out = 768,
965 .name = "NTSC", .id = V4L2_STD_NTSC,
966 .v_offset = 0x16, .v_field = 240,
967 .h_offset = 0x06, .h_pixels = 708,
968 .v_max_out = 480, .h_max_out = 640,
970 .name = "SECAM", .id = V4L2_STD_SECAM,
971 .v_offset = 0x14, .v_field = 288,
972 .h_offset = 0x14, .h_pixels = 720,
973 .v_max_out = 576, .h_max_out = 768,
977 static struct saa7146_pci_extension_data mxb = {
978 .ext_priv = "Multimedia eXtension Board",
982 static struct pci_device_id pci_tbl[] = {
984 .vendor = PCI_VENDOR_ID_PHILIPS,
985 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
988 .driver_data = (unsigned long)&mxb,
994 MODULE_DEVICE_TABLE(pci, pci_tbl);
996 static struct saa7146_ext_vv vv_data = {
997 .inputs = MXB_INPUTS,
998 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
999 .stds = &standard[0],
1000 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
1001 .std_callback = &std_callback,
1002 .ioctls = &ioctls[0],
1006 static struct saa7146_extension extension = {
1007 .name = MXB_IDENTIFIER,
1008 .flags = SAA7146_USE_I2C_IRQ,
1010 .pci_tbl = &pci_tbl[0],
1011 .module = THIS_MODULE,
1014 .attach = mxb_attach,
1015 .detach = mxb_detach,
1021 static int __init mxb_init_module(void)
1023 if( 0 != saa7146_register_extension(&extension)) {
1024 DEB_S(("failed to register extension.\n"));
1031 static void __exit mxb_cleanup_module(void)
1033 saa7146_unregister_extension(&extension);
1036 module_init(mxb_init_module);
1037 module_exit(mxb_cleanup_module);
1039 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1040 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1041 MODULE_LICENSE("GPL");