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;
158 if ((result = request_module("saa7111")) < 0) {
159 printk("mxb: saa7111 i2c module not available.\n");
162 if ((result = request_module("tea6420")) < 0) {
163 printk("mxb: tea6420 i2c module not available.\n");
166 if ((result = request_module("tea6415c")) < 0) {
167 printk("mxb: tea6415c i2c module not available.\n");
170 if ((result = request_module("tda9840")) < 0) {
171 printk("mxb: tda9840 i2c module not available.\n");
174 if ((result = request_module("tuner")) < 0) {
175 printk("mxb: tuner i2c module not available.\n");
179 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
181 DEB_D(("not enough kernel memory.\n"));
185 mxb->i2c_adapter = (struct i2c_adapter) {
186 .class = I2C_CLASS_TV_ANALOG,
190 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
191 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
192 DEB_S(("cannot register i2c-device. skipping.\n"));
197 /* loop through all i2c-devices on the bus and look who is there */
198 list_for_each_entry(client, &mxb->i2c_adapter.clients, list) {
199 if( I2C_ADDR_TEA6420_1 == client->addr )
200 mxb->tea6420_1 = client;
201 if( I2C_ADDR_TEA6420_2 == client->addr )
202 mxb->tea6420_2 = client;
203 if( I2C_TEA6415C_2 == client->addr )
204 mxb->tea6415c = client;
205 if( I2C_ADDR_TDA9840 == client->addr )
206 mxb->tda9840 = client;
207 if( I2C_SAA7111 == client->addr )
208 mxb->saa7111a = client;
209 if( 0x60 == client->addr )
213 /* check if all devices are present */
214 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
215 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
217 printk("mxb: did not find all i2c devices. aborting\n");
218 i2c_del_adapter(&mxb->i2c_adapter);
223 /* all devices are present, probe was successful */
225 /* we store the pointer in our private data field */
231 /* some init data for the saa7740, the so-called 'sound arena module'.
232 there are no specs available, so we simply use some init values */
236 } mxb_saa7740_init[] = {
237 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
238 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
239 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
240 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
241 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
242 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
243 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
244 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
245 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
246 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
247 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
248 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
249 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
250 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
251 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
252 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
253 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
254 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
255 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
256 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
257 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
258 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
259 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
260 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
261 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
262 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
263 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
264 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
265 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
266 { 3, { 0x48, 0x00, 0x01 } },
267 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
268 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
269 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
270 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
271 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
272 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
273 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
274 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
275 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
276 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
277 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
278 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
279 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
280 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
281 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
282 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
283 { 3, { 0x80, 0xb3, 0x0a } },
287 static const unsigned char mxb_saa7111_init[] = {
288 0x00, 0x00, /* 00 - ID byte */
289 0x01, 0x00, /* 01 - reserved */
292 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
293 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
294 0x04, 0x00, /* 04 - GAI1=256 */
295 0x05, 0x00, /* 05 - GAI2=256 */
298 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
299 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
300 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
301 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
302 0x0a, 0x80, /* 0a - BRIG=128 */
303 0x0b, 0x47, /* 0b - CONT=1.109 */
304 0x0c, 0x40, /* 0c - SATN=1.0 */
305 0x0d, 0x00, /* 0d - HUE=0 */
306 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
307 0x0f, 0x00, /* 0f - reserved */
308 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
309 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
310 0x12, 0x80, /* 12 - xx output control 2 */
311 0x13, 0x30, /* 13 - xx output control 3 */
312 0x14, 0x00, /* 14 - reserved */
313 0x15, 0x15, /* 15 - VBI */
314 0x16, 0x04, /* 16 - VBI */
315 0x17, 0x00, /* 17 - VBI */
318 /* bring hardware to a sane state. this has to be done, just in case someone
319 wants to capture from this device before it has been properly initialized.
320 the capture engine would badly fail, because no valid signal arrives on the
321 saa7146, thus leading to timeouts and stuff. */
322 static int mxb_init_done(struct saa7146_dev* dev)
324 struct mxb* mxb = (struct mxb*)dev->ext_priv;
325 struct video_decoder_init init;
327 struct tuner_setup tun_setup;
328 v4l2_std_id std = V4L2_STD_PAL_BG;
331 struct tea6415c_multiplex vm;
333 /* select video mode in saa7111a */
335 /* fixme: currently pointless: gets overwritten by configuration below */
336 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
338 /* write configuration to saa7111a */
339 init.data = mxb_saa7111_init;
340 init.len = sizeof(mxb_saa7111_init);
341 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
343 /* select tuner-output on saa7111a */
345 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
347 /* enable vbi bypass */
349 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
351 /* select a tuner type */
352 tun_setup.mode_mask = T_ANALOG_TV;
353 tun_setup.addr = ADDR_UNSET;
354 tun_setup.type = TUNER_PHILIPS_PAL;
355 mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
356 /* tune in some frequency on tuner */
357 mxb->cur_freq.tuner = 0;
358 mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
359 mxb->cur_freq.frequency = freq;
360 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
363 /* set a default video standard */
364 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
366 /* mute audio on tea6420s */
367 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
368 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
369 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
370 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
372 /* switch to tuner-channel on tea6415c*/
375 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
377 /* select tuner-output on multicable on tea6415c*/
380 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
382 /* the rest for mxb */
386 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
387 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
389 /* check if the saa7740 (aka 'sound arena module') is present
390 on the mxb. if so, we must initialize it. due to lack of
391 informations about the saa7740, the values were reverse
395 msg.len = mxb_saa7740_init[0].length;
396 msg.buf = &mxb_saa7740_init[0].data[0];
398 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
399 /* the sound arena module is a pos, that's probably the reason
400 philips refuses to hand out a datasheet for the saa7740...
401 it seems to screw up the i2c bus, so we disable fast irq
402 based i2c transactions here and rely on the slow and safe
403 polling method ... */
404 extension.flags &= ~SAA7146_USE_I2C_IRQ;
406 if( -1 == mxb_saa7740_init[i].length ) {
410 msg.len = mxb_saa7740_init[i].length;
411 msg.buf = &mxb_saa7740_init[i].data[0];
412 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
413 DEB_D(("failed to initialize 'sound arena module'.\n"));
417 INFO(("'sound arena module' detected.\n"));
420 /* the rest for saa7146: you should definitely set some basic values
421 for the input-port handling of the saa7146. */
423 /* ext->saa has been filled by the core driver */
425 /* some stuff is done via variables */
426 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
428 /* some stuff is done via direct write to the registers */
430 /* this is ugly, but because of the fact that this is completely
431 hardware dependend, it should be done directly... */
432 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
433 saa7146_write(dev, DD1_INIT, 0x02000200);
434 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
439 /* interrupt-handler. this gets called when irq_mask is != 0.
440 it must clear the interrupt-bits in irq_mask it has handled */
442 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
444 struct mxb* mxb = (struct mxb*)dev->ext_priv;
448 static struct saa7146_ext_vv vv_data;
450 /* this function only gets called when the probing was successful */
451 static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
453 struct mxb* mxb = (struct mxb*)dev->ext_priv;
455 DEB_EE(("dev:%p\n",dev));
457 /* checking for i2c-devices can be omitted here, because we
458 already did this in "mxb_vl42_probe" */
460 saa7146_vv_init(dev,&vv_data);
461 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
462 ERR(("cannot register capture v4l2 device. skipping.\n"));
466 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
467 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
468 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
469 ERR(("cannot register vbi v4l2 device. skipping.\n"));
473 i2c_use_client(mxb->tea6420_1);
474 i2c_use_client(mxb->tea6420_2);
475 i2c_use_client(mxb->tea6415c);
476 i2c_use_client(mxb->tda9840);
477 i2c_use_client(mxb->saa7111a);
478 i2c_use_client(mxb->tuner);
480 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
487 static int mxb_detach(struct saa7146_dev* dev)
489 struct mxb* mxb = (struct mxb*)dev->ext_priv;
491 DEB_EE(("dev:%p\n",dev));
493 i2c_release_client(mxb->tea6420_1);
494 i2c_release_client(mxb->tea6420_2);
495 i2c_release_client(mxb->tea6415c);
496 i2c_release_client(mxb->tda9840);
497 i2c_release_client(mxb->saa7111a);
498 i2c_release_client(mxb->tuner);
500 saa7146_unregister_device(&mxb->video_dev,dev);
501 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
502 saa7146_unregister_device(&mxb->vbi_dev,dev);
504 saa7146_vv_release(dev);
508 i2c_del_adapter(&mxb->i2c_adapter);
514 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
516 struct saa7146_dev *dev = fh->dev;
517 struct mxb* mxb = (struct mxb*)dev->ext_priv;
518 struct saa7146_vv *vv = dev->vv_data;
521 case VIDIOC_ENUMINPUT:
523 struct v4l2_input *i = arg;
525 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
526 if( i->index < 0 || i->index >= MXB_INPUTS) {
529 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
533 /* the saa7146 provides some controls (brightness, contrast, saturation)
534 which gets registered *after* this function. because of this we have
535 to return with a value != 0 even if the function succeded.. */
536 case VIDIOC_QUERYCTRL:
538 struct v4l2_queryctrl *qc = arg;
541 for (i = MAXCONTROLS - 1; i >= 0; i--) {
542 if (mxb_controls[i].id == qc->id) {
543 *qc = mxb_controls[i];
544 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
552 struct v4l2_control *vc = arg;
555 for (i = MAXCONTROLS - 1; i >= 0; i--) {
556 if (mxb_controls[i].id == vc->id) {
566 case V4L2_CID_AUDIO_MUTE: {
567 vc->value = mxb->cur_mute;
568 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
573 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
579 struct v4l2_control *vc = arg;
582 for (i = MAXCONTROLS - 1; i >= 0; i--) {
583 if (mxb_controls[i].id == vc->id) {
593 case V4L2_CID_AUDIO_MUTE: {
594 mxb->cur_mute = vc->value;
595 if( 0 == vc->value ) {
596 /* switch the audio-source */
597 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
598 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
600 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
601 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
603 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
611 int *input = (int *)arg;
612 *input = mxb->cur_input;
614 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
619 int input = *(int *)arg;
620 struct tea6415c_multiplex vm;
623 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
625 if (input < 0 || input >= MXB_INPUTS) {
629 /* fixme: locke das setzen des inputs mit hilfe des mutexes
630 mutex_lock(&dev->lock);
632 mutex_unlock(&dev->lock);
635 /* fixme: check if streaming capture
636 if ( 0 != dev->streaming ) {
637 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
642 mxb->cur_input = input;
644 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
646 /* prepare switching of tea6415c and saa7111a;
647 have a look at the 'background'-file for further informations */
656 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
657 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
660 /* connect tuner-output always to multicable */
667 /* nothing to be done here. aux3_yc is
668 directly connected to the saa711a */
674 /* nothing to be done here. aux3 is
675 directly connected to the saa711a */
688 /* switch video in tea6415c only if necessary */
693 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
694 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
705 /* switch video in saa7111a */
706 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
707 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
710 /* switch the audio-source only if necessary */
711 if( 0 == mxb->cur_mute ) {
712 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
713 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
720 struct v4l2_tuner *t = arg;
723 if( 0 != t->index ) {
724 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
728 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
730 memset(t,0,sizeof(*t));
731 strcpy(t->name, "Television");
733 t->type = V4L2_TUNER_ANALOG_TV;
734 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
735 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
736 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
737 /* FIXME: add the real signal strength here */
741 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
742 t->audmode = mxb->cur_mode;
745 t->rxsubchans = V4L2_TUNER_SUB_MONO;
748 case TDA9840_MONO_DETECT: {
749 t->rxsubchans = V4L2_TUNER_SUB_MONO;
750 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
753 case TDA9840_DUAL_DETECT: {
754 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
755 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
758 case TDA9840_STEREO_DETECT: {
759 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
760 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
763 default: { /* TDA9840_INCORRECT_DETECT */
764 t->rxsubchans = V4L2_TUNER_MODE_MONO;
765 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
775 struct v4l2_tuner *t = arg;
779 if( 0 != t->index ) {
780 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
785 case V4L2_TUNER_MODE_STEREO: {
786 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
787 byte = TDA9840_SET_STEREO;
788 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
791 case V4L2_TUNER_MODE_LANG1_LANG2: {
792 mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2;
793 byte = TDA9840_SET_BOTH;
794 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"));
797 case V4L2_TUNER_MODE_LANG1: {
798 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
799 byte = TDA9840_SET_LANG1;
800 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
803 case V4L2_TUNER_MODE_LANG2: {
804 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
805 byte = TDA9840_SET_LANG2;
806 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
809 default: { /* case V4L2_TUNER_MODE_MONO: {*/
810 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
811 byte = TDA9840_SET_MONO;
812 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
817 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
818 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
823 case VIDIOC_G_FREQUENCY:
825 struct v4l2_frequency *f = arg;
827 if(0 != mxb->cur_input) {
828 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
834 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
837 case VIDIOC_S_FREQUENCY:
839 struct v4l2_frequency *f = arg;
844 if (V4L2_TUNER_ANALOG_TV != f->type)
847 if(0 != mxb->cur_input) {
848 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
853 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
855 /* tune in desired frequency */
856 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
858 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
859 spin_lock(&dev->slock);
860 vv->vbi_fieldcount = 0;
861 spin_unlock(&dev->slock);
869 if( i < 0 || i >= MXB_AUDIOS ) {
870 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
874 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
876 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
877 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
881 case MXB_S_AUDIO_LINE:
885 if( i < 0 || i >= MXB_AUDIOS ) {
886 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
890 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
891 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
892 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
898 struct v4l2_audio *a = arg;
900 if( a->index < 0 || a->index > MXB_INPUTS ) {
901 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
905 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
906 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
912 struct v4l2_audio *a = arg;
913 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
918 DEB2(printk("does not handle this ioctl.\n"));
925 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
927 struct mxb* mxb = (struct mxb*)dev->ext_priv;
931 if(V4L2_STD_PAL_I == std->id ) {
932 v4l2_std_id std = V4L2_STD_PAL_I;
933 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
934 /* set the 7146 gpio register -- I don't know what this does exactly */
935 saa7146_write(dev, GPIO_CTRL, 0x00404050);
936 /* unset the 7111 gpio register -- I don't know what this does exactly */
937 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
938 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
940 v4l2_std_id std = V4L2_STD_PAL_BG;
941 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
942 /* set the 7146 gpio register -- I don't know what this does exactly */
943 saa7146_write(dev, GPIO_CTRL, 0x00404050);
944 /* set the 7111 gpio register -- I don't know what this does exactly */
945 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
946 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
951 static struct saa7146_standard standard[] = {
953 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
954 .v_offset = 0x17, .v_field = 288,
955 .h_offset = 0x14, .h_pixels = 680,
956 .v_max_out = 576, .h_max_out = 768,
958 .name = "PAL-I", .id = V4L2_STD_PAL_I,
959 .v_offset = 0x17, .v_field = 288,
960 .h_offset = 0x14, .h_pixels = 680,
961 .v_max_out = 576, .h_max_out = 768,
963 .name = "NTSC", .id = V4L2_STD_NTSC,
964 .v_offset = 0x16, .v_field = 240,
965 .h_offset = 0x06, .h_pixels = 708,
966 .v_max_out = 480, .h_max_out = 640,
968 .name = "SECAM", .id = V4L2_STD_SECAM,
969 .v_offset = 0x14, .v_field = 288,
970 .h_offset = 0x14, .h_pixels = 720,
971 .v_max_out = 576, .h_max_out = 768,
975 static struct saa7146_pci_extension_data mxb = {
976 .ext_priv = "Multimedia eXtension Board",
980 static struct pci_device_id pci_tbl[] = {
982 .vendor = PCI_VENDOR_ID_PHILIPS,
983 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
986 .driver_data = (unsigned long)&mxb,
992 MODULE_DEVICE_TABLE(pci, pci_tbl);
994 static struct saa7146_ext_vv vv_data = {
995 .inputs = MXB_INPUTS,
996 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
997 .stds = &standard[0],
998 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
999 .std_callback = &std_callback,
1000 .ioctls = &ioctls[0],
1004 static struct saa7146_extension extension = {
1005 .name = MXB_IDENTIFIER,
1006 .flags = SAA7146_USE_I2C_IRQ,
1008 .pci_tbl = &pci_tbl[0],
1009 .module = THIS_MODULE,
1012 .attach = mxb_attach,
1013 .detach = mxb_detach,
1019 static int __init mxb_init_module(void)
1021 if( 0 != saa7146_register_extension(&extension)) {
1022 DEB_S(("failed to register extension.\n"));
1029 static void __exit mxb_cleanup_module(void)
1031 saa7146_unregister_extension(&extension);
1034 module_init(mxb_init_module);
1035 module_exit(mxb_cleanup_module);
1037 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1038 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1039 MODULE_LICENSE("GPL");