initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / media / video / mxb.c
blob121d626f03b668ec57e3e2aa8f0a31be124b7ccf
1 /*
2 mxb.c - 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>
30 #include "mxb.h"
31 #include "tea6415c.h"
32 #include "tea6420.h"
33 #include "tda9840.h"
35 #define I2C_SAA7111 0x24
37 #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
39 /* global variable */
40 static int mxb_num = 0;
42 /* initial frequence the tuner will be tuned to.
43 in verden (lower saxony, germany) 4148 is a
44 channel called "phoenix" */
45 static int freq = 4148;
46 MODULE_PARM(freq,"i");
47 MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
49 static int debug = 0;
50 MODULE_PARM(debug,"i");
51 MODULE_PARM_DESC(debug, "debug verbosity");
53 #define MXB_INPUTS 4
54 enum { TUNER, AUX1, AUX3, AUX3_YC };
56 static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
57 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
58 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
59 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
60 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
63 /* this array holds the information, which port of the saa7146 each
64 input actually uses. the mxb uses port 0 for every input */
65 static struct {
66 int hps_source;
67 int hps_sync;
68 } input_port_selection[MXB_INPUTS] = {
69 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
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 },
75 /* this array holds the information of the audio source (mxb_audios),
76 which has to be switched corresponding to the video source (mxb_channels) */
77 static int video_audio_connect[MXB_INPUTS] =
78 { 0, 1, 3, 3 };
80 /* these are the necessary input-output-pins for bringing one audio source
81 (see above) to the CD-output */
82 static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
84 {{1,1,0},{1,1,0}}, /* Tuner */
85 {{5,1,0},{6,1,0}}, /* AUX 1 */
86 {{4,1,0},{6,1,0}}, /* AUX 2 */
87 {{3,1,0},{6,1,0}}, /* AUX 3 */
88 {{1,1,0},{3,1,0}}, /* Radio */
89 {{1,1,0},{2,1,0}}, /* CD-Rom */
90 {{6,1,0},{6,1,0}} /* Mute */
93 /* these are the necessary input-output-pins for bringing one audio source
94 (see above) to the line-output */
95 static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
97 {{2,3,0},{1,2,0}},
98 {{5,3,0},{6,2,0}},
99 {{4,3,0},{6,2,0}},
100 {{3,3,0},{6,2,0}},
101 {{2,3,0},{3,2,0}},
102 {{2,3,0},{2,2,0}},
103 {{6,3,0},{6,2,0}} /* Mute */
106 #define MAXCONTROLS 1
107 static struct v4l2_queryctrl mxb_controls[] = {
108 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
111 static struct saa7146_extension_ioctls ioctls[] = {
112 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
113 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
114 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
115 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
116 { VIDIOC_G_CTRL, SAA7146_BEFORE },
117 { VIDIOC_S_CTRL, SAA7146_BEFORE },
118 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
119 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
120 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
121 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
122 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
123 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
124 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
125 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
126 { 0, 0 }
129 struct mxb
131 struct video_device video_dev;
132 struct video_device vbi_dev;
134 struct i2c_adapter i2c_adapter;
136 struct i2c_client* saa7111a;
137 struct i2c_client* tda9840;
138 struct i2c_client* tea6415c;
139 struct i2c_client* tuner;
140 struct i2c_client* tea6420_1;
141 struct i2c_client* tea6420_2;
143 int cur_mode; /* current audio mode (mono, stereo, ...) */
144 int cur_input; /* current input */
145 int cur_freq; /* current frequency the tuner is tuned to */
146 int cur_mute; /* current mute status */
149 static struct saa7146_extension extension;
151 static int mxb_probe(struct saa7146_dev* dev)
153 struct mxb* mxb = NULL;
154 struct i2c_client *client;
155 struct list_head *item;
156 int result;
158 if ((result = request_module("saa7111")) < 0) {
159 printk("mxb: saa7111 i2c module not available.\n");
160 return -ENODEV;
162 if ((result = request_module("tuner")) < 0) {
163 printk("mxb: tuner i2c module not available.\n");
164 return -ENODEV;
166 if ((result = request_module("tea6420")) < 0) {
167 printk("mxb: tea6420 i2c module not available.\n");
168 return -ENODEV;
170 if ((result = request_module("tea6415c")) < 0) {
171 printk("mxb: tea6415c i2c module not available.\n");
172 return -ENODEV;
174 if ((result = request_module("tda9840")) < 0) {
175 printk("mxb: tda9840 i2c module not available.\n");
176 return -ENODEV;
179 mxb = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL);
180 if( NULL == mxb ) {
181 DEB_D(("not enough kernel memory.\n"));
182 return -ENOMEM;
184 memset(mxb, 0x0, sizeof(struct mxb));
186 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, I2C_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480);
187 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
188 DEB_S(("cannot register i2c-device. skipping.\n"));
189 kfree(mxb);
190 return -EFAULT;
193 /* loop through all i2c-devices on the bus and look who is there */
194 list_for_each(item,&mxb->i2c_adapter.clients) {
195 client = list_entry(item, struct i2c_client, list);
196 if( I2C_TEA6420_1 == client->addr )
197 mxb->tea6420_1 = client;
198 if( I2C_TEA6420_2 == client->addr )
199 mxb->tea6420_2 = client;
200 if( I2C_TEA6415C_2 == client->addr )
201 mxb->tea6415c = client;
202 if( I2C_TDA9840 == client->addr )
203 mxb->tda9840 = client;
204 if( I2C_SAA7111 == client->addr )
205 mxb->saa7111a = client;
206 if( 0x60 == client->addr )
207 mxb->tuner = client;
210 /* check if all devices are present */
211 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
212 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
214 printk("mxb: did not find all i2c devices. aborting\n");
215 i2c_del_adapter(&mxb->i2c_adapter);
216 kfree(mxb);
217 return -ENODEV;
220 /* all devices are present, probe was successful */
222 /* we store the pointer in our private data field */
223 dev->ext_priv = mxb;
225 return 0;
228 /* some init data for the saa7740, the so-called 'sound arena module'.
229 there are no specs available, so we simply use some init values */
230 static struct {
231 int length;
232 char data[9];
233 } mxb_saa7740_init[] = {
234 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
235 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
236 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
237 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
238 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
239 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
240 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
241 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
242 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
243 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
244 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
245 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
246 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
247 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
248 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
249 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
250 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
251 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
252 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
253 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
254 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
255 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
256 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
257 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
258 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
259 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
260 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
261 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
262 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
263 { 3, { 0x48, 0x00, 0x01 } },
264 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
265 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
266 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
267 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
268 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
269 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
270 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
271 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
272 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
273 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
274 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
275 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
276 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
277 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
278 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
279 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
280 { 3, { 0x80, 0xb3, 0x0a } },
281 {-1, { 0} }
284 static const unsigned char mxb_saa7111_init[] = {
285 0x00, 0x00, /* 00 - ID byte */
286 0x01, 0x00, /* 01 - reserved */
288 /*front end */
289 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
290 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
291 0x04, 0x00, /* 04 - GAI1=256 */
292 0x05, 0x00, /* 05 - GAI2=256 */
294 /* decoder */
295 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
296 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
297 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
298 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
299 0x0a, 0x80, /* 0a - BRIG=128 */
300 0x0b, 0x47, /* 0b - CONT=1.109 */
301 0x0c, 0x40, /* 0c - SATN=1.0 */
302 0x0d, 0x00, /* 0d - HUE=0 */
303 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
304 0x0f, 0x00, /* 0f - reserved */
305 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
306 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
307 0x12, 0x80, /* 12 - xx output control 2 */
308 0x13, 0x30, /* 13 - xx output control 3 */
309 0x14, 0x00, /* 14 - reserved */
310 0x15, 0x15, /* 15 - VBI */
311 0x16, 0x04, /* 16 - VBI */
312 0x17, 0x00, /* 17 - VBI */
315 /* bring hardware to a sane state. this has to be done, just in case someone
316 wants to capture from this device before it has been properly initialized.
317 the capture engine would badly fail, because no valid signal arrives on the
318 saa7146, thus leading to timeouts and stuff. */
319 static int mxb_init_done(struct saa7146_dev* dev)
321 struct mxb* mxb = (struct mxb*)dev->ext_priv;
322 struct video_decoder_init init;
323 struct i2c_msg msg;
325 int i = 0, err = 0;
326 struct tea6415c_multiplex vm;
328 /* select video mode in saa7111a */
329 i = VIDEO_MODE_PAL;
330 /* fixme: currently pointless: gets overwritten by configuration below */
331 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
333 /* write configuration to saa7111a */
334 init.data = mxb_saa7111_init;
335 init.len = sizeof(mxb_saa7111_init);
336 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
338 /* select tuner-output on saa7111a */
339 i = 0;
340 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
342 /* enable vbi bypass */
343 i = 1;
344 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
346 /* select a tuner type */
347 i = 5;
348 mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE, &i);
350 /* mute audio on tea6420s */
351 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
352 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
353 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
354 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
356 /* switch to tuner-channel on tea6415c*/
357 vm.out = 17;
358 vm.in = 3;
359 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
361 /* select tuner-output on multicable on tea6415c*/
362 vm.in = 3;
363 vm.out = 13;
364 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
366 /* tune in some frequency on tuner */
367 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &freq);
369 /* the rest for mxb */
370 mxb->cur_input = 0;
371 mxb->cur_freq = freq;
372 mxb->cur_mute = 1;
374 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
375 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
377 /* check if the saa7740 (aka 'sound arena module') is present
378 on the mxb. if so, we must initialize it. due to lack of
379 informations about the saa7740, the values were reverse
380 engineered. */
381 msg.addr = 0x1b;
382 msg.flags = 0;
383 msg.len = mxb_saa7740_init[0].length;
384 msg.buf = &mxb_saa7740_init[0].data[0];
386 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
387 /* the sound arena module is a pos, that's probably the reason
388 philips refuses to hand out a datasheet for the saa7740...
389 it seems to screw up the i2c bus, so we disable fast irq
390 based i2c transactions here and rely on the slow and safe
391 polling method ... */
392 extension.flags &= ~SAA7146_USE_I2C_IRQ;
393 for(i = 1;;i++) {
394 if( -1 == mxb_saa7740_init[i].length ) {
395 break;
398 msg.len = mxb_saa7740_init[i].length;
399 msg.buf = &mxb_saa7740_init[i].data[0];
400 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
401 DEB_D(("failed to initialize 'sound arena module'.\n"));
402 goto err;
405 INFO(("'sound arena module' detected.\n"));
407 err:
408 /* the rest for saa7146: you should definitely set some basic values
409 for the input-port handling of the saa7146. */
411 /* ext->saa has been filled by the core driver */
413 /* some stuff is done via variables */
414 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
416 /* some stuff is done via direct write to the registers */
418 /* this is ugly, but because of the fact that this is completely
419 hardware dependend, it should be done directly... */
420 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
421 saa7146_write(dev, DD1_INIT, 0x02000200);
422 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
424 return 0;
427 /* interrupt-handler. this gets called when irq_mask is != 0.
428 it must clear the interrupt-bits in irq_mask it has handled */
430 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
432 struct mxb* mxb = (struct mxb*)dev->ext_priv;
436 static struct saa7146_ext_vv vv_data;
438 /* this function only gets called when the probing was successful */
439 static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
441 struct mxb* mxb = (struct mxb*)dev->ext_priv;
443 DEB_EE(("dev:%p\n",dev));
445 /* checking for i2c-devices can be omitted here, because we
446 already did this in "mxb_vl42_probe" */
448 saa7146_vv_init(dev,&vv_data);
449 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
450 ERR(("cannot register capture v4l2 device. skipping.\n"));
451 return -1;
454 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
455 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
456 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
457 ERR(("cannot register vbi v4l2 device. skipping.\n"));
461 i2c_use_client(mxb->tea6420_1);
462 i2c_use_client(mxb->tea6420_2);
463 i2c_use_client(mxb->tea6415c);
464 i2c_use_client(mxb->tda9840);
465 i2c_use_client(mxb->saa7111a);
466 i2c_use_client(mxb->tuner);
468 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
470 mxb_num++;
471 mxb_init_done(dev);
472 return 0;
475 static int mxb_detach(struct saa7146_dev* dev)
477 struct mxb* mxb = (struct mxb*)dev->ext_priv;
479 DEB_EE(("dev:%p\n",dev));
481 i2c_release_client(mxb->tea6420_1);
482 i2c_release_client(mxb->tea6420_2);
483 i2c_release_client(mxb->tea6415c);
484 i2c_release_client(mxb->tda9840);
485 i2c_release_client(mxb->saa7111a);
486 i2c_release_client(mxb->tuner);
488 saa7146_unregister_device(&mxb->video_dev,dev);
489 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
490 saa7146_unregister_device(&mxb->vbi_dev,dev);
492 saa7146_vv_release(dev);
494 mxb_num--;
496 i2c_del_adapter(&mxb->i2c_adapter);
497 kfree(mxb);
499 return 0;
502 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
504 struct saa7146_dev *dev = fh->dev;
505 struct mxb* mxb = (struct mxb*)dev->ext_priv;
506 struct saa7146_vv *vv = dev->vv_data;
508 switch(cmd) {
509 case VIDIOC_ENUMINPUT:
511 struct v4l2_input *i = arg;
513 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
514 if( i->index < 0 || i->index >= MXB_INPUTS) {
515 return -EINVAL;
517 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
519 return 0;
521 /* the saa7146 provides some controls (brightness, contrast, saturation)
522 which gets registered *after* this function. because of this we have
523 to return with a value != 0 even if the function succeded.. */
524 case VIDIOC_QUERYCTRL:
526 struct v4l2_queryctrl *qc = arg;
527 int i;
529 for (i = MAXCONTROLS - 1; i >= 0; i--) {
530 if (mxb_controls[i].id == qc->id) {
531 *qc = mxb_controls[i];
532 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
533 return 0;
536 return -EAGAIN;
538 case VIDIOC_G_CTRL:
540 struct v4l2_control *vc = arg;
541 int i;
543 for (i = MAXCONTROLS - 1; i >= 0; i--) {
544 if (mxb_controls[i].id == vc->id) {
545 break;
549 if( i < 0 ) {
550 return -EAGAIN;
553 switch (vc->id ) {
554 case V4L2_CID_AUDIO_MUTE: {
555 vc->value = mxb->cur_mute;
556 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
557 return 0;
561 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
562 return 0;
565 case VIDIOC_S_CTRL:
567 struct v4l2_control *vc = arg;
568 int i = 0;
570 for (i = MAXCONTROLS - 1; i >= 0; i--) {
571 if (mxb_controls[i].id == vc->id) {
572 break;
576 if( i < 0 ) {
577 return -EAGAIN;
580 switch (vc->id ) {
581 case V4L2_CID_AUDIO_MUTE: {
582 mxb->cur_mute = vc->value;
583 if( 0 == vc->value ) {
584 /* switch the audio-source */
585 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
586 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
587 } else {
588 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
589 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
591 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
592 break;
595 return 0;
597 case VIDIOC_G_INPUT:
599 int *input = (int *)arg;
600 *input = mxb->cur_input;
602 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
603 return 0;
605 case VIDIOC_S_INPUT:
607 int input = *(int *)arg;
608 struct tea6415c_multiplex vm;
609 int i = 0;
611 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
613 if (input < 0 || input >= MXB_INPUTS) {
614 return -EINVAL;
617 /* fixme: locke das setzen des inputs mit hilfe des mutexes
618 down(&dev->lock);
619 video_mux(dev,*i);
620 up(&dev->lock);
623 /* fixme: check if streaming capture
624 if ( 0 != dev->streaming ) {
625 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
626 return -EPERM;
630 mxb->cur_input = input;
632 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
634 /* prepare switching of tea6415c and saa7111a;
635 have a look at the 'background'-file for further informations */
636 switch( input ) {
638 case TUNER:
640 i = 0;
641 vm.in = 3;
642 vm.out = 17;
644 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
645 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
646 return -EFAULT;
648 /* connect tuner-output always to multicable */
649 vm.in = 3;
650 vm.out = 13;
651 break;
653 case AUX3_YC:
655 /* nothing to be done here. aux3_yc is
656 directly connected to the saa711a */
657 i = 5;
658 break;
660 case AUX3:
662 /* nothing to be done here. aux3 is
663 directly connected to the saa711a */
664 i = 1;
665 break;
667 case AUX1:
669 i = 0;
670 vm.in = 1;
671 vm.out = 17;
672 break;
676 /* switch video in tea6415c only if necessary */
677 switch( input ) {
678 case TUNER:
679 case AUX1:
681 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
682 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
683 return -EFAULT;
685 break;
687 default:
689 break;
693 /* switch video in saa7111a */
694 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
695 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
698 /* switch the audio-source only if necessary */
699 if( 0 == mxb->cur_mute ) {
700 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
701 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
704 return 0;
706 case VIDIOC_G_TUNER:
708 struct v4l2_tuner *t = arg;
709 int byte = 0;
711 if( 0 != t->index ) {
712 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
713 return -EINVAL;
716 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
718 memset(t,0,sizeof(*t));
719 strcpy(t->name, "Television");
721 t->type = V4L2_TUNER_ANALOG_TV;
722 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
723 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
724 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
725 /* FIXME: add the real signal strength here */
726 t->signal = 0xffff;
727 t->afc = 0;
729 byte = mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, NULL);
730 t->audmode = mxb->cur_mode;
732 if( byte < 0 ) {
733 t->rxsubchans = V4L2_TUNER_SUB_MONO;
734 } else {
735 switch(byte) {
736 case TDA9840_MONO_DETECT: {
737 t->rxsubchans = V4L2_TUNER_SUB_MONO;
738 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
739 break;
741 case TDA9840_DUAL_DETECT: {
742 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
743 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
744 break;
746 case TDA9840_STEREO_DETECT: {
747 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
748 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
749 break;
751 default: { /* TDA9840_INCORRECT_DETECT */
752 t->rxsubchans = V4L2_TUNER_MODE_MONO;
753 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
754 break;
759 return 0;
761 case VIDIOC_S_TUNER:
763 struct v4l2_tuner *t = arg;
764 int result = 0;
765 int byte = 0;
767 if( 0 != t->index ) {
768 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
769 return -EINVAL;
772 switch(t->audmode) {
773 case V4L2_TUNER_MODE_STEREO: {
774 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
775 byte = TDA9840_SET_STEREO;
776 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
777 break;
779 case V4L2_TUNER_MODE_LANG1: {
780 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
781 byte = TDA9840_SET_LANG1;
782 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
783 break;
785 case V4L2_TUNER_MODE_LANG2: {
786 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
787 byte = TDA9840_SET_LANG2;
788 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
789 break;
791 default: { /* case V4L2_TUNER_MODE_MONO: {*/
792 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
793 byte = TDA9840_SET_MONO;
794 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
795 break;
799 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
800 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
803 return 0;
805 case VIDIOC_G_FREQUENCY:
807 struct v4l2_frequency *f = arg;
809 if(0 != mxb->cur_input) {
810 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
811 return -EINVAL;
814 memset(f,0,sizeof(*f));
815 f->type = V4L2_TUNER_ANALOG_TV;
816 f->frequency = mxb->cur_freq;
818 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq));
819 return 0;
821 case VIDIOC_S_FREQUENCY:
823 struct v4l2_frequency *f = arg;
824 int t_locked = 0;
825 int v_byte = 0;
827 if (0 != f->tuner)
828 return -EINVAL;
830 if (V4L2_TUNER_ANALOG_TV != f->type)
831 return -EINVAL;
833 if(0 != mxb->cur_input) {
834 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
835 return -EINVAL;
838 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
840 mxb->cur_freq = f->frequency;
842 /* tune in desired frequency */
843 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &mxb->cur_freq);
845 /* check if pll of tuner & saa7111a is locked */
846 // mxb->tuner->driver->command(mxb->tuner,TUNER_IS_LOCKED, &t_locked);
847 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_GET_STATUS, &v_byte);
849 /* not locked -- anything to do here ? */
850 if( 0 == t_locked || 0 == (v_byte & DECODER_STATUS_GOOD)) {
853 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
854 spin_lock(&dev->slock);
855 vv->vbi_fieldcount = 0;
856 spin_unlock(&dev->slock);
858 return 0;
860 case MXB_S_AUDIO_CD:
862 int i = *(int*)arg;
864 if( i < 0 || i >= MXB_AUDIOS ) {
865 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
866 return -EINVAL;
869 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
871 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
872 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
874 return 0;
876 case MXB_S_AUDIO_LINE:
878 int i = *(int*)arg;
880 if( i < 0 || i >= MXB_AUDIOS ) {
881 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
882 return -EINVAL;
885 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
886 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
887 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
889 return 0;
891 case VIDIOC_G_AUDIO:
893 struct v4l2_audio *a = arg;
895 if( a->index < 0 || a->index > MXB_INPUTS ) {
896 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
897 return -EINVAL;
900 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
901 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
903 return 0;
905 case VIDIOC_S_AUDIO:
907 struct v4l2_audio *a = arg;
908 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
909 return 0;
911 default:
913 DEB2(printk("does not handle this ioctl.\n"));
915 return -ENOIOCTLCMD;
917 return 0;
920 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
922 struct mxb* mxb = (struct mxb*)dev->ext_priv;
923 int zero = 0;
924 int one = 1;
926 if(V4L2_STD_PAL_I == std->id ) {
927 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
928 /* set the 7146 gpio register -- I don't know what this does exactly */
929 saa7146_write(dev, GPIO_CTRL, 0x00404050);
930 /* unset the 7111 gpio register -- I don't know what this does exactly */
931 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
932 } else {
933 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
934 /* set the 7146 gpio register -- I don't know what this does exactly */
935 saa7146_write(dev, GPIO_CTRL, 0x00404050);
936 /* set the 7111 gpio register -- I don't know what this does exactly */
937 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
939 return 0;
942 static struct saa7146_standard standard[] = {
944 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
945 .v_offset = 0x17, .v_field = 288,
946 .h_offset = 0x14, .h_pixels = 680,
947 .v_max_out = 576, .h_max_out = 768,
948 }, {
949 .name = "PAL-I", .id = V4L2_STD_PAL_I,
950 .v_offset = 0x17, .v_field = 288,
951 .h_offset = 0x14, .h_pixels = 680,
952 .v_max_out = 576, .h_max_out = 768,
953 }, {
954 .name = "NTSC", .id = V4L2_STD_NTSC,
955 .v_offset = 0x16, .v_field = 240,
956 .h_offset = 0x06, .h_pixels = 708,
957 .v_max_out = 480, .h_max_out = 640,
958 }, {
959 .name = "SECAM", .id = V4L2_STD_SECAM,
960 .v_offset = 0x14, .v_field = 288,
961 .h_offset = 0x14, .h_pixels = 720,
962 .v_max_out = 576, .h_max_out = 768,
966 static struct saa7146_pci_extension_data mxb = {
967 .ext_priv = "Multimedia eXtension Board",
968 .ext = &extension,
971 static struct pci_device_id pci_tbl[] = {
973 .vendor = PCI_VENDOR_ID_PHILIPS,
974 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
975 .subvendor = 0x0000,
976 .subdevice = 0x0000,
977 .driver_data = (unsigned long)&mxb,
978 }, {
979 .vendor = 0,
983 MODULE_DEVICE_TABLE(pci, pci_tbl);
985 static struct saa7146_ext_vv vv_data = {
986 .inputs = MXB_INPUTS,
987 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
988 .stds = &standard[0],
989 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
990 .std_callback = &std_callback,
991 .ioctls = &ioctls[0],
992 .ioctl = mxb_ioctl,
995 static struct saa7146_extension extension = {
996 .name = MXB_IDENTIFIER,
997 .flags = SAA7146_USE_I2C_IRQ,
999 .pci_tbl = &pci_tbl[0],
1000 .module = THIS_MODULE,
1002 .probe = mxb_probe,
1003 .attach = mxb_attach,
1004 .detach = mxb_detach,
1006 .irq_mask = 0,
1007 .irq_func = NULL,
1010 int __init mxb_init_module(void)
1012 if( 0 != saa7146_register_extension(&extension)) {
1013 DEB_S(("failed to register extension.\n"));
1014 return -ENODEV;
1017 return 0;
1020 void __exit mxb_cleanup_module(void)
1022 saa7146_unregister_extension(&extension);
1025 module_init(mxb_init_module);
1026 module_exit(mxb_cleanup_module);
1028 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1029 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1030 MODULE_LICENSE("GPL");