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