Merge branch 'r8169-for-jeff-20070806' of git://electric-eye.fr.zoreil.com/home/romie...
[linux-2.6] / drivers / media / dvb / dvb-usb / m920x.c
1 /* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver
2  *
3  * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
4  *
5  *      This program is free software; you can redistribute it and/or modify it
6  *      under the terms of the GNU General Public License as published by the
7  *      Free Software Foundation, version 2.
8  *
9  * see Documentation/dvb/README.dvb-usb for more information
10  */
11
12 #include "m920x.h"
13
14 #include "mt352.h"
15 #include "mt352_priv.h"
16 #include "qt1010.h"
17 #include "tda1004x.h"
18 #include "tda827x.h"
19
20 /* debug */
21 static int dvb_usb_m920x_debug;
22 module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
23 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
24
25 static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
26
27 static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
28                              u16 index, void *data, int size)
29 {
30         int ret;
31
32         ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
33                               request, USB_TYPE_VENDOR | USB_DIR_IN,
34                               value, index, data, size, 2000);
35         if (ret < 0) {
36                 printk(KERN_INFO "m920x_read = error: %d\n", ret);
37                 return ret;
38         }
39
40         if (ret != size) {
41                 deb("m920x_read = no data\n");
42                 return -EIO;
43         }
44
45         return 0;
46 }
47
48 static inline int m920x_write(struct usb_device *udev, u8 request,
49                               u16 value, u16 index)
50 {
51         int ret;
52
53         ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
54                               request, USB_TYPE_VENDOR | USB_DIR_OUT,
55                               value, index, NULL, 0, 2000);
56
57         return ret;
58 }
59
60 static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
61 {
62         int ret = 0, i, epi, flags = 0;
63         int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
64
65         /* Remote controller init. */
66         if (d->props.rc_query) {
67                 deb("Initialising remote control\n");
68                 while (rc_seq->address) {
69                         if ((ret = m920x_write(d->udev, M9206_CORE,
70                                                rc_seq->data,
71                                                rc_seq->address)) != 0) {
72                                 deb("Initialising remote control failed\n");
73                                 return ret;
74                         }
75
76                         rc_seq++;
77                 }
78
79                 deb("Initialising remote control success\n");
80         }
81
82         for (i = 0; i < d->props.num_adapters; i++)
83                 flags |= d->adapter[i].props.caps;
84
85         /* Some devices(Dposh) might crash if we attempt touch at all. */
86         if (flags & DVB_USB_ADAP_HAS_PID_FILTER) {
87                 for (i = 0; i < d->props.num_adapters; i++) {
88                         epi = d->adapter[i].props.stream.endpoint - 0x81;
89
90                         if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
91                                 printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
92                                 return -EINVAL;
93                         }
94
95                         adap_enabled[epi] = 1;
96                 }
97
98                 for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
99                         if (adap_enabled[i])
100                                 continue;
101
102                         if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
103                                 return ret;
104
105                         if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
106                                 return ret;
107                 }
108         }
109
110         return ret;
111 }
112
113 static int m920x_init_ep(struct usb_interface *intf)
114 {
115         struct usb_device *udev = interface_to_usbdev(intf);
116         struct usb_host_interface *alt;
117
118         if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) {
119                 deb("No alt found!\n");
120                 return -ENODEV;
121         }
122
123         return usb_set_interface(udev, alt->desc.bInterfaceNumber,
124                                  alt->desc.bAlternateSetting);
125 }
126
127 static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
128 {
129         struct m920x_state *m = d->priv;
130         int i, ret = 0;
131         u8 rc_state[2];
132
133         if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
134                 goto unlock;
135
136         if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
137                 goto unlock;
138
139         for (i = 0; i < d->props.rc_key_map_size; i++)
140                 if (d->props.rc_key_map[i].data == rc_state[1]) {
141                         *event = d->props.rc_key_map[i].event;
142
143                         switch(rc_state[0]) {
144                         case 0x80:
145                                 *state = REMOTE_NO_KEY_PRESSED;
146                                 goto unlock;
147
148                         case 0x88: /* framing error or "invalid code" */
149                         case 0x99:
150                         case 0xc0:
151                         case 0xd8:
152                                 *state = REMOTE_NO_KEY_PRESSED;
153                                 m->rep_count = 0;
154                                 goto unlock;
155
156                         case 0x93:
157                         case 0x92:
158                                 m->rep_count = 0;
159                                 *state = REMOTE_KEY_PRESSED;
160                                 goto unlock;
161
162                         case 0x91:
163                                 /* prevent immediate auto-repeat */
164                                 if (++m->rep_count > 2)
165                                         *state = REMOTE_KEY_REPEAT;
166                                 else
167                                         *state = REMOTE_NO_KEY_PRESSED;
168                                 goto unlock;
169
170                         default:
171                                 deb("Unexpected rc state %02x\n", rc_state[0]);
172                                 *state = REMOTE_NO_KEY_PRESSED;
173                                 goto unlock;
174                         }
175                 }
176
177         if (rc_state[1] != 0)
178                 deb("Unknown rc key %02x\n", rc_state[1]);
179
180         *state = REMOTE_NO_KEY_PRESSED;
181
182  unlock:
183
184         return ret;
185 }
186
187 /* I2C */
188 static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
189 {
190         struct dvb_usb_device *d = i2c_get_adapdata(adap);
191         int i, j;
192         int ret = 0;
193
194         if (!num)
195                 return -EINVAL;
196
197         if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
198                 return -EAGAIN;
199
200         for (i = 0; i < num; i++) {
201                 if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
202                         /* For a 0 byte message, I think sending the address
203                          * to index 0x80|0x40 would be the correct thing to
204                          * do.  However, zero byte messages are only used for
205                          * probing, and since we don't know how to get the
206                          * slave's ack, we can't probe. */
207                         ret = -ENOTSUPP;
208                         goto unlock;
209                 }
210                 /* Send START & address/RW bit */
211                 if (!(msg[i].flags & I2C_M_NOSTART)) {
212                         if ((ret = m920x_write(d->udev, M9206_I2C,
213                                         (msg[i].addr << 1) |
214                                         (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
215                                 goto unlock;
216                         /* Should check for ack here, if we knew how. */
217                 }
218                 if (msg[i].flags & I2C_M_RD) {
219                         for (j = 0; j < msg[i].len; j++) {
220                                 /* Last byte of transaction?
221                                  * Send STOP, otherwise send ACK. */
222                                 int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
223
224                                 if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
225                                                       0x20 | stop,
226                                                       &msg[i].buf[j], 1)) != 0)
227                                         goto unlock;
228                         }
229                 } else {
230                         for (j = 0; j < msg[i].len; j++) {
231                                 /* Last byte of transaction? Then send STOP. */
232                                 int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
233
234                                 if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
235                                         goto unlock;
236                                 /* Should check for ack here too. */
237                         }
238                 }
239         }
240         ret = num;
241
242  unlock:
243         mutex_unlock(&d->i2c_mutex);
244
245         return ret;
246 }
247
248 static u32 m920x_i2c_func(struct i2c_adapter *adapter)
249 {
250         return I2C_FUNC_I2C;
251 }
252
253 static struct i2c_algorithm m920x_i2c_algo = {
254         .master_xfer   = m920x_i2c_xfer,
255         .functionality = m920x_i2c_func,
256 };
257
258 /* pid filter */
259 static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
260 {
261         int ret = 0;
262
263         if (pid >= 0x8000)
264                 return -EINVAL;
265
266         pid |= 0x8000;
267
268         if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
269                 return ret;
270
271         if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
272                 return ret;
273
274         return ret;
275 }
276
277 static int m920x_update_filters(struct dvb_usb_adapter *adap)
278 {
279         struct m920x_state *m = adap->dev->priv;
280         int enabled = m->filtering_enabled[adap->id];
281         int i, ret = 0, filter = 0;
282         int ep = adap->props.stream.endpoint;
283
284         for (i = 0; i < M9206_MAX_FILTERS; i++)
285                 if (m->filters[adap->id][i] == 8192)
286                         enabled = 0;
287
288         /* Disable all filters */
289         if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
290                 return ret;
291
292         for (i = 0; i < M9206_MAX_FILTERS; i++)
293                 if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
294                         return ret;
295
296         /* Set */
297         if (enabled) {
298                 for (i = 0; i < M9206_MAX_FILTERS; i++) {
299                         if (m->filters[adap->id][i] == 0)
300                                 continue;
301
302                         if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
303                                 return ret;
304
305                         filter++;
306                 }
307         }
308
309         return ret;
310 }
311
312 static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
313 {
314         struct m920x_state *m = adap->dev->priv;
315
316         m->filtering_enabled[adap->id] = onoff ? 1 : 0;
317
318         return m920x_update_filters(adap);
319 }
320
321 static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
322 {
323         struct m920x_state *m = adap->dev->priv;
324
325         m->filters[adap->id][index] = onoff ? pid : 0;
326
327         return m920x_update_filters(adap);
328 }
329
330 static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
331 {
332         u16 value, index, size;
333         u8 read[4], *buff;
334         int i, pass, ret = 0;
335
336         buff = kmalloc(65536, GFP_KERNEL);
337
338         if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
339                 goto done;
340         deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
341
342         if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
343                 goto done;
344         deb("%x\n", read[0]);
345
346         for (pass = 0; pass < 2; pass++) {
347                 for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
348                         value = le16_to_cpu(*(u16 *)(fw->data + i));
349                         i += sizeof(u16);
350
351                         index = le16_to_cpu(*(u16 *)(fw->data + i));
352                         i += sizeof(u16);
353
354                         size = le16_to_cpu(*(u16 *)(fw->data + i));
355                         i += sizeof(u16);
356
357                         if (pass == 1) {
358                                 /* Will stall if using fw->data ... */
359                                 memcpy(buff, fw->data + i, size);
360
361                                 ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
362                                                       M9206_FW,
363                                                       USB_TYPE_VENDOR | USB_DIR_OUT,
364                                                       value, index, buff, size, 20);
365                                 if (ret != size) {
366                                         deb("error while uploading fw!\n");
367                                         ret = -EIO;
368                                         goto done;
369                                 }
370                                 msleep(3);
371                         }
372                         i += size;
373                 }
374                 if (i != fw->size) {
375                         deb("bad firmware file!\n");
376                         ret = -EINVAL;
377                         goto done;
378                 }
379         }
380
381         msleep(36);
382
383         /* m920x will disconnect itself from the bus after this. */
384         (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
385         deb("firmware uploaded!\n");
386
387  done:
388         kfree(buff);
389
390         return ret;
391 }
392
393 /* Callbacks for DVB USB */
394 static int m920x_identify_state(struct usb_device *udev,
395                                 struct dvb_usb_device_properties *props,
396                                 struct dvb_usb_device_description **desc,
397                                 int *cold)
398 {
399         struct usb_host_interface *alt;
400
401         alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1);
402         *cold = (alt == NULL) ? 1 : 0;
403
404         return 0;
405 }
406
407 /* demod configurations */
408 static int m920x_mt352_demod_init(struct dvb_frontend *fe)
409 {
410         int ret;
411         u8 config[] = { CONFIG, 0x3d };
412         u8 clock[] = { CLOCK_CTL, 0x30 };
413         u8 reset[] = { RESET, 0x80 };
414         u8 adc_ctl[] = { ADC_CTL_1, 0x40 };
415         u8 agc[] = { AGC_TARGET, 0x1c, 0x20 };
416         u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 };
417         u8 unk1[] = { 0x93, 0x1a };
418         u8 unk2[] = { 0xb5, 0x7a };
419
420         deb("Demod init!\n");
421
422         if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0)
423                 return ret;
424         if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0)
425                 return ret;
426         if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0)
427                 return ret;
428         if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0)
429                 return ret;
430         if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0)
431                 return ret;
432         if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0)
433                 return ret;
434         if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0)
435                 return ret;
436         if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0)
437                 return ret;
438
439         return 0;
440 }
441
442 static struct mt352_config m920x_mt352_config = {
443         .demod_address = 0x0f,
444         .no_tuner = 1,
445         .demod_init = m920x_mt352_demod_init,
446 };
447
448 static struct tda1004x_config m920x_tda10046_08_config = {
449         .demod_address = 0x08,
450         .invert = 0,
451         .invert_oclk = 0,
452         .ts_mode = TDA10046_TS_SERIAL,
453         .xtal_freq = TDA10046_XTAL_16M,
454         .if_freq = TDA10046_FREQ_045,
455         .agc_config = TDA10046_AGC_TDA827X,
456         .gpio_config = TDA10046_GPTRI,
457         .request_firmware = NULL,
458 };
459
460 static struct tda1004x_config m920x_tda10046_0b_config = {
461         .demod_address = 0x0b,
462         .invert = 0,
463         .invert_oclk = 0,
464         .ts_mode = TDA10046_TS_SERIAL,
465         .xtal_freq = TDA10046_XTAL_16M,
466         .if_freq = TDA10046_FREQ_045,
467         .agc_config = TDA10046_AGC_TDA827X,
468         .gpio_config = TDA10046_GPTRI,
469         .request_firmware = NULL, /* uses firmware EEPROM */
470 };
471
472 /* tuner configurations */
473 static struct qt1010_config m920x_qt1010_config = {
474         .i2c_address = 0x62
475 };
476
477 /* Callbacks for DVB USB */
478 static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
479 {
480         deb("%s\n",__FUNCTION__);
481
482         if ((adap->fe = dvb_attach(mt352_attach,
483                                    &m920x_mt352_config,
484                                    &adap->dev->i2c_adap)) == NULL)
485                 return -EIO;
486
487         return 0;
488 }
489
490 static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
491 {
492         deb("%s\n",__FUNCTION__);
493
494         if ((adap->fe = dvb_attach(tda10046_attach,
495                                    &m920x_tda10046_08_config,
496                                    &adap->dev->i2c_adap)) == NULL)
497                 return -EIO;
498
499         return 0;
500 }
501
502 static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
503 {
504         deb("%s\n",__FUNCTION__);
505
506         if ((adap->fe = dvb_attach(tda10046_attach,
507                                    &m920x_tda10046_0b_config,
508                                    &adap->dev->i2c_adap)) == NULL)
509                 return -EIO;
510
511         return 0;
512 }
513
514 static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
515 {
516         deb("%s\n",__FUNCTION__);
517
518         if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
519                 return -ENODEV;
520
521         return 0;
522 }
523
524 static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
525 {
526         deb("%s\n",__FUNCTION__);
527
528         if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
529                 return -ENODEV;
530
531         return 0;
532 }
533
534 static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
535 {
536         deb("%s\n",__FUNCTION__);
537
538         if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
539                 return -ENODEV;
540
541         return 0;
542 }
543
544 /* device-specific initialization */
545 static struct m920x_inits megasky_rc_init [] = {
546         { M9206_RC_INIT2, 0xa8 },
547         { M9206_RC_INIT1, 0x51 },
548         { } /* terminating entry */
549 };
550
551 static struct m920x_inits tvwalkertwin_rc_init [] = {
552         { M9206_RC_INIT2, 0x00 },
553         { M9206_RC_INIT1, 0xef },
554         { 0xff28,         0x00 },
555         { 0xff23,         0x00 },
556         { 0xff21,         0x30 },
557         { } /* terminating entry */
558 };
559
560 /* ir keymaps */
561 static struct dvb_usb_rc_key megasky_rc_keys [] = {
562         { 0x0, 0x12, KEY_POWER },
563         { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
564         { 0x0, 0x02, KEY_CHANNELUP },
565         { 0x0, 0x05, KEY_CHANNELDOWN },
566         { 0x0, 0x03, KEY_VOLUMEUP },
567         { 0x0, 0x06, KEY_VOLUMEDOWN },
568         { 0x0, 0x04, KEY_MUTE },
569         { 0x0, 0x07, KEY_OK }, /* TS */
570         { 0x0, 0x08, KEY_STOP },
571         { 0x0, 0x09, KEY_MENU }, /* swap */
572         { 0x0, 0x0a, KEY_REWIND },
573         { 0x0, 0x1b, KEY_PAUSE },
574         { 0x0, 0x1f, KEY_FASTFORWARD },
575         { 0x0, 0x0c, KEY_RECORD },
576         { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
577         { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
578 };
579
580 static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
581         { 0x0, 0x01, KEY_ZOOM }, /* Full Screen */
582         { 0x0, 0x02, KEY_CAMERA }, /* snapshot */
583         { 0x0, 0x03, KEY_MUTE },
584         { 0x0, 0x04, KEY_REWIND },
585         { 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */
586         { 0x0, 0x06, KEY_FASTFORWARD },
587         { 0x0, 0x07, KEY_RECORD },
588         { 0x0, 0x08, KEY_STOP },
589         { 0x0, 0x09, KEY_TIME }, /* Timeshift */
590         { 0x0, 0x0c, KEY_COFFEE }, /* Recall */
591         { 0x0, 0x0e, KEY_CHANNELUP },
592         { 0x0, 0x12, KEY_POWER },
593         { 0x0, 0x15, KEY_MENU }, /* source */
594         { 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */
595         { 0x0, 0x1a, KEY_CHANNELDOWN },
596         { 0x0, 0x1b, KEY_VOLUMEDOWN },
597         { 0x0, 0x1e, KEY_VOLUMEUP },
598 };
599
600 /* DVB USB Driver stuff */
601 static struct dvb_usb_device_properties megasky_properties;
602 static struct dvb_usb_device_properties digivox_mini_ii_properties;
603 static struct dvb_usb_device_properties tvwalkertwin_properties;
604 static struct dvb_usb_device_properties dposh_properties;
605
606 static int m920x_probe(struct usb_interface *intf,
607                        const struct usb_device_id *id)
608 {
609         struct dvb_usb_device *d = NULL;
610         int ret;
611         struct m920x_inits *rc_init_seq = NULL;
612         int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
613
614         deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
615
616         if (bInterfaceNumber == 0) {
617                 /* Single-tuner device, or first interface on
618                  * multi-tuner device
619                  */
620
621                 if ((ret = dvb_usb_device_init(intf, &megasky_properties,
622                                                THIS_MODULE, &d)) == 0) {
623                         rc_init_seq = megasky_rc_init;
624                         goto found;
625                 }
626
627                 if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
628                                                THIS_MODULE, &d)) == 0) {
629                         /* No remote control, so no rc_init_seq */
630                         goto found;
631                 }
632
633                 /* This configures both tuners on the TV Walker Twin */
634                 if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
635                                                THIS_MODULE, &d)) == 0) {
636                         rc_init_seq = tvwalkertwin_rc_init;
637                         goto found;
638                 }
639
640                 if ((ret = dvb_usb_device_init(intf, &dposh_properties,
641                                                THIS_MODULE, &d)) == 0) {
642                         /* Remote controller not supported yet. */
643                         goto found;
644                 }
645
646                 return ret;
647         } else {
648                 /* Another interface on a multi-tuner device */
649
650                 /* The LifeView TV Walker Twin gets here, but struct
651                  * tvwalkertwin_properties already configured both
652                  * tuners, so there is nothing for us to do here
653                  */
654         }
655
656  found:
657         if ((ret = m920x_init_ep(intf)) < 0)
658                 return ret;
659
660         if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
661                 return ret;
662
663         return ret;
664 }
665
666 static struct usb_device_id m920x_table [] = {
667                 { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
668                 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
669                              USB_PID_MSI_DIGI_VOX_MINI_II) },
670                 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
671                              USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
672                 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
673                              USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
674                 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
675                 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
676                 { }             /* Terminating entry */
677 };
678 MODULE_DEVICE_TABLE (usb, m920x_table);
679
680 static struct dvb_usb_device_properties megasky_properties = {
681         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
682
683         .usb_ctrl = DEVICE_SPECIFIC,
684         .firmware = "dvb-usb-megasky-02.fw",
685         .download_firmware = m920x_firmware_download,
686
687         .rc_interval      = 100,
688         .rc_key_map       = megasky_rc_keys,
689         .rc_key_map_size  = ARRAY_SIZE(megasky_rc_keys),
690         .rc_query         = m920x_rc_query,
691
692         .size_of_priv     = sizeof(struct m920x_state),
693
694         .identify_state   = m920x_identify_state,
695         .num_adapters = 1,
696         .adapter = {{
697                 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
698                         DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
699
700                 .pid_filter_count = 8,
701                 .pid_filter       = m920x_pid_filter,
702                 .pid_filter_ctrl  = m920x_pid_filter_ctrl,
703
704                 .frontend_attach  = m920x_mt352_frontend_attach,
705                 .tuner_attach     = m920x_qt1010_tuner_attach,
706
707                 .stream = {
708                         .type = USB_BULK,
709                         .count = 8,
710                         .endpoint = 0x81,
711                         .u = {
712                                 .bulk = {
713                                         .buffersize = 512,
714                                 }
715                         }
716                 },
717         }},
718         .i2c_algo         = &m920x_i2c_algo,
719
720         .num_device_descs = 1,
721         .devices = {
722                 {   "MSI Mega Sky 580 DVB-T USB2.0",
723                         { &m920x_table[0], NULL },
724                         { NULL },
725                 }
726         }
727 };
728
729 static struct dvb_usb_device_properties digivox_mini_ii_properties = {
730         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
731
732         .usb_ctrl = DEVICE_SPECIFIC,
733         .firmware = "dvb-usb-digivox-02.fw",
734         .download_firmware = m920x_firmware_download,
735
736         .size_of_priv     = sizeof(struct m920x_state),
737
738         .identify_state   = m920x_identify_state,
739         .num_adapters = 1,
740         .adapter = {{
741                 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
742                         DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
743
744                 .pid_filter_count = 8,
745                 .pid_filter       = m920x_pid_filter,
746                 .pid_filter_ctrl  = m920x_pid_filter_ctrl,
747
748                 .frontend_attach  = m920x_tda10046_08_frontend_attach,
749                 .tuner_attach     = m920x_tda8275_60_tuner_attach,
750
751                 .stream = {
752                         .type = USB_BULK,
753                         .count = 8,
754                         .endpoint = 0x81,
755                         .u = {
756                                 .bulk = {
757                                         .buffersize = 0x4000,
758                                 }
759                         }
760                 },
761         }},
762         .i2c_algo         = &m920x_i2c_algo,
763
764         .num_device_descs = 1,
765         .devices = {
766                 {   "MSI DIGI VOX mini II DVB-T USB2.0",
767                         { &m920x_table[1], NULL },
768                         { NULL },
769                 },
770         }
771 };
772
773 /* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
774  *
775  * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
776  * TDA10046 #0 is located at i2c address 0x08
777  * TDA10046 #1 is located at i2c address 0x0b
778  * TDA8275A #0 is located at i2c address 0x60
779  * TDA8275A #1 is located at i2c address 0x61
780  */
781 static struct dvb_usb_device_properties tvwalkertwin_properties = {
782         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
783
784         .usb_ctrl = DEVICE_SPECIFIC,
785         .firmware = "dvb-usb-tvwalkert.fw",
786         .download_firmware = m920x_firmware_download,
787
788         .rc_interval      = 100,
789         .rc_key_map       = tvwalkertwin_rc_keys,
790         .rc_key_map_size  = ARRAY_SIZE(tvwalkertwin_rc_keys),
791         .rc_query         = m920x_rc_query,
792
793         .size_of_priv     = sizeof(struct m920x_state),
794
795         .identify_state   = m920x_identify_state,
796         .num_adapters = 2,
797         .adapter = {{
798                 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
799                         DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
800
801                 .pid_filter_count = 8,
802                 .pid_filter       = m920x_pid_filter,
803                 .pid_filter_ctrl  = m920x_pid_filter_ctrl,
804
805                 .frontend_attach  = m920x_tda10046_08_frontend_attach,
806                 .tuner_attach     = m920x_tda8275_60_tuner_attach,
807
808                 .stream = {
809                         .type = USB_BULK,
810                         .count = 8,
811                         .endpoint = 0x81,
812                         .u = {
813                                  .bulk = {
814                                          .buffersize = 512,
815                                  }
816                         }
817                 }},{
818                 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
819                         DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
820
821                 .pid_filter_count = 8,
822                 .pid_filter       = m920x_pid_filter,
823                 .pid_filter_ctrl  = m920x_pid_filter_ctrl,
824
825                 .frontend_attach  = m920x_tda10046_0b_frontend_attach,
826                 .tuner_attach     = m920x_tda8275_61_tuner_attach,
827
828                 .stream = {
829                         .type = USB_BULK,
830                         .count = 8,
831                         .endpoint = 0x82,
832                         .u = {
833                                  .bulk = {
834                                          .buffersize = 512,
835                                  }
836                         }
837                 },
838         }},
839         .i2c_algo         = &m920x_i2c_algo,
840
841         .num_device_descs = 1,
842         .devices = {
843                 {   .name = "LifeView TV Walker Twin DVB-T USB2.0",
844                     .cold_ids = { &m920x_table[2], NULL },
845                     .warm_ids = { &m920x_table[3], NULL },
846                 },
847         }
848 };
849
850 static struct dvb_usb_device_properties dposh_properties = {
851         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
852
853         .usb_ctrl = DEVICE_SPECIFIC,
854         .firmware = "dvb-usb-dposh-01.fw",
855         .download_firmware = m920x_firmware_download,
856
857         .size_of_priv     = sizeof(struct m920x_state),
858
859         .identify_state   = m920x_identify_state,
860         .num_adapters = 1,
861         .adapter = {{
862                 /* Hardware pid filters don't work with this device/firmware */
863
864                 .frontend_attach  = m920x_mt352_frontend_attach,
865                 .tuner_attach     = m920x_qt1010_tuner_attach,
866
867                 .stream = {
868                         .type = USB_BULK,
869                         .count = 8,
870                         .endpoint = 0x81,
871                         .u = {
872                                  .bulk = {
873                                          .buffersize = 512,
874                                  }
875                         }
876                 },
877         }},
878         .i2c_algo         = &m920x_i2c_algo,
879
880         .num_device_descs = 1,
881         .devices = {
882                  {   .name = "Dposh DVB-T USB2.0",
883                      .cold_ids = { &m920x_table[4], NULL },
884                      .warm_ids = { &m920x_table[5], NULL },
885                  },
886          }
887 };
888
889 static struct usb_driver m920x_driver = {
890         .name           = "dvb_usb_m920x",
891         .probe          = m920x_probe,
892         .disconnect     = dvb_usb_device_exit,
893         .id_table       = m920x_table,
894 };
895
896 /* module stuff */
897 static int __init m920x_module_init(void)
898 {
899         int ret;
900
901         if ((ret = usb_register(&m920x_driver))) {
902                 err("usb_register failed. Error number %d", ret);
903                 return ret;
904         }
905
906         return 0;
907 }
908
909 static void __exit m920x_module_exit(void)
910 {
911         /* deregister this driver from the USB subsystem */
912         usb_deregister(&m920x_driver);
913 }
914
915 module_init (m920x_module_init);
916 module_exit (m920x_module_exit);
917
918 MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
919 MODULE_DESCRIPTION("DVB Driver for ULI M920x");
920 MODULE_VERSION("0.1");
921 MODULE_LICENSE("GPL");
922
923 /*
924  * Local variables:
925  * c-basic-offset: 8
926  */