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>
30 #include <media/saa7115.h>
37 #define I2C_SAA7111 0x24
39 #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
44 /* initial frequence the tuner will be tuned to.
45 in verden (lower saxony, germany) 4148 is a
46 channel called "phoenix" */
47 static int freq = 4148;
48 module_param(freq, int, 0644);
49 MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
52 module_param(debug, int, 0644);
53 MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
56 enum { TUNER, AUX1, AUX3, AUX3_YC };
58 static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
59 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
60 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
61 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
62 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
65 /* this array holds the information, which port of the saa7146 each
66 input actually uses. the mxb uses port 0 for every input */
70 } input_port_selection[MXB_INPUTS] = {
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 },
74 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
77 /* this array holds the information of the audio source (mxb_audios),
78 which has to be switched corresponding to the video source (mxb_channels) */
79 static int video_audio_connect[MXB_INPUTS] =
82 /* these are the necessary input-output-pins for bringing one audio source
83 (see above) to the CD-output */
84 static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
86 {{1,1,0},{1,1,0}}, /* Tuner */
87 {{5,1,0},{6,1,0}}, /* AUX 1 */
88 {{4,1,0},{6,1,0}}, /* AUX 2 */
89 {{3,1,0},{6,1,0}}, /* AUX 3 */
90 {{1,1,0},{3,1,0}}, /* Radio */
91 {{1,1,0},{2,1,0}}, /* CD-Rom */
92 {{6,1,0},{6,1,0}} /* Mute */
95 /* these are the necessary input-output-pins for bringing one audio source
96 (see above) to the line-output */
97 static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
105 {{6,3,0},{6,2,0}} /* Mute */
108 #define MAXCONTROLS 1
109 static struct v4l2_queryctrl mxb_controls[] = {
110 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
113 static struct saa7146_extension_ioctls ioctls[] = {
114 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
115 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
116 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
117 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
118 { VIDIOC_G_CTRL, SAA7146_BEFORE },
119 { VIDIOC_S_CTRL, SAA7146_BEFORE },
120 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
121 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
122 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
123 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
124 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
125 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
126 { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE },
127 { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE },
128 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
129 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
135 struct video_device *video_dev;
136 struct video_device *vbi_dev;
138 struct i2c_adapter i2c_adapter;
140 struct i2c_client *saa7111a;
141 struct i2c_client *tda9840;
142 struct i2c_client *tea6415c;
143 struct i2c_client *tuner;
144 struct i2c_client *tea6420_1;
145 struct i2c_client *tea6420_2;
147 int cur_mode; /* current audio mode (mono, stereo, ...) */
148 int cur_input; /* current input */
149 int cur_mute; /* current mute status */
150 struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
153 static struct saa7146_extension extension;
155 static int mxb_check_clients(struct device *dev, void *data)
157 struct mxb *mxb = data;
158 struct i2c_client *client = i2c_verify_client(dev);
163 if (I2C_ADDR_TEA6420_1 == client->addr)
164 mxb->tea6420_1 = client;
165 if (I2C_ADDR_TEA6420_2 == client->addr)
166 mxb->tea6420_2 = client;
167 if (I2C_TEA6415C_2 == client->addr)
168 mxb->tea6415c = client;
169 if (I2C_ADDR_TDA9840 == client->addr)
170 mxb->tda9840 = client;
171 if (I2C_SAA7111 == client->addr)
172 mxb->saa7111a = client;
173 if (0x60 == client->addr)
179 static int mxb_probe(struct saa7146_dev* dev)
181 struct mxb* mxb = NULL;
184 result = request_module("saa7115");
186 printk("mxb: saa7111 i2c module not available.\n");
189 result = request_module("tea6420");
191 printk("mxb: tea6420 i2c module not available.\n");
194 result = request_module("tea6415c");
196 printk("mxb: tea6415c i2c module not available.\n");
199 result = request_module("tda9840");
201 printk("mxb: tda9840 i2c module not available.\n");
204 result = request_module("tuner");
206 printk("mxb: tuner i2c module not available.\n");
210 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
212 DEB_D(("not enough kernel memory.\n"));
216 mxb->i2c_adapter = (struct i2c_adapter) {
217 .class = I2C_CLASS_TV_ANALOG,
221 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
222 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
223 DEB_S(("cannot register i2c-device. skipping.\n"));
228 /* loop through all i2c-devices on the bus and look who is there */
229 device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
231 /* check if all devices are present */
232 if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
233 !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
234 printk("mxb: did not find all i2c devices. aborting\n");
235 i2c_del_adapter(&mxb->i2c_adapter);
240 /* all devices are present, probe was successful */
242 /* we store the pointer in our private data field */
248 /* some init data for the saa7740, the so-called 'sound arena module'.
249 there are no specs available, so we simply use some init values */
253 } mxb_saa7740_init[] = {
254 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
255 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
256 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
257 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
258 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
259 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
260 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
261 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
262 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
263 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
264 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
265 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
266 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
267 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
268 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
269 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
270 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
271 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
272 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
273 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
274 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
275 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
276 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
277 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
278 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
279 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
280 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
281 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
282 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
283 { 3, { 0x48, 0x00, 0x01 } },
284 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
285 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
286 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
287 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
288 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
289 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
290 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
291 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
292 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
293 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
294 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
295 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
296 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
297 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
298 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
299 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
300 { 3, { 0x80, 0xb3, 0x0a } },
304 /* bring hardware to a sane state. this has to be done, just in case someone
305 wants to capture from this device before it has been properly initialized.
306 the capture engine would badly fail, because no valid signal arrives on the
307 saa7146, thus leading to timeouts and stuff. */
308 static int mxb_init_done(struct saa7146_dev* dev)
310 struct mxb* mxb = (struct mxb*)dev->ext_priv;
312 struct tuner_setup tun_setup;
313 v4l2_std_id std = V4L2_STD_PAL_BG;
314 struct v4l2_routing route;
317 struct tea6415c_multiplex vm;
319 /* select video mode in saa7111a */
320 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std);
322 /* select tuner-output on saa7111a */
324 route.input = SAA7115_COMPOSITE0;
325 route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
326 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route);
328 /* select a tuner type */
329 tun_setup.mode_mask = T_ANALOG_TV;
330 tun_setup.addr = ADDR_UNSET;
331 tun_setup.type = TUNER_PHILIPS_PAL;
332 mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup);
333 /* tune in some frequency on tuner */
334 mxb->cur_freq.tuner = 0;
335 mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
336 mxb->cur_freq.frequency = freq;
337 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
340 /* set a default video standard */
341 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
343 /* mute audio on tea6420s */
344 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]);
345 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]);
346 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]);
347 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]);
349 /* switch to tuner-channel on tea6415c*/
352 mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
354 /* select tuner-output on multicable on tea6415c*/
357 mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
359 /* the rest for mxb */
363 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
365 /* check if the saa7740 (aka 'sound arena module') is present
366 on the mxb. if so, we must initialize it. due to lack of
367 informations about the saa7740, the values were reverse
371 msg.len = mxb_saa7740_init[0].length;
372 msg.buf = &mxb_saa7740_init[0].data[0];
374 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
376 /* the sound arena module is a pos, that's probably the reason
377 philips refuses to hand out a datasheet for the saa7740...
378 it seems to screw up the i2c bus, so we disable fast irq
379 based i2c transactions here and rely on the slow and safe
380 polling method ... */
381 extension.flags &= ~SAA7146_USE_I2C_IRQ;
383 if (-1 == mxb_saa7740_init[i].length)
386 msg.len = mxb_saa7740_init[i].length;
387 msg.buf = &mxb_saa7740_init[i].data[0];
388 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
390 DEB_D(("failed to initialize 'sound arena module'.\n"));
394 INFO(("'sound arena module' detected.\n"));
397 /* the rest for saa7146: you should definitely set some basic values
398 for the input-port handling of the saa7146. */
400 /* ext->saa has been filled by the core driver */
402 /* some stuff is done via variables */
403 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
404 input_port_selection[mxb->cur_input].hps_sync);
406 /* some stuff is done via direct write to the registers */
408 /* this is ugly, but because of the fact that this is completely
409 hardware dependend, it should be done directly... */
410 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
411 saa7146_write(dev, DD1_INIT, 0x02000200);
412 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
417 /* interrupt-handler. this gets called when irq_mask is != 0.
418 it must clear the interrupt-bits in irq_mask it has handled */
420 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
422 struct mxb* mxb = (struct mxb*)dev->ext_priv;
426 static struct saa7146_ext_vv vv_data;
428 /* this function only gets called when the probing was successful */
429 static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
431 struct mxb *mxb = (struct mxb *)dev->ext_priv;
433 DEB_EE(("dev:%p\n", dev));
435 /* checking for i2c-devices can be omitted here, because we
436 already did this in "mxb_vl42_probe" */
438 saa7146_vv_init(dev, &vv_data);
439 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
440 ERR(("cannot register capture v4l2 device. skipping.\n"));
444 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
445 if (MXB_BOARD_CAN_DO_VBI(dev)) {
446 if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
447 ERR(("cannot register vbi v4l2 device. skipping.\n"));
451 i2c_use_client(mxb->tea6420_1);
452 i2c_use_client(mxb->tea6420_2);
453 i2c_use_client(mxb->tea6415c);
454 i2c_use_client(mxb->tda9840);
455 i2c_use_client(mxb->saa7111a);
456 i2c_use_client(mxb->tuner);
458 printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
465 static int mxb_detach(struct saa7146_dev *dev)
467 struct mxb *mxb = (struct mxb *)dev->ext_priv;
469 DEB_EE(("dev:%p\n", dev));
471 i2c_release_client(mxb->tea6420_1);
472 i2c_release_client(mxb->tea6420_2);
473 i2c_release_client(mxb->tea6415c);
474 i2c_release_client(mxb->tda9840);
475 i2c_release_client(mxb->saa7111a);
476 i2c_release_client(mxb->tuner);
478 saa7146_unregister_device(&mxb->video_dev,dev);
479 if (MXB_BOARD_CAN_DO_VBI(dev))
480 saa7146_unregister_device(&mxb->vbi_dev, dev);
481 saa7146_vv_release(dev);
485 i2c_del_adapter(&mxb->i2c_adapter);
491 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
493 struct saa7146_dev *dev = fh->dev;
494 struct mxb *mxb = (struct mxb *)dev->ext_priv;
495 struct saa7146_vv *vv = dev->vv_data;
498 case VIDIOC_ENUMINPUT:
500 struct v4l2_input *i = arg;
502 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
503 if (i->index < 0 || i->index >= MXB_INPUTS)
505 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
508 /* the saa7146 provides some controls (brightness, contrast, saturation)
509 which gets registered *after* this function. because of this we have
510 to return with a value != 0 even if the function succeded.. */
511 case VIDIOC_QUERYCTRL:
513 struct v4l2_queryctrl *qc = arg;
516 for (i = MAXCONTROLS - 1; i >= 0; i--) {
517 if (mxb_controls[i].id == qc->id) {
518 *qc = mxb_controls[i];
519 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
527 struct v4l2_control *vc = arg;
530 for (i = MAXCONTROLS - 1; i >= 0; i--) {
531 if (mxb_controls[i].id == vc->id)
538 if (vc->id == V4L2_CID_AUDIO_MUTE) {
539 vc->value = mxb->cur_mute;
540 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
544 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
550 struct v4l2_control *vc = arg;
553 for (i = MAXCONTROLS - 1; i >= 0; i--) {
554 if (mxb_controls[i].id == vc->id)
561 if (vc->id == V4L2_CID_AUDIO_MUTE) {
562 mxb->cur_mute = vc->value;
564 /* switch the audio-source */
565 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
566 &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
567 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
568 &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
570 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
571 &TEA6420_line[6][0]);
572 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
573 &TEA6420_line[6][1]);
575 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
581 int *input = (int *)arg;
582 *input = mxb->cur_input;
584 DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
589 int input = *(int *)arg;
590 struct tea6415c_multiplex vm;
591 struct v4l2_routing route;
594 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
596 if (input < 0 || input >= MXB_INPUTS)
599 mxb->cur_input = input;
601 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
602 input_port_selection[input].hps_sync);
604 /* prepare switching of tea6415c and saa7111a;
605 have a look at the 'background'-file for further informations */
608 i = SAA7115_COMPOSITE0;
612 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
613 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
616 /* connect tuner-output always to multicable */
621 /* nothing to be done here. aux3_yc is
622 directly connected to the saa711a */
626 /* nothing to be done here. aux3 is
627 directly connected to the saa711a */
628 i = SAA7115_COMPOSITE1;
631 i = SAA7115_COMPOSITE0;
637 /* switch video in tea6415c only if necessary */
641 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
642 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
650 /* switch video in saa7111a */
653 if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
654 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
656 /* switch the audio-source only if necessary */
657 if( 0 == mxb->cur_mute ) {
658 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
659 &TEA6420_line[video_audio_connect[input]][0]);
660 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
661 &TEA6420_line[video_audio_connect[input]][1]);
668 struct v4l2_tuner *t = arg;
671 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
675 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
677 memset(t, 0, sizeof(*t));
678 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
680 strlcpy(t->name, "TV Tuner", sizeof(t->name));
681 t->type = V4L2_TUNER_ANALOG_TV;
682 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
683 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
684 t->audmode = mxb->cur_mode;
689 struct v4l2_tuner *t = arg;
692 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
696 mxb->cur_mode = t->audmode;
697 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
700 case VIDIOC_G_FREQUENCY:
702 struct v4l2_frequency *f = arg;
704 if (mxb->cur_input) {
705 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
712 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
715 case VIDIOC_S_FREQUENCY:
717 struct v4l2_frequency *f = arg;
722 if (V4L2_TUNER_ANALOG_TV != f->type)
725 if (mxb->cur_input) {
726 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
731 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
733 /* tune in desired frequency */
734 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
736 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
737 spin_lock(&dev->slock);
738 vv->vbi_fieldcount = 0;
739 spin_unlock(&dev->slock);
747 if (i < 0 || i >= MXB_AUDIOS) {
748 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
752 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
754 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
755 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
759 case MXB_S_AUDIO_LINE:
763 if (i < 0 || i >= MXB_AUDIOS) {
764 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
768 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
769 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
770 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
776 struct v4l2_audio *a = arg;
778 if (a->index < 0 || a->index > MXB_INPUTS) {
779 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
783 DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
784 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
790 struct v4l2_audio *a = arg;
792 DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
795 #ifdef CONFIG_VIDEO_ADV_DEBUG
796 case VIDIOC_DBG_S_REGISTER:
797 case VIDIOC_DBG_G_REGISTER:
798 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
803 DEB2(printk("does not handle this ioctl.\n"));
810 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
812 struct mxb *mxb = (struct mxb *)dev->ext_priv;
816 if (V4L2_STD_PAL_I == standard->id) {
817 v4l2_std_id std = V4L2_STD_PAL_I;
819 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
820 /* set the 7146 gpio register -- I don't know what this does exactly */
821 saa7146_write(dev, GPIO_CTRL, 0x00404050);
822 /* unset the 7111 gpio register -- I don't know what this does exactly */
823 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero);
824 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
826 v4l2_std_id std = V4L2_STD_PAL_BG;
828 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
829 /* set the 7146 gpio register -- I don't know what this does exactly */
830 saa7146_write(dev, GPIO_CTRL, 0x00404050);
831 /* set the 7111 gpio register -- I don't know what this does exactly */
832 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one);
833 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
838 static struct saa7146_standard standard[] = {
840 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
841 .v_offset = 0x17, .v_field = 288,
842 .h_offset = 0x14, .h_pixels = 680,
843 .v_max_out = 576, .h_max_out = 768,
845 .name = "PAL-I", .id = V4L2_STD_PAL_I,
846 .v_offset = 0x17, .v_field = 288,
847 .h_offset = 0x14, .h_pixels = 680,
848 .v_max_out = 576, .h_max_out = 768,
850 .name = "NTSC", .id = V4L2_STD_NTSC,
851 .v_offset = 0x16, .v_field = 240,
852 .h_offset = 0x06, .h_pixels = 708,
853 .v_max_out = 480, .h_max_out = 640,
855 .name = "SECAM", .id = V4L2_STD_SECAM,
856 .v_offset = 0x14, .v_field = 288,
857 .h_offset = 0x14, .h_pixels = 720,
858 .v_max_out = 576, .h_max_out = 768,
862 static struct saa7146_pci_extension_data mxb = {
863 .ext_priv = "Multimedia eXtension Board",
867 static struct pci_device_id pci_tbl[] = {
869 .vendor = PCI_VENDOR_ID_PHILIPS,
870 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
873 .driver_data = (unsigned long)&mxb,
879 MODULE_DEVICE_TABLE(pci, pci_tbl);
881 static struct saa7146_ext_vv vv_data = {
882 .inputs = MXB_INPUTS,
883 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
884 .stds = &standard[0],
885 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
886 .std_callback = &std_callback,
887 .ioctls = &ioctls[0],
891 static struct saa7146_extension extension = {
892 .name = MXB_IDENTIFIER,
893 .flags = SAA7146_USE_I2C_IRQ,
895 .pci_tbl = &pci_tbl[0],
896 .module = THIS_MODULE,
899 .attach = mxb_attach,
900 .detach = mxb_detach,
906 static int __init mxb_init_module(void)
908 if (saa7146_register_extension(&extension)) {
909 DEB_S(("failed to register extension.\n"));
916 static void __exit mxb_cleanup_module(void)
918 saa7146_unregister_extension(&extension);
921 module_init(mxb_init_module);
922 module_exit(mxb_cleanup_module);
924 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
925 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
926 MODULE_LICENSE("GPL");