patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / drivers / media / video / mxb.c
1 /*
2     mxb.c - v4l2 driver for the Multimedia eXtension Board
3     
4     Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6     Visit http://www.mihu.de/linux/saa7146/mxb/
7     for further details about this card.
8     
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.
13
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.
18
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.
22 */
23
24 #define DEBUG_VARIABLE debug
25
26 #include <media/saa7146_vv.h>
27 #include <media/tuner.h>
28 #include <linux/video_decoder.h>
29
30 #include "mxb.h"
31 #include "tea6415c.h"
32 #include "tea6420.h"
33 #include "tda9840.h"
34
35 #define I2C_SAA7111 0x24
36
37 #define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0) 
38
39 /* global variable */
40 static int mxb_num = 0;
41
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");
48
49 static int debug = 0;
50 MODULE_PARM(debug,"i");
51 MODULE_PARM_DESC(debug, "debug verbosity");
52
53 #define MXB_INPUTS 4
54 enum { TUNER, AUX1, AUX3, AUX3_YC };
55
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 },
61 };
62
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 },
73 };
74
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 };
79
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] =
83                 { 
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 */
91                 };
92
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] =
96                 {
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 */
104                 };
105
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 },
109 };
110
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 }
127 };
128
129 struct mxb
130 {
131         struct video_device     video_dev;
132         struct video_device     vbi_dev;
133
134         struct i2c_adapter      i2c_adapter;    
135
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;
142
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 */
147 };
148
149 static struct saa7146_extension extension;
150
151 static int mxb_probe(struct saa7146_dev* dev)
152 {
153         struct mxb* mxb = 0;
154         struct i2c_client *client;
155         struct list_head *item;
156         int result;
157
158         if ((result = request_module("saa7111")) < 0) {
159                 printk("mxb: saa7111 i2c module not available.\n");
160                 return -ENODEV;
161         }
162         if ((result = request_module("tuner")) < 0) {
163                 printk("mxb: tuner i2c module not available.\n");
164                 return -ENODEV;
165         }
166         if ((result = request_module("tea6420")) < 0) {
167                 printk("mxb: tea6420 i2c module not available.\n");
168                 return -ENODEV;
169         }
170         if ((result = request_module("tea6415c")) < 0) {
171                 printk("mxb: tea6415c i2c module not available.\n");
172                 return -ENODEV;
173         }
174         if ((result = request_module("tda9840")) < 0) {
175                 printk("mxb: tda9840 i2c module not available.\n");
176                 return -ENODEV;
177         }
178
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;
183         }
184         memset(mxb, 0x0, sizeof(struct mxb));   
185
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;
191         }
192
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;
208         }
209
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 ) {
213
214                 printk("mxb: did not find all i2c devices. aborting\n");
215                 i2c_del_adapter(&mxb->i2c_adapter);
216                 kfree(mxb);
217                 return -ENODEV;
218         }
219
220         /* all devices are present, probe was successful */     
221
222         /* we store the pointer in our private data field */
223         dev->ext_priv = mxb;
224
225         return 0;
226 }
227
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} }
282 };
283
284 static const unsigned char mxb_saa7111_init[] = {
285         0x00, 0x00,       /* 00 - ID byte */
286         0x01, 0x00,       /* 01 - reserved */
287
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 */
293
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 */
313 };
314
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)
320 {
321         struct mxb* mxb = (struct mxb*)dev->ext_priv;
322         struct video_decoder_init init;
323         struct i2c_msg msg;
324
325         int i = 0, err = 0;
326         struct  tea6415c_multiplex vm;  
327
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);
332
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);
337
338         /* select tuner-output on saa7111a */
339         i = 0;
340         mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
341
342         /* enable vbi bypass */
343         i = 1;
344         mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
345
346         /* select a tuner type */
347         i = 5; 
348         mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE, &i);
349         
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]);
355
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);
360
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);
365                                 
366         /* tune in some frequency on tuner */
367         mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &freq);
368
369         /* the rest for mxb */
370         mxb->cur_input = 0;
371         mxb->cur_freq = freq;
372         mxb->cur_mute = 1;
373
374         mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
375         mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
376                         
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];
385
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;
396                         }
397
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;
403                         }
404                 }
405                 INFO(("'sound arena module' detected.\n"));
406         }
407 err:    
408         /* the rest for saa7146: you should definitely set some basic values
409            for the input-port handling of the saa7146. */
410
411         /* ext->saa has been filled by the core driver */
412            
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);
415
416         /* some stuff is done via direct write to the registers */
417
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));
423
424         return 0;
425 }
426
427 /* interrupt-handler. this gets called when irq_mask is != 0.
428    it must clear the interrupt-bits in irq_mask it has handled */
429 /*
430 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
431 {
432         struct mxb* mxb = (struct mxb*)dev->ext_priv;
433 }
434 */
435
436 static struct saa7146_ext_vv vv_data;
437
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)
440 {
441         struct mxb* mxb = (struct mxb*)dev->ext_priv;
442         
443         DEB_EE(("dev:%p\n",dev));
444
445         /* checking for i2c-devices can be omitted here, because we
446            already did this in "mxb_vl42_probe" */
447
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;
452         }
453         
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"));
458                 }
459         }
460
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);
467
468         printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
469
470         mxb_num++;
471         mxb_init_done(dev);
472         return 0;
473 }
474
475 static int mxb_detach(struct saa7146_dev* dev)
476 {
477         struct mxb* mxb = (struct mxb*)dev->ext_priv;
478
479         DEB_EE(("dev:%p\n",dev));
480
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);
487
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);
491         }
492         saa7146_vv_release(dev);
493
494         mxb_num--;
495
496         i2c_del_adapter(&mxb->i2c_adapter);
497         kfree(mxb);
498
499         return 0;
500 }
501
502 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
503 {
504         struct saa7146_dev *dev = fh->dev;
505         struct mxb* mxb = (struct mxb*)dev->ext_priv;
506         struct saa7146_vv *vv = dev->vv_data; 
507         
508         switch(cmd) {
509         case VIDIOC_ENUMINPUT:
510         {
511                 struct v4l2_input *i = arg;
512                 
513                 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
514                 if( i->index < 0 || i->index >= MXB_INPUTS) {
515                         return -EINVAL;
516                 }
517                 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
518
519                 return 0;
520         }
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:
525         {
526                 struct v4l2_queryctrl *qc = arg;
527                 int i;
528
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;
534                         }
535                 }
536                 return -EAGAIN;
537         }
538         case VIDIOC_G_CTRL:
539         {
540                 struct v4l2_control *vc = arg;
541                 int i;
542
543                 for (i = MAXCONTROLS - 1; i >= 0; i--) {
544                         if (mxb_controls[i].id == vc->id) {
545                                 break;
546                         }
547                 }
548                 
549                 if( i < 0 ) {
550                         return -EAGAIN;
551                 }
552                         
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;
558                         }
559                 }
560                 
561                 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
562                 return 0;
563         }
564
565         case VIDIOC_S_CTRL:
566         {
567                 struct  v4l2_control    *vc = arg;
568                 int i = 0;
569                 
570                 for (i = MAXCONTROLS - 1; i >= 0; i--) {
571                         if (mxb_controls[i].id == vc->id) {
572                                 break;
573                         }
574                 }
575                 
576                 if( i < 0 ) {
577                         return -EAGAIN;
578                 }
579                 
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]);
590                                 }
591                                 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
592                                 break;
593                         }
594                 }
595                 return 0;
596         }
597         case VIDIOC_G_INPUT:
598         {
599                 int *input = (int *)arg;
600                 *input = mxb->cur_input;
601
602                 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
603                 return 0;               
604         }       
605         case VIDIOC_S_INPUT:
606         {
607                 int input = *(int *)arg;
608                 struct  tea6415c_multiplex vm;  
609                 int i = 0;
610
611                 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
612
613                 if (input < 0 || input >= MXB_INPUTS) {
614                         return -EINVAL;
615                 }
616                 
617                 /* fixme: locke das setzen des inputs mit hilfe des mutexes
618                 down(&dev->lock);
619                 video_mux(dev,*i);
620                 up(&dev->lock);
621                 */
622                                 
623                 /* fixme: check if streaming capture
624                 if ( 0 != dev->streaming ) {
625                         DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
626                         return -EPERM;
627                 }
628                 */
629                 
630                 mxb->cur_input = input;
631         
632                 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
633                 
634                 /* prepare switching of tea6415c and saa7111a;
635                    have a look at the 'background'-file for further informations  */
636                 switch( input ) {
637                         
638                         case TUNER:
639                         {
640                                 i = 0;
641                                 vm.in  = 3;
642                                 vm.out = 17;
643                                                                 
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;
647                                 }
648                                 /* connect tuner-output always to multicable */
649                                 vm.in  = 3;
650                                 vm.out = 13;
651                                 break;                          
652                         }
653                         case AUX3_YC:
654                         {
655                                 /* nothing to be done here. aux3_yc is
656                                    directly connected to the saa711a */
657                                 i = 5;
658                                 break;
659                         }
660                         case AUX3:
661                         {
662                                 /* nothing to be done here. aux3 is
663                                    directly connected to the saa711a */
664                                 i = 1;
665                                 break;
666                         }
667                         case AUX1:
668                         {
669                                 i = 0;
670                                 vm.in  = 1;
671                                 vm.out = 17;
672                                 break;
673                         }
674                 }
675
676                 /* switch video in tea6415c only if necessary */
677                 switch( input ) {
678                         case TUNER:
679                         case AUX1:
680                         {
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;
684                                 }
685                                 break;
686                         }
687                         default:
688                         {
689                                 break;
690                         }
691                 }
692                                 
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");
696                 }                       
697
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]);
702                 }
703
704                 return 0;
705         }
706         case VIDIOC_G_TUNER:
707         {
708                 struct v4l2_tuner *t = arg;
709                 int byte = 0;
710
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;
714                 }
715
716                 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
717
718                 memset(t,0,sizeof(*t));
719                 strcpy(t->name, "Television");
720
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;             
728
729                 byte = mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, NULL);
730                 t->audmode = mxb->cur_mode;
731                 
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;
740                                 }
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;
745                                 }
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;
750                                 }
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;
755                                 }
756                         }
757                 }
758
759                 return 0;
760         }
761         case VIDIOC_S_TUNER:
762         {
763                 struct v4l2_tuner *t = arg;
764                 int result = 0;
765                 int byte = 0;
766                 
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;
770                 }
771         
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;
778                         }
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;
784                         }
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;
790                         }
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;
796                         }
797                 }
798
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);
801                 }
802                                 
803                 return 0;
804         }
805         case VIDIOC_G_FREQUENCY:
806         {
807                 struct v4l2_frequency *f = arg;
808
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;
812                 }
813
814                 memset(f,0,sizeof(*f));
815                 f->type = V4L2_TUNER_ANALOG_TV;
816                 f->frequency =  mxb->cur_freq;
817
818                 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq));
819                 return 0;
820         }
821         case VIDIOC_S_FREQUENCY:
822         {
823                 struct v4l2_frequency *f = arg;
824                 int t_locked = 0;
825                 int v_byte = 0;
826
827                 if (0 != f->tuner)
828                         return -EINVAL;
829
830                 if (V4L2_TUNER_ANALOG_TV != f->type)
831                         return -EINVAL;
832                 
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;
836                 }
837
838                 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
839
840                 mxb->cur_freq = f->frequency;
841
842                 /* tune in desired frequency */                 
843                 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &mxb->cur_freq);
844
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);
848
849                 /* not locked -- anything to do here ? */
850                 if( 0 == t_locked || 0 == (v_byte & DECODER_STATUS_GOOD)) {
851                 }
852
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);
857
858                 return 0;
859         }
860         case MXB_S_AUDIO_CD:
861         {
862                 int i = *(int*)arg;
863                                 
864                 if( i < 0 || i >= MXB_AUDIOS ) {
865                         DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
866                         return -EINVAL;
867                 }
868                 
869                 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
870
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]);
873
874                 return 0;
875         }
876         case MXB_S_AUDIO_LINE:
877         {
878                 int i = *(int*)arg;
879                                 
880                 if( i < 0 || i >= MXB_AUDIOS ) {
881                         DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
882                         return -EINVAL;
883                 }
884                 
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]);
888
889                 return 0;
890         }
891         case VIDIOC_G_AUDIO:
892         {
893                 struct v4l2_audio *a = arg;
894
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;
898                 }
899                 
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));
902                 
903                 return 0;
904         }
905         case VIDIOC_S_AUDIO:
906         {
907                 struct v4l2_audio *a = arg;
908                 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
909                 return 0;
910         }       
911         default:
912 /*
913                 DEB2(printk("does not handle this ioctl.\n"));
914 */
915                 return -ENOIOCTLCMD;
916         }
917         return 0;
918 }
919
920 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
921 {
922         struct mxb* mxb = (struct mxb*)dev->ext_priv;
923         int zero = 0;
924         int one = 1;
925
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);
938         }
939         return 0;
940 }
941
942 static struct saa7146_standard standard[] = {
943         {
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,
963         }
964 };
965
966 static struct saa7146_pci_extension_data mxb = {
967         .ext_priv = "Multimedia eXtension Board",
968         .ext = &extension,
969 };
970
971 static struct pci_device_id pci_tbl[] = {
972         {
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,
980         }
981 };
982
983 MODULE_DEVICE_TABLE(pci, pci_tbl);
984
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,
993 };
994
995 static struct saa7146_extension extension = {
996         .name           = MXB_IDENTIFIER,
997         .flags          = SAA7146_USE_I2C_IRQ,
998         
999         .pci_tbl        = &pci_tbl[0],
1000         .module         = THIS_MODULE,
1001
1002         .probe          = mxb_probe,
1003         .attach         = mxb_attach,
1004         .detach         = mxb_detach,
1005
1006         .irq_mask       = 0,
1007         .irq_func       = NULL,
1008 };      
1009
1010 int __init mxb_init_module(void) 
1011 {
1012         if( 0 != saa7146_register_extension(&extension)) {
1013                 DEB_S(("failed to register extension.\n"));
1014                 return -ENODEV;
1015         }
1016         
1017         return 0;
1018 }
1019
1020 void __exit mxb_cleanup_module(void) 
1021 {
1022         saa7146_unregister_extension(&extension);
1023 }
1024
1025 module_init(mxb_init_module);
1026 module_exit(mxb_cleanup_module);
1027
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");