2 mxb - v4l2 driver for the Multimedia eXtension Board
4 Copyright (C) 1998-2003 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 = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL);
182 DEB_D(("not enough kernel memory.\n"));
185 memset(mxb, 0x0, sizeof(struct mxb));
187 mxb->i2c_adapter = (struct i2c_adapter) {
188 .class = I2C_CLASS_TV_ANALOG,
192 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
193 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
194 DEB_S(("cannot register i2c-device. skipping.\n"));
199 /* loop through all i2c-devices on the bus and look who is there */
200 list_for_each(item,&mxb->i2c_adapter.clients) {
201 client = list_entry(item, struct i2c_client, list);
202 if( I2C_TEA6420_1 == client->addr )
203 mxb->tea6420_1 = client;
204 if( I2C_TEA6420_2 == client->addr )
205 mxb->tea6420_2 = client;
206 if( I2C_TEA6415C_2 == client->addr )
207 mxb->tea6415c = client;
208 if( I2C_TDA9840 == client->addr )
209 mxb->tda9840 = client;
210 if( I2C_SAA7111 == client->addr )
211 mxb->saa7111a = client;
212 if( 0x60 == client->addr )
216 /* check if all devices are present */
217 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
218 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
220 printk("mxb: did not find all i2c devices. aborting\n");
221 i2c_del_adapter(&mxb->i2c_adapter);
226 /* all devices are present, probe was successful */
228 /* we store the pointer in our private data field */
234 /* some init data for the saa7740, the so-called 'sound arena module'.
235 there are no specs available, so we simply use some init values */
239 } mxb_saa7740_init[] = {
240 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
241 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
242 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
243 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
244 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
245 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
246 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
247 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
248 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
249 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
250 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
251 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
252 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
253 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
254 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
255 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
256 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
257 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
258 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
259 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
260 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
261 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
262 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
263 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
264 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
265 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
266 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
267 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
268 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
269 { 3, { 0x48, 0x00, 0x01 } },
270 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
271 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
272 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
273 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
274 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
275 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
276 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
277 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
278 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
279 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
280 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
281 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
282 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
283 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
284 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
285 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
286 { 3, { 0x80, 0xb3, 0x0a } },
290 static const unsigned char mxb_saa7111_init[] = {
291 0x00, 0x00, /* 00 - ID byte */
292 0x01, 0x00, /* 01 - reserved */
295 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
296 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
297 0x04, 0x00, /* 04 - GAI1=256 */
298 0x05, 0x00, /* 05 - GAI2=256 */
301 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
302 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
303 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
304 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
305 0x0a, 0x80, /* 0a - BRIG=128 */
306 0x0b, 0x47, /* 0b - CONT=1.109 */
307 0x0c, 0x40, /* 0c - SATN=1.0 */
308 0x0d, 0x00, /* 0d - HUE=0 */
309 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
310 0x0f, 0x00, /* 0f - reserved */
311 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
312 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
313 0x12, 0x80, /* 12 - xx output control 2 */
314 0x13, 0x30, /* 13 - xx output control 3 */
315 0x14, 0x00, /* 14 - reserved */
316 0x15, 0x15, /* 15 - VBI */
317 0x16, 0x04, /* 16 - VBI */
318 0x17, 0x00, /* 17 - VBI */
321 /* bring hardware to a sane state. this has to be done, just in case someone
322 wants to capture from this device before it has been properly initialized.
323 the capture engine would badly fail, because no valid signal arrives on the
324 saa7146, thus leading to timeouts and stuff. */
325 static int mxb_init_done(struct saa7146_dev* dev)
327 struct mxb* mxb = (struct mxb*)dev->ext_priv;
328 struct video_decoder_init init;
330 struct tuner_setup tun_setup;
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 /* mute audio on tea6420s */
366 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
367 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
368 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
369 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
371 /* switch to tuner-channel on tea6415c*/
374 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
376 /* select tuner-output on multicable on tea6415c*/
379 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
381 /* the rest for mxb */
385 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
386 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
388 /* check if the saa7740 (aka 'sound arena module') is present
389 on the mxb. if so, we must initialize it. due to lack of
390 informations about the saa7740, the values were reverse
394 msg.len = mxb_saa7740_init[0].length;
395 msg.buf = &mxb_saa7740_init[0].data[0];
397 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
398 /* the sound arena module is a pos, that's probably the reason
399 philips refuses to hand out a datasheet for the saa7740...
400 it seems to screw up the i2c bus, so we disable fast irq
401 based i2c transactions here and rely on the slow and safe
402 polling method ... */
403 extension.flags &= ~SAA7146_USE_I2C_IRQ;
405 if( -1 == mxb_saa7740_init[i].length ) {
409 msg.len = mxb_saa7740_init[i].length;
410 msg.buf = &mxb_saa7740_init[i].data[0];
411 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
412 DEB_D(("failed to initialize 'sound arena module'.\n"));
416 INFO(("'sound arena module' detected.\n"));
419 /* the rest for saa7146: you should definitely set some basic values
420 for the input-port handling of the saa7146. */
422 /* ext->saa has been filled by the core driver */
424 /* some stuff is done via variables */
425 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
427 /* some stuff is done via direct write to the registers */
429 /* this is ugly, but because of the fact that this is completely
430 hardware dependend, it should be done directly... */
431 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
432 saa7146_write(dev, DD1_INIT, 0x02000200);
433 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
438 /* interrupt-handler. this gets called when irq_mask is != 0.
439 it must clear the interrupt-bits in irq_mask it has handled */
441 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
443 struct mxb* mxb = (struct mxb*)dev->ext_priv;
447 static struct saa7146_ext_vv vv_data;
449 /* this function only gets called when the probing was successful */
450 static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
452 struct mxb* mxb = (struct mxb*)dev->ext_priv;
454 DEB_EE(("dev:%p\n",dev));
456 /* checking for i2c-devices can be omitted here, because we
457 already did this in "mxb_vl42_probe" */
459 saa7146_vv_init(dev,&vv_data);
460 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
461 ERR(("cannot register capture v4l2 device. skipping.\n"));
465 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
466 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
467 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
468 ERR(("cannot register vbi v4l2 device. skipping.\n"));
472 i2c_use_client(mxb->tea6420_1);
473 i2c_use_client(mxb->tea6420_2);
474 i2c_use_client(mxb->tea6415c);
475 i2c_use_client(mxb->tda9840);
476 i2c_use_client(mxb->saa7111a);
477 i2c_use_client(mxb->tuner);
479 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
486 static int mxb_detach(struct saa7146_dev* dev)
488 struct mxb* mxb = (struct mxb*)dev->ext_priv;
490 DEB_EE(("dev:%p\n",dev));
492 i2c_release_client(mxb->tea6420_1);
493 i2c_release_client(mxb->tea6420_2);
494 i2c_release_client(mxb->tea6415c);
495 i2c_release_client(mxb->tda9840);
496 i2c_release_client(mxb->saa7111a);
497 i2c_release_client(mxb->tuner);
499 saa7146_unregister_device(&mxb->video_dev,dev);
500 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
501 saa7146_unregister_device(&mxb->vbi_dev,dev);
503 saa7146_vv_release(dev);
507 i2c_del_adapter(&mxb->i2c_adapter);
513 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
515 struct saa7146_dev *dev = fh->dev;
516 struct mxb* mxb = (struct mxb*)dev->ext_priv;
517 struct saa7146_vv *vv = dev->vv_data;
520 case VIDIOC_ENUMINPUT:
522 struct v4l2_input *i = arg;
524 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
525 if( i->index < 0 || i->index >= MXB_INPUTS) {
528 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
532 /* the saa7146 provides some controls (brightness, contrast, saturation)
533 which gets registered *after* this function. because of this we have
534 to return with a value != 0 even if the function succeded.. */
535 case VIDIOC_QUERYCTRL:
537 struct v4l2_queryctrl *qc = arg;
540 for (i = MAXCONTROLS - 1; i >= 0; i--) {
541 if (mxb_controls[i].id == qc->id) {
542 *qc = mxb_controls[i];
543 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
551 struct v4l2_control *vc = arg;
554 for (i = MAXCONTROLS - 1; i >= 0; i--) {
555 if (mxb_controls[i].id == vc->id) {
565 case V4L2_CID_AUDIO_MUTE: {
566 vc->value = mxb->cur_mute;
567 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
572 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
578 struct v4l2_control *vc = arg;
581 for (i = MAXCONTROLS - 1; i >= 0; i--) {
582 if (mxb_controls[i].id == vc->id) {
592 case V4L2_CID_AUDIO_MUTE: {
593 mxb->cur_mute = vc->value;
594 if( 0 == vc->value ) {
595 /* switch the audio-source */
596 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
597 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
599 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
600 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
602 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
610 int *input = (int *)arg;
611 *input = mxb->cur_input;
613 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
618 int input = *(int *)arg;
619 struct tea6415c_multiplex vm;
622 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
624 if (input < 0 || input >= MXB_INPUTS) {
628 /* fixme: locke das setzen des inputs mit hilfe des mutexes
634 /* fixme: check if streaming capture
635 if ( 0 != dev->streaming ) {
636 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
641 mxb->cur_input = input;
643 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
645 /* prepare switching of tea6415c and saa7111a;
646 have a look at the 'background'-file for further informations */
655 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
656 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
659 /* connect tuner-output always to multicable */
666 /* nothing to be done here. aux3_yc is
667 directly connected to the saa711a */
673 /* nothing to be done here. aux3 is
674 directly connected to the saa711a */
687 /* switch video in tea6415c only if necessary */
692 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
693 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
704 /* switch video in saa7111a */
705 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
706 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
709 /* switch the audio-source only if necessary */
710 if( 0 == mxb->cur_mute ) {
711 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
712 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
719 struct v4l2_tuner *t = arg;
722 if( 0 != t->index ) {
723 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
727 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
729 memset(t,0,sizeof(*t));
730 strcpy(t->name, "Television");
732 t->type = V4L2_TUNER_ANALOG_TV;
733 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
734 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
735 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
736 /* FIXME: add the real signal strength here */
740 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
741 t->audmode = mxb->cur_mode;
744 t->rxsubchans = V4L2_TUNER_SUB_MONO;
747 case TDA9840_MONO_DETECT: {
748 t->rxsubchans = V4L2_TUNER_SUB_MONO;
749 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
752 case TDA9840_DUAL_DETECT: {
753 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
754 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
757 case TDA9840_STEREO_DETECT: {
758 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
759 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
762 default: { /* TDA9840_INCORRECT_DETECT */
763 t->rxsubchans = V4L2_TUNER_MODE_MONO;
764 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
774 struct v4l2_tuner *t = arg;
778 if( 0 != t->index ) {
779 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
784 case V4L2_TUNER_MODE_STEREO: {
785 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
786 byte = TDA9840_SET_STEREO;
787 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
790 case V4L2_TUNER_MODE_LANG1: {
791 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
792 byte = TDA9840_SET_LANG1;
793 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
796 case V4L2_TUNER_MODE_LANG2: {
797 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
798 byte = TDA9840_SET_LANG2;
799 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
802 default: { /* case V4L2_TUNER_MODE_MONO: {*/
803 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
804 byte = TDA9840_SET_MONO;
805 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
810 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
811 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
816 case VIDIOC_G_FREQUENCY:
818 struct v4l2_frequency *f = arg;
820 if(0 != mxb->cur_input) {
821 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
827 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
830 case VIDIOC_S_FREQUENCY:
832 struct v4l2_frequency *f = arg;
837 if (V4L2_TUNER_ANALOG_TV != f->type)
840 if(0 != mxb->cur_input) {
841 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
846 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
848 /* tune in desired frequency */
849 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
851 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
852 spin_lock(&dev->slock);
853 vv->vbi_fieldcount = 0;
854 spin_unlock(&dev->slock);
862 if( i < 0 || i >= MXB_AUDIOS ) {
863 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
867 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
869 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
870 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
874 case MXB_S_AUDIO_LINE:
878 if( i < 0 || i >= MXB_AUDIOS ) {
879 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
883 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
884 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
885 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
891 struct v4l2_audio *a = arg;
893 if( a->index < 0 || a->index > MXB_INPUTS ) {
894 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
898 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
899 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
905 struct v4l2_audio *a = arg;
906 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
911 DEB2(printk("does not handle this ioctl.\n"));
918 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
920 struct mxb* mxb = (struct mxb*)dev->ext_priv;
924 if(V4L2_STD_PAL_I == std->id ) {
925 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
926 /* set the 7146 gpio register -- I don't know what this does exactly */
927 saa7146_write(dev, GPIO_CTRL, 0x00404050);
928 /* unset the 7111 gpio register -- I don't know what this does exactly */
929 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
931 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
932 /* set the 7146 gpio register -- I don't know what this does exactly */
933 saa7146_write(dev, GPIO_CTRL, 0x00404050);
934 /* set the 7111 gpio register -- I don't know what this does exactly */
935 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
940 static struct saa7146_standard standard[] = {
942 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
943 .v_offset = 0x17, .v_field = 288,
944 .h_offset = 0x14, .h_pixels = 680,
945 .v_max_out = 576, .h_max_out = 768,
947 .name = "PAL-I", .id = V4L2_STD_PAL_I,
948 .v_offset = 0x17, .v_field = 288,
949 .h_offset = 0x14, .h_pixels = 680,
950 .v_max_out = 576, .h_max_out = 768,
952 .name = "NTSC", .id = V4L2_STD_NTSC,
953 .v_offset = 0x16, .v_field = 240,
954 .h_offset = 0x06, .h_pixels = 708,
955 .v_max_out = 480, .h_max_out = 640,
957 .name = "SECAM", .id = V4L2_STD_SECAM,
958 .v_offset = 0x14, .v_field = 288,
959 .h_offset = 0x14, .h_pixels = 720,
960 .v_max_out = 576, .h_max_out = 768,
964 static struct saa7146_pci_extension_data mxb = {
965 .ext_priv = "Multimedia eXtension Board",
969 static struct pci_device_id pci_tbl[] = {
971 .vendor = PCI_VENDOR_ID_PHILIPS,
972 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
975 .driver_data = (unsigned long)&mxb,
981 MODULE_DEVICE_TABLE(pci, pci_tbl);
983 static struct saa7146_ext_vv vv_data = {
984 .inputs = MXB_INPUTS,
985 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
986 .stds = &standard[0],
987 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
988 .std_callback = &std_callback,
989 .ioctls = &ioctls[0],
993 static struct saa7146_extension extension = {
994 .name = MXB_IDENTIFIER,
995 .flags = SAA7146_USE_I2C_IRQ,
997 .pci_tbl = &pci_tbl[0],
998 .module = THIS_MODULE,
1001 .attach = mxb_attach,
1002 .detach = mxb_detach,
1008 static int __init mxb_init_module(void)
1010 if( 0 != saa7146_register_extension(&extension)) {
1011 DEB_S(("failed to register extension.\n"));
1018 static void __exit mxb_cleanup_module(void)
1020 saa7146_unregister_extension(&extension);
1023 module_init(mxb_init_module);
1024 module_exit(mxb_cleanup_module);
1026 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1027 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1028 MODULE_LICENSE("GPL");