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