V4L/DVB (3835): [PATCH] update pwc driver
[linux-2.6] / drivers / media / video / mxb.c
1 /*
2     mxb - v4l2 driver for the Multimedia eXtension Board
3
4     Copyright (C) 1998-2006 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_ADDR_TEA6420_1 == client->addr )
202                         mxb->tea6420_1 = client;
203                 if( I2C_ADDR_TEA6420_2 == client->addr )
204                         mxb->tea6420_2 = client;
205                 if( I2C_TEA6415C_2 == client->addr )
206                         mxb->tea6415c = client;
207                 if( I2C_ADDR_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         v4l2_std_id std = V4L2_STD_PAL_BG;
331
332         int i = 0, err = 0;
333         struct  tea6415c_multiplex vm;
334
335         /* select video mode in saa7111a */
336         i = VIDEO_MODE_PAL;
337         /* fixme: currently pointless: gets overwritten by configuration below */
338         mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
339
340         /* write configuration to saa7111a */
341         init.data = mxb_saa7111_init;
342         init.len = sizeof(mxb_saa7111_init);
343         mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
344
345         /* select tuner-output on saa7111a */
346         i = 0;
347         mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
348
349         /* enable vbi bypass */
350         i = 1;
351         mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
352
353         /* select a tuner type */
354         tun_setup.mode_mask = T_ANALOG_TV;
355         tun_setup.addr = ADDR_UNSET;
356         tun_setup.type = TUNER_PHILIPS_PAL;
357         mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
358         /* tune in some frequency on tuner */
359         mxb->cur_freq.tuner = 0;
360         mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
361         mxb->cur_freq.frequency = freq;
362         mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
363                                         &mxb->cur_freq);
364
365         /* set a default video standard */
366         mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
367
368         /* mute audio on tea6420s */
369         mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
370         mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
371         mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
372         mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
373
374         /* switch to tuner-channel on tea6415c*/
375         vm.out = 17;
376         vm.in  = 3;
377         mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
378
379         /* select tuner-output on multicable on tea6415c*/
380         vm.in  = 3;
381         vm.out = 13;
382         mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
383
384         /* the rest for mxb */
385         mxb->cur_input = 0;
386         mxb->cur_mute = 1;
387
388         mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
389         mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
390
391         /* check if the saa7740 (aka 'sound arena module') is present
392            on the mxb. if so, we must initialize it. due to lack of
393            informations about the saa7740, the values were reverse
394            engineered. */
395         msg.addr = 0x1b;
396         msg.flags = 0;
397         msg.len = mxb_saa7740_init[0].length;
398         msg.buf = &mxb_saa7740_init[0].data[0];
399
400         if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
401                 /* the sound arena module is a pos, that's probably the reason
402                    philips refuses to hand out a datasheet for the saa7740...
403                    it seems to screw up the i2c bus, so we disable fast irq
404                    based i2c transactions here and rely on the slow and safe
405                    polling method ... */
406                 extension.flags &= ~SAA7146_USE_I2C_IRQ;
407                 for(i = 1;;i++) {
408                         if( -1 == mxb_saa7740_init[i].length ) {
409                                 break;
410                         }
411
412                         msg.len = mxb_saa7740_init[i].length;
413                         msg.buf = &mxb_saa7740_init[i].data[0];
414                         if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
415                                 DEB_D(("failed to initialize 'sound arena module'.\n"));
416                                 goto err;
417                         }
418                 }
419                 INFO(("'sound arena module' detected.\n"));
420         }
421 err:
422         /* the rest for saa7146: you should definitely set some basic values
423            for the input-port handling of the saa7146. */
424
425         /* ext->saa has been filled by the core driver */
426
427         /* some stuff is done via variables */
428         saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
429
430         /* some stuff is done via direct write to the registers */
431
432         /* this is ugly, but because of the fact that this is completely
433            hardware dependend, it should be done directly... */
434         saa7146_write(dev, DD1_STREAM_B,        0x00000000);
435         saa7146_write(dev, DD1_INIT,            0x02000200);
436         saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
437
438         return 0;
439 }
440
441 /* interrupt-handler. this gets called when irq_mask is != 0.
442    it must clear the interrupt-bits in irq_mask it has handled */
443 /*
444 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
445 {
446         struct mxb* mxb = (struct mxb*)dev->ext_priv;
447 }
448 */
449
450 static struct saa7146_ext_vv vv_data;
451
452 /* this function only gets called when the probing was successful */
453 static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
454 {
455         struct mxb* mxb = (struct mxb*)dev->ext_priv;
456
457         DEB_EE(("dev:%p\n",dev));
458
459         /* checking for i2c-devices can be omitted here, because we
460            already did this in "mxb_vl42_probe" */
461
462         saa7146_vv_init(dev,&vv_data);
463         if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
464                 ERR(("cannot register capture v4l2 device. skipping.\n"));
465                 return -1;
466         }
467
468         /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
469         if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
470                 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
471                         ERR(("cannot register vbi v4l2 device. skipping.\n"));
472                 }
473         }
474
475         i2c_use_client(mxb->tea6420_1);
476         i2c_use_client(mxb->tea6420_2);
477         i2c_use_client(mxb->tea6415c);
478         i2c_use_client(mxb->tda9840);
479         i2c_use_client(mxb->saa7111a);
480         i2c_use_client(mxb->tuner);
481
482         printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
483
484         mxb_num++;
485         mxb_init_done(dev);
486         return 0;
487 }
488
489 static int mxb_detach(struct saa7146_dev* dev)
490 {
491         struct mxb* mxb = (struct mxb*)dev->ext_priv;
492
493         DEB_EE(("dev:%p\n",dev));
494
495         i2c_release_client(mxb->tea6420_1);
496         i2c_release_client(mxb->tea6420_2);
497         i2c_release_client(mxb->tea6415c);
498         i2c_release_client(mxb->tda9840);
499         i2c_release_client(mxb->saa7111a);
500         i2c_release_client(mxb->tuner);
501
502         saa7146_unregister_device(&mxb->video_dev,dev);
503         if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
504                 saa7146_unregister_device(&mxb->vbi_dev,dev);
505         }
506         saa7146_vv_release(dev);
507
508         mxb_num--;
509
510         i2c_del_adapter(&mxb->i2c_adapter);
511         kfree(mxb);
512
513         return 0;
514 }
515
516 static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
517 {
518         struct saa7146_dev *dev = fh->dev;
519         struct mxb* mxb = (struct mxb*)dev->ext_priv;
520         struct saa7146_vv *vv = dev->vv_data;
521
522         switch(cmd) {
523         case VIDIOC_ENUMINPUT:
524         {
525                 struct v4l2_input *i = arg;
526
527                 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
528                 if( i->index < 0 || i->index >= MXB_INPUTS) {
529                         return -EINVAL;
530                 }
531                 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
532
533                 return 0;
534         }
535         /* the saa7146 provides some controls (brightness, contrast, saturation)
536            which gets registered *after* this function. because of this we have
537            to return with a value != 0 even if the function succeded.. */
538         case VIDIOC_QUERYCTRL:
539         {
540                 struct v4l2_queryctrl *qc = arg;
541                 int i;
542
543                 for (i = MAXCONTROLS - 1; i >= 0; i--) {
544                         if (mxb_controls[i].id == qc->id) {
545                                 *qc = mxb_controls[i];
546                                 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
547                                 return 0;
548                         }
549                 }
550                 return -EAGAIN;
551         }
552         case VIDIOC_G_CTRL:
553         {
554                 struct v4l2_control *vc = arg;
555                 int i;
556
557                 for (i = MAXCONTROLS - 1; i >= 0; i--) {
558                         if (mxb_controls[i].id == vc->id) {
559                                 break;
560                         }
561                 }
562
563                 if( i < 0 ) {
564                         return -EAGAIN;
565                 }
566
567                 switch (vc->id ) {
568                         case V4L2_CID_AUDIO_MUTE: {
569                                 vc->value = mxb->cur_mute;
570                                 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
571                                 return 0;
572                         }
573                 }
574
575                 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
576                 return 0;
577         }
578
579         case VIDIOC_S_CTRL:
580         {
581                 struct  v4l2_control    *vc = arg;
582                 int i = 0;
583
584                 for (i = MAXCONTROLS - 1; i >= 0; i--) {
585                         if (mxb_controls[i].id == vc->id) {
586                                 break;
587                         }
588                 }
589
590                 if( i < 0 ) {
591                         return -EAGAIN;
592                 }
593
594                 switch (vc->id ) {
595                         case V4L2_CID_AUDIO_MUTE: {
596                                 mxb->cur_mute = vc->value;
597                                 if( 0 == vc->value ) {
598                                         /* switch the audio-source */
599                                         mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
600                                         mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
601                                 } else {
602                                         mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
603                                         mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
604                                 }
605                                 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
606                                 break;
607                         }
608                 }
609                 return 0;
610         }
611         case VIDIOC_G_INPUT:
612         {
613                 int *input = (int *)arg;
614                 *input = mxb->cur_input;
615
616                 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
617                 return 0;
618         }
619         case VIDIOC_S_INPUT:
620         {
621                 int input = *(int *)arg;
622                 struct  tea6415c_multiplex vm;
623                 int i = 0;
624
625                 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
626
627                 if (input < 0 || input >= MXB_INPUTS) {
628                         return -EINVAL;
629                 }
630
631                 /* fixme: locke das setzen des inputs mit hilfe des mutexes
632                 mutex_lock(&dev->lock);
633                 video_mux(dev,*i);
634                 mutex_unlock(&dev->lock);
635                 */
636
637                 /* fixme: check if streaming capture
638                 if ( 0 != dev->streaming ) {
639                         DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
640                         return -EPERM;
641                 }
642                 */
643
644                 mxb->cur_input = input;
645
646                 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
647
648                 /* prepare switching of tea6415c and saa7111a;
649                    have a look at the 'background'-file for further informations  */
650                 switch( input ) {
651
652                         case TUNER:
653                         {
654                                 i = 0;
655                                 vm.in  = 3;
656                                 vm.out = 17;
657
658                         if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
659                                         printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
660                                         return -EFAULT;
661                                 }
662                                 /* connect tuner-output always to multicable */
663                                 vm.in  = 3;
664                                 vm.out = 13;
665                                 break;
666                         }
667                         case AUX3_YC:
668                         {
669                                 /* nothing to be done here. aux3_yc is
670                                    directly connected to the saa711a */
671                                 i = 5;
672                                 break;
673                         }
674                         case AUX3:
675                         {
676                                 /* nothing to be done here. aux3 is
677                                    directly connected to the saa711a */
678                                 i = 1;
679                                 break;
680                         }
681                         case AUX1:
682                         {
683                                 i = 0;
684                                 vm.in  = 1;
685                                 vm.out = 17;
686                                 break;
687                         }
688                 }
689
690                 /* switch video in tea6415c only if necessary */
691                 switch( input ) {
692                         case TUNER:
693                         case AUX1:
694                         {
695                                 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
696                                         printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
697                                         return -EFAULT;
698                                 }
699                                 break;
700                         }
701                         default:
702                         {
703                                 break;
704                         }
705                 }
706
707                 /* switch video in saa7111a */
708                 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
709                         printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
710                 }
711
712                 /* switch the audio-source only if necessary */
713                 if( 0 == mxb->cur_mute ) {
714                         mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
715                         mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
716                 }
717
718                 return 0;
719         }
720         case VIDIOC_G_TUNER:
721         {
722                 struct v4l2_tuner *t = arg;
723                 int byte = 0;
724
725                 if( 0 != t->index ) {
726                         DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
727                         return -EINVAL;
728                 }
729
730                 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
731
732                 memset(t,0,sizeof(*t));
733                 strcpy(t->name, "Television");
734
735                 t->type = V4L2_TUNER_ANALOG_TV;
736                 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
737                 t->rangelow = 772;      /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
738                 t->rangehigh = 13684;   /* 855.25 MHz / 62.5 kHz = 13684 */
739                 /* FIXME: add the real signal strength here */
740                 t->signal = 0xffff;
741                 t->afc = 0;
742
743                 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
744                 t->audmode = mxb->cur_mode;
745
746                 if( byte < 0 ) {
747                         t->rxsubchans  = V4L2_TUNER_SUB_MONO;
748                 } else {
749                         switch(byte) {
750                                 case TDA9840_MONO_DETECT: {
751                                         t->rxsubchans   = V4L2_TUNER_SUB_MONO;
752                                         DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
753                                         break;
754                                 }
755                                 case TDA9840_DUAL_DETECT: {
756                                         t->rxsubchans   = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
757                                         DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
758                                         break;
759                                 }
760                                 case TDA9840_STEREO_DETECT: {
761                                         t->rxsubchans   = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
762                                         DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
763                                         break;
764                                 }
765                                 default: { /* TDA9840_INCORRECT_DETECT */
766                                         t->rxsubchans   = V4L2_TUNER_MODE_MONO;
767                                         DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
768                                         break;
769                                 }
770                         }
771                 }
772
773                 return 0;
774         }
775         case VIDIOC_S_TUNER:
776         {
777                 struct v4l2_tuner *t = arg;
778                 int result = 0;
779                 int byte = 0;
780
781                 if( 0 != t->index ) {
782                         DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
783                         return -EINVAL;
784                 }
785
786                 switch(t->audmode) {
787                         case V4L2_TUNER_MODE_STEREO: {
788                                 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
789                                 byte = TDA9840_SET_STEREO;
790                                 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
791                                 break;
792                         }
793                         case V4L2_TUNER_MODE_LANG1_LANG2: {
794                                 mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2;
795                                 byte = TDA9840_SET_BOTH;
796                                 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"));
797                                 break;
798                         }
799                         case V4L2_TUNER_MODE_LANG1: {
800                                 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
801                                 byte = TDA9840_SET_LANG1;
802                                 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
803                                 break;
804                         }
805                         case V4L2_TUNER_MODE_LANG2: {
806                                 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
807                                 byte = TDA9840_SET_LANG2;
808                                 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
809                                 break;
810                         }
811                         default: { /* case V4L2_TUNER_MODE_MONO: {*/
812                                 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
813                                 byte = TDA9840_SET_MONO;
814                                 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
815                                 break;
816                         }
817                 }
818
819                 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
820                         printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
821                 }
822
823                 return 0;
824         }
825         case VIDIOC_G_FREQUENCY:
826         {
827                 struct v4l2_frequency *f = arg;
828
829                 if(0 != mxb->cur_input) {
830                         DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
831                         return -EINVAL;
832                 }
833
834                 *f = mxb->cur_freq;
835
836                 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
837                 return 0;
838         }
839         case VIDIOC_S_FREQUENCY:
840         {
841                 struct v4l2_frequency *f = arg;
842
843                 if (0 != f->tuner)
844                         return -EINVAL;
845
846                 if (V4L2_TUNER_ANALOG_TV != f->type)
847                         return -EINVAL;
848
849                 if(0 != mxb->cur_input) {
850                         DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
851                         return -EINVAL;
852                 }
853
854                 mxb->cur_freq = *f;
855                 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
856
857                 /* tune in desired frequency */
858                 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
859
860                 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
861                 spin_lock(&dev->slock);
862                 vv->vbi_fieldcount = 0;
863                 spin_unlock(&dev->slock);
864
865                 return 0;
866         }
867         case MXB_S_AUDIO_CD:
868         {
869                 int i = *(int*)arg;
870
871                 if( i < 0 || i >= MXB_AUDIOS ) {
872                         DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
873                         return -EINVAL;
874                 }
875
876                 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
877
878                 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
879                 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
880
881                 return 0;
882         }
883         case MXB_S_AUDIO_LINE:
884         {
885                 int i = *(int*)arg;
886
887                 if( i < 0 || i >= MXB_AUDIOS ) {
888                         DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
889                         return -EINVAL;
890                 }
891
892                 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
893                 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
894                 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
895
896                 return 0;
897         }
898         case VIDIOC_G_AUDIO:
899         {
900                 struct v4l2_audio *a = arg;
901
902                 if( a->index < 0 || a->index > MXB_INPUTS ) {
903                         DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
904                         return -EINVAL;
905                 }
906
907                 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
908                 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
909
910                 return 0;
911         }
912         case VIDIOC_S_AUDIO:
913         {
914                 struct v4l2_audio *a = arg;
915                 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
916                 return 0;
917         }
918         default:
919 /*
920                 DEB2(printk("does not handle this ioctl.\n"));
921 */
922                 return -ENOIOCTLCMD;
923         }
924         return 0;
925 }
926
927 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
928 {
929         struct mxb* mxb = (struct mxb*)dev->ext_priv;
930         int zero = 0;
931         int one = 1;
932
933         if(V4L2_STD_PAL_I == std->id ) {
934                 v4l2_std_id std = V4L2_STD_PAL_I;
935                 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
936                 /* set the 7146 gpio register -- I don't know what this does exactly */
937                 saa7146_write(dev, GPIO_CTRL, 0x00404050);
938                 /* unset the 7111 gpio register -- I don't know what this does exactly */
939                 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
940                 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
941         } else {
942                 v4l2_std_id std = V4L2_STD_PAL_BG;
943                 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
944                 /* set the 7146 gpio register -- I don't know what this does exactly */
945                 saa7146_write(dev, GPIO_CTRL, 0x00404050);
946                 /* set the 7111 gpio register -- I don't know what this does exactly */
947                 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
948                 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
949         }
950         return 0;
951 }
952
953 static struct saa7146_standard standard[] = {
954         {
955                 .name   = "PAL-BG",     .id     = V4L2_STD_PAL_BG,
956                 .v_offset       = 0x17, .v_field        = 288,
957                 .h_offset       = 0x14, .h_pixels       = 680,
958                 .v_max_out      = 576,  .h_max_out      = 768,
959         }, {
960                 .name   = "PAL-I",      .id     = V4L2_STD_PAL_I,
961                 .v_offset       = 0x17, .v_field        = 288,
962                 .h_offset       = 0x14, .h_pixels       = 680,
963                 .v_max_out      = 576,  .h_max_out      = 768,
964         }, {
965                 .name   = "NTSC",       .id     = V4L2_STD_NTSC,
966                 .v_offset       = 0x16, .v_field        = 240,
967                 .h_offset       = 0x06, .h_pixels       = 708,
968                 .v_max_out      = 480,  .h_max_out      = 640,
969         }, {
970                 .name   = "SECAM",      .id     = V4L2_STD_SECAM,
971                 .v_offset       = 0x14, .v_field        = 288,
972                 .h_offset       = 0x14, .h_pixels       = 720,
973                 .v_max_out      = 576,  .h_max_out      = 768,
974         }
975 };
976
977 static struct saa7146_pci_extension_data mxb = {
978         .ext_priv = "Multimedia eXtension Board",
979         .ext = &extension,
980 };
981
982 static struct pci_device_id pci_tbl[] = {
983         {
984                 .vendor    = PCI_VENDOR_ID_PHILIPS,
985                 .device    = PCI_DEVICE_ID_PHILIPS_SAA7146,
986                 .subvendor = 0x0000,
987                 .subdevice = 0x0000,
988                 .driver_data = (unsigned long)&mxb,
989         }, {
990                 .vendor = 0,
991         }
992 };
993
994 MODULE_DEVICE_TABLE(pci, pci_tbl);
995
996 static struct saa7146_ext_vv vv_data = {
997         .inputs         = MXB_INPUTS,
998         .capabilities   = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
999         .stds           = &standard[0],
1000         .num_stds       = sizeof(standard)/sizeof(struct saa7146_standard),
1001         .std_callback   = &std_callback,
1002         .ioctls         = &ioctls[0],
1003         .ioctl          = mxb_ioctl,
1004 };
1005
1006 static struct saa7146_extension extension = {
1007         .name           = MXB_IDENTIFIER,
1008         .flags          = SAA7146_USE_I2C_IRQ,
1009
1010         .pci_tbl        = &pci_tbl[0],
1011         .module         = THIS_MODULE,
1012
1013         .probe          = mxb_probe,
1014         .attach         = mxb_attach,
1015         .detach         = mxb_detach,
1016
1017         .irq_mask       = 0,
1018         .irq_func       = NULL,
1019 };
1020
1021 static int __init mxb_init_module(void)
1022 {
1023         if( 0 != saa7146_register_extension(&extension)) {
1024                 DEB_S(("failed to register extension.\n"));
1025                 return -ENODEV;
1026         }
1027
1028         return 0;
1029 }
1030
1031 static void __exit mxb_cleanup_module(void)
1032 {
1033         saa7146_unregister_extension(&extension);
1034 }
1035
1036 module_init(mxb_init_module);
1037 module_exit(mxb_cleanup_module);
1038
1039 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1040 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1041 MODULE_LICENSE("GPL");