Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tm6000-cards.c
Go to the documentation of this file.
1 /*
2  * tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3  *
4  * Copyright (C) 2006-2007 Mauro Carvalho Chehab <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation version 2
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 #include <linux/init.h>
21 #include <linux/module.h>
22 #include <linux/pci.h>
23 #include <linux/delay.h>
24 #include <linux/i2c.h>
25 #include <linux/usb.h>
26 #include <linux/slab.h>
27 #include <media/v4l2-common.h>
28 #include <media/tuner.h>
29 #include <media/tvaudio.h>
30 #include <media/i2c-addr.h>
31 #include <media/rc-map.h>
32 
33 #include "tm6000.h"
34 #include "tm6000-regs.h"
35 #include "tuner-xc2028.h"
36 #include "xc5000.h"
37 
38 #define TM6000_BOARD_UNKNOWN 0
39 #define TM5600_BOARD_GENERIC 1
40 #define TM6000_BOARD_GENERIC 2
41 #define TM6010_BOARD_GENERIC 3
42 #define TM5600_BOARD_10MOONS_UT821 4
43 #define TM5600_BOARD_10MOONS_UT330 5
44 #define TM6000_BOARD_ADSTECH_DUAL_TV 6
45 #define TM6000_BOARD_FREECOM_AND_SIMILAR 7
46 #define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
47 #define TM6010_BOARD_HAUPPAUGE_900H 9
48 #define TM6010_BOARD_BEHOLD_WANDER 10
49 #define TM6010_BOARD_BEHOLD_VOYAGER 11
50 #define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
51 #define TM6010_BOARD_TWINHAN_TU501 13
52 #define TM6010_BOARD_BEHOLD_WANDER_LITE 14
53 #define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15
54 #define TM5600_BOARD_TERRATEC_GRABSTER 16
55 
56 #define is_generic(model) ((model == TM6000_BOARD_UNKNOWN) || \
57  (model == TM5600_BOARD_GENERIC) || \
58  (model == TM6000_BOARD_GENERIC) || \
59  (model == TM6010_BOARD_GENERIC))
60 
61 #define TM6000_MAXBOARDS 16
62 static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
63 
64 module_param_array(card, int, NULL, 0444);
65 
66 static unsigned long tm6000_devused;
67 
68 
69 struct tm6000_board {
70  char *name;
71  char eename[16]; /* EEPROM name */
72  unsigned eename_size; /* size of EEPROM name */
73  unsigned eename_pos; /* Position where it appears at ROM */
74 
76 
77  enum tm6000_devtype type; /* variant of the chipset */
78  int tuner_type; /* type of the tuner */
79  int tuner_addr; /* tuner address */
80  int demod_addr; /* demodulator address */
81 
82  struct tm6000_gpio gpio;
83 
84  struct tm6000_input vinput[3];
86 
87  char *ir_codes;
88 };
89 
90 static struct tm6000_board tm6000_boards[] = {
92  .name = "Unknown tm6000 video grabber",
93  .caps = {
94  .has_tuner = 1,
95  .has_eeprom = 1,
96  },
97  .gpio = {
98  .tuner_reset = TM6000_GPIO_1,
99  },
100  .vinput = { {
101  .type = TM6000_INPUT_TV,
102  .vmux = TM6000_VMUX_VIDEO_B,
103  .amux = TM6000_AMUX_ADC1,
104  }, {
105  .type = TM6000_INPUT_COMPOSITE1,
106  .vmux = TM6000_VMUX_VIDEO_A,
107  .amux = TM6000_AMUX_ADC2,
108  }, {
109  .type = TM6000_INPUT_SVIDEO,
110  .vmux = TM6000_VMUX_VIDEO_AB,
111  .amux = TM6000_AMUX_ADC2,
112  },
113  },
114  },
116  .name = "Generic tm5600 board",
117  .type = TM5600,
118  .tuner_type = TUNER_XC2028,
119  .tuner_addr = 0xc2 >> 1,
120  .caps = {
121  .has_tuner = 1,
122  .has_eeprom = 1,
123  },
124  .gpio = {
125  .tuner_reset = TM6000_GPIO_1,
126  },
127  .vinput = { {
128  .type = TM6000_INPUT_TV,
129  .vmux = TM6000_VMUX_VIDEO_B,
130  .amux = TM6000_AMUX_ADC1,
131  }, {
132  .type = TM6000_INPUT_COMPOSITE1,
133  .vmux = TM6000_VMUX_VIDEO_A,
134  .amux = TM6000_AMUX_ADC2,
135  }, {
136  .type = TM6000_INPUT_SVIDEO,
137  .vmux = TM6000_VMUX_VIDEO_AB,
138  .amux = TM6000_AMUX_ADC2,
139  },
140  },
141  },
143  .name = "Generic tm6000 board",
144  .tuner_type = TUNER_XC2028,
145  .tuner_addr = 0xc2 >> 1,
146  .caps = {
147  .has_tuner = 1,
148  .has_eeprom = 1,
149  },
150  .gpio = {
151  .tuner_reset = TM6000_GPIO_1,
152  },
153  .vinput = { {
154  .type = TM6000_INPUT_TV,
155  .vmux = TM6000_VMUX_VIDEO_B,
156  .amux = TM6000_AMUX_ADC1,
157  }, {
158  .type = TM6000_INPUT_COMPOSITE1,
159  .vmux = TM6000_VMUX_VIDEO_A,
160  .amux = TM6000_AMUX_ADC2,
161  }, {
162  .type = TM6000_INPUT_SVIDEO,
163  .vmux = TM6000_VMUX_VIDEO_AB,
164  .amux = TM6000_AMUX_ADC2,
165  },
166  },
167  },
169  .name = "Generic tm6010 board",
170  .type = TM6010,
171  .tuner_type = TUNER_XC2028,
172  .tuner_addr = 0xc2 >> 1,
173  .demod_addr = 0x1e >> 1,
174  .caps = {
175  .has_tuner = 1,
176  .has_dvb = 1,
177  .has_zl10353 = 1,
178  .has_eeprom = 1,
179  .has_remote = 1,
180  },
181  .gpio = {
182  .tuner_reset = TM6010_GPIO_2,
183  .tuner_on = TM6010_GPIO_3,
184  .demod_reset = TM6010_GPIO_1,
185  .demod_on = TM6010_GPIO_4,
186  .power_led = TM6010_GPIO_7,
187  .dvb_led = TM6010_GPIO_5,
188  .ir = TM6010_GPIO_0,
189  },
190  .vinput = { {
191  .type = TM6000_INPUT_TV,
192  .vmux = TM6000_VMUX_VIDEO_B,
193  .amux = TM6000_AMUX_SIF1,
194  }, {
195  .type = TM6000_INPUT_COMPOSITE1,
196  .vmux = TM6000_VMUX_VIDEO_A,
197  .amux = TM6000_AMUX_ADC2,
198  }, {
199  .type = TM6000_INPUT_SVIDEO,
200  .vmux = TM6000_VMUX_VIDEO_AB,
201  .amux = TM6000_AMUX_ADC2,
202  },
203  },
204  },
206  .name = "10Moons UT 821",
207  .tuner_type = TUNER_XC2028,
208  .eename = { '1', '0', 'M', 'O', 'O', 'N', 'S', '5', '6', '0', '0', 0xff, 0x45, 0x5b},
209  .eename_size = 14,
210  .eename_pos = 0x14,
211  .type = TM5600,
212  .tuner_addr = 0xc2 >> 1,
213  .caps = {
214  .has_tuner = 1,
215  .has_eeprom = 1,
216  },
217  .gpio = {
218  .tuner_reset = TM6000_GPIO_1,
219  },
220  .vinput = { {
221  .type = TM6000_INPUT_TV,
222  .vmux = TM6000_VMUX_VIDEO_B,
223  .amux = TM6000_AMUX_ADC1,
224  }, {
225  .type = TM6000_INPUT_COMPOSITE1,
226  .vmux = TM6000_VMUX_VIDEO_A,
227  .amux = TM6000_AMUX_ADC2,
228  }, {
229  .type = TM6000_INPUT_SVIDEO,
230  .vmux = TM6000_VMUX_VIDEO_AB,
231  .amux = TM6000_AMUX_ADC2,
232  },
233  },
234  },
236  .name = "10Moons UT 330",
237  .tuner_type = TUNER_PHILIPS_FQ1216AME_MK4,
238  .tuner_addr = 0xc8 >> 1,
239  .caps = {
240  .has_tuner = 1,
241  .has_dvb = 0,
242  .has_zl10353 = 0,
243  .has_eeprom = 1,
244  },
245  .vinput = { {
246  .type = TM6000_INPUT_TV,
247  .vmux = TM6000_VMUX_VIDEO_B,
248  .amux = TM6000_AMUX_ADC1,
249  }, {
250  .type = TM6000_INPUT_COMPOSITE1,
251  .vmux = TM6000_VMUX_VIDEO_A,
252  .amux = TM6000_AMUX_ADC2,
253  }, {
254  .type = TM6000_INPUT_SVIDEO,
255  .vmux = TM6000_VMUX_VIDEO_AB,
256  .amux = TM6000_AMUX_ADC2,
257  },
258  },
259  },
261  .name = "ADSTECH Dual TV USB",
262  .tuner_type = TUNER_XC2028,
263  .tuner_addr = 0xc8 >> 1,
264  .caps = {
265  .has_tuner = 1,
266  .has_tda9874 = 1,
267  .has_dvb = 1,
268  .has_zl10353 = 1,
269  .has_eeprom = 1,
270  },
271  .vinput = { {
272  .type = TM6000_INPUT_TV,
273  .vmux = TM6000_VMUX_VIDEO_B,
274  .amux = TM6000_AMUX_ADC1,
275  }, {
276  .type = TM6000_INPUT_COMPOSITE1,
277  .vmux = TM6000_VMUX_VIDEO_A,
278  .amux = TM6000_AMUX_ADC2,
279  }, {
280  .type = TM6000_INPUT_SVIDEO,
281  .vmux = TM6000_VMUX_VIDEO_AB,
282  .amux = TM6000_AMUX_ADC2,
283  },
284  },
285  },
287  .name = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual",
288  .tuner_type = TUNER_XC2028, /* has a XC3028 */
289  .tuner_addr = 0xc2 >> 1,
290  .demod_addr = 0x1e >> 1,
291  .caps = {
292  .has_tuner = 1,
293  .has_dvb = 1,
294  .has_zl10353 = 1,
295  .has_eeprom = 0,
296  .has_remote = 1,
297  },
298  .gpio = {
299  .tuner_reset = TM6000_GPIO_4,
300  },
301  .vinput = { {
302  .type = TM6000_INPUT_TV,
303  .vmux = TM6000_VMUX_VIDEO_B,
304  .amux = TM6000_AMUX_ADC1,
305  }, {
306  .type = TM6000_INPUT_COMPOSITE1,
307  .vmux = TM6000_VMUX_VIDEO_A,
308  .amux = TM6000_AMUX_ADC2,
309  }, {
310  .type = TM6000_INPUT_SVIDEO,
311  .vmux = TM6000_VMUX_VIDEO_AB,
312  .amux = TM6000_AMUX_ADC2,
313  },
314  },
315  },
317  .name = "ADSTECH Mini Dual TV USB",
318  .tuner_type = TUNER_XC2028, /* has a XC3028 */
319  .tuner_addr = 0xc8 >> 1,
320  .demod_addr = 0x1e >> 1,
321  .caps = {
322  .has_tuner = 1,
323  .has_dvb = 1,
324  .has_zl10353 = 1,
325  .has_eeprom = 0,
326  },
327  .gpio = {
328  .tuner_reset = TM6000_GPIO_4,
329  },
330  .vinput = { {
331  .type = TM6000_INPUT_TV,
332  .vmux = TM6000_VMUX_VIDEO_B,
333  .amux = TM6000_AMUX_ADC1,
334  }, {
335  .type = TM6000_INPUT_COMPOSITE1,
336  .vmux = TM6000_VMUX_VIDEO_A,
337  .amux = TM6000_AMUX_ADC2,
338  }, {
339  .type = TM6000_INPUT_SVIDEO,
340  .vmux = TM6000_VMUX_VIDEO_AB,
341  .amux = TM6000_AMUX_ADC2,
342  },
343  },
344  },
346  .name = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick",
347  .eename = { 'H', 0, 'V', 0, 'R', 0, '9', 0, '0', 0, '0', 0, 'H', 0 },
348  .eename_size = 14,
349  .eename_pos = 0x42,
350  .tuner_type = TUNER_XC2028, /* has a XC3028 */
351  .tuner_addr = 0xc2 >> 1,
352  .demod_addr = 0x1e >> 1,
353  .type = TM6010,
354  .ir_codes = RC_MAP_HAUPPAUGE,
355  .caps = {
356  .has_tuner = 1,
357  .has_dvb = 1,
358  .has_zl10353 = 1,
359  .has_eeprom = 1,
360  .has_remote = 1,
361  },
362  .gpio = {
363  .tuner_reset = TM6010_GPIO_2,
364  .tuner_on = TM6010_GPIO_3,
365  .demod_reset = TM6010_GPIO_1,
366  .demod_on = TM6010_GPIO_4,
367  .power_led = TM6010_GPIO_7,
368  .dvb_led = TM6010_GPIO_5,
369  .ir = TM6010_GPIO_0,
370  },
371  .vinput = { {
372  .type = TM6000_INPUT_TV,
373  .vmux = TM6000_VMUX_VIDEO_B,
374  .amux = TM6000_AMUX_SIF1,
375  }, {
376  .type = TM6000_INPUT_COMPOSITE1,
377  .vmux = TM6000_VMUX_VIDEO_A,
378  .amux = TM6000_AMUX_ADC2,
379  }, {
380  .type = TM6000_INPUT_SVIDEO,
381  .vmux = TM6000_VMUX_VIDEO_AB,
382  .amux = TM6000_AMUX_ADC2,
383  },
384  },
385  },
387  .name = "Beholder Wander DVB-T/TV/FM USB2.0",
388  .tuner_type = TUNER_XC5000,
389  .tuner_addr = 0xc2 >> 1,
390  .demod_addr = 0x1e >> 1,
391  .type = TM6010,
392  .caps = {
393  .has_tuner = 1,
394  .has_dvb = 1,
395  .has_zl10353 = 1,
396  .has_eeprom = 1,
397  .has_remote = 1,
398  .has_radio = 1,
399  },
400  .gpio = {
401  .tuner_reset = TM6010_GPIO_0,
402  .demod_reset = TM6010_GPIO_1,
403  .power_led = TM6010_GPIO_6,
404  },
405  .vinput = { {
406  .type = TM6000_INPUT_TV,
407  .vmux = TM6000_VMUX_VIDEO_B,
408  .amux = TM6000_AMUX_SIF1,
409  }, {
410  .type = TM6000_INPUT_COMPOSITE1,
411  .vmux = TM6000_VMUX_VIDEO_A,
412  .amux = TM6000_AMUX_ADC2,
413  }, {
414  .type = TM6000_INPUT_SVIDEO,
415  .vmux = TM6000_VMUX_VIDEO_AB,
416  .amux = TM6000_AMUX_ADC2,
417  },
418  },
419  .rinput = {
420  .type = TM6000_INPUT_RADIO,
421  .amux = TM6000_AMUX_ADC1,
422  },
423  },
425  .name = "Beholder Voyager TV/FM USB2.0",
426  .tuner_type = TUNER_XC5000,
427  .tuner_addr = 0xc2 >> 1,
428  .type = TM6010,
429  .caps = {
430  .has_tuner = 1,
431  .has_dvb = 0,
432  .has_zl10353 = 0,
433  .has_eeprom = 1,
434  .has_remote = 1,
435  .has_radio = 1,
436  },
437  .gpio = {
438  .tuner_reset = TM6010_GPIO_0,
439  .power_led = TM6010_GPIO_6,
440  },
441  .vinput = { {
442  .type = TM6000_INPUT_TV,
443  .vmux = TM6000_VMUX_VIDEO_B,
444  .amux = TM6000_AMUX_SIF1,
445  }, {
446  .type = TM6000_INPUT_COMPOSITE1,
447  .vmux = TM6000_VMUX_VIDEO_A,
448  .amux = TM6000_AMUX_ADC2,
449  }, {
450  .type = TM6000_INPUT_SVIDEO,
451  .vmux = TM6000_VMUX_VIDEO_AB,
452  .amux = TM6000_AMUX_ADC2,
453  },
454  },
455  .rinput = {
456  .type = TM6000_INPUT_RADIO,
457  .amux = TM6000_AMUX_ADC1,
458  },
459  },
461  .name = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick",
462  .tuner_type = TUNER_XC2028, /* has a XC3028 */
463  .tuner_addr = 0xc2 >> 1,
464  .demod_addr = 0x1e >> 1,
465  .type = TM6010,
466  .caps = {
467  .has_tuner = 1,
468  .has_dvb = 1,
469  .has_zl10353 = 1,
470  .has_eeprom = 1,
471  .has_remote = 1,
472  .has_radio = 1,
473  },
474  .gpio = {
475  .tuner_reset = TM6010_GPIO_2,
476  .tuner_on = TM6010_GPIO_3,
477  .demod_reset = TM6010_GPIO_1,
478  .demod_on = TM6010_GPIO_4,
479  .power_led = TM6010_GPIO_7,
480  .dvb_led = TM6010_GPIO_5,
481  .ir = TM6010_GPIO_0,
482  },
483  .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
484  .vinput = { {
485  .type = TM6000_INPUT_TV,
486  .vmux = TM6000_VMUX_VIDEO_B,
487  .amux = TM6000_AMUX_SIF1,
488  }, {
489  .type = TM6000_INPUT_COMPOSITE1,
490  .vmux = TM6000_VMUX_VIDEO_A,
491  .amux = TM6000_AMUX_ADC2,
492  }, {
493  .type = TM6000_INPUT_SVIDEO,
494  .vmux = TM6000_VMUX_VIDEO_AB,
495  .amux = TM6000_AMUX_ADC2,
496  },
497  },
498  .rinput = {
499  .type = TM6000_INPUT_RADIO,
500  .amux = TM6000_AMUX_SIF1,
501  },
502  },
504  .name = "Terratec Grabster AV 150/250 MX",
505  .type = TM5600,
506  .tuner_type = TUNER_ABSENT,
507  .vinput = { {
508  .type = TM6000_INPUT_TV,
509  .vmux = TM6000_VMUX_VIDEO_B,
510  .amux = TM6000_AMUX_ADC1,
511  }, {
512  .type = TM6000_INPUT_COMPOSITE1,
513  .vmux = TM6000_VMUX_VIDEO_A,
514  .amux = TM6000_AMUX_ADC2,
515  }, {
516  .type = TM6000_INPUT_SVIDEO,
517  .vmux = TM6000_VMUX_VIDEO_AB,
518  .amux = TM6000_AMUX_ADC2,
519  },
520  },
521  },
523  .name = "Twinhan TU501(704D1)",
524  .tuner_type = TUNER_XC2028, /* has a XC3028 */
525  .tuner_addr = 0xc2 >> 1,
526  .demod_addr = 0x1e >> 1,
527  .type = TM6010,
528  .caps = {
529  .has_tuner = 1,
530  .has_dvb = 1,
531  .has_zl10353 = 1,
532  .has_eeprom = 1,
533  .has_remote = 1,
534  },
535  .gpio = {
536  .tuner_reset = TM6010_GPIO_2,
537  .tuner_on = TM6010_GPIO_3,
538  .demod_reset = TM6010_GPIO_1,
539  .demod_on = TM6010_GPIO_4,
540  .power_led = TM6010_GPIO_7,
541  .dvb_led = TM6010_GPIO_5,
542  .ir = TM6010_GPIO_0,
543  },
544  .vinput = { {
545  .type = TM6000_INPUT_TV,
546  .vmux = TM6000_VMUX_VIDEO_B,
547  .amux = TM6000_AMUX_SIF1,
548  }, {
549  .type = TM6000_INPUT_COMPOSITE1,
550  .vmux = TM6000_VMUX_VIDEO_A,
551  .amux = TM6000_AMUX_ADC2,
552  }, {
553  .type = TM6000_INPUT_SVIDEO,
554  .vmux = TM6000_VMUX_VIDEO_AB,
555  .amux = TM6000_AMUX_ADC2,
556  },
557  },
558  },
560  .name = "Beholder Wander Lite DVB-T/TV/FM USB2.0",
561  .tuner_type = TUNER_XC5000,
562  .tuner_addr = 0xc2 >> 1,
563  .demod_addr = 0x1e >> 1,
564  .type = TM6010,
565  .caps = {
566  .has_tuner = 1,
567  .has_dvb = 1,
568  .has_zl10353 = 1,
569  .has_eeprom = 1,
570  .has_remote = 0,
571  .has_radio = 1,
572  },
573  .gpio = {
574  .tuner_reset = TM6010_GPIO_0,
575  .demod_reset = TM6010_GPIO_1,
576  .power_led = TM6010_GPIO_6,
577  },
578  .vinput = { {
579  .type = TM6000_INPUT_TV,
580  .vmux = TM6000_VMUX_VIDEO_B,
581  .amux = TM6000_AMUX_SIF1,
582  },
583  },
584  .rinput = {
585  .type = TM6000_INPUT_RADIO,
586  .amux = TM6000_AMUX_ADC1,
587  },
588  },
590  .name = "Beholder Voyager Lite TV/FM USB2.0",
591  .tuner_type = TUNER_XC5000,
592  .tuner_addr = 0xc2 >> 1,
593  .type = TM6010,
594  .caps = {
595  .has_tuner = 1,
596  .has_dvb = 0,
597  .has_zl10353 = 0,
598  .has_eeprom = 1,
599  .has_remote = 0,
600  .has_radio = 1,
601  },
602  .gpio = {
603  .tuner_reset = TM6010_GPIO_0,
604  .power_led = TM6010_GPIO_6,
605  },
606  .vinput = { {
607  .type = TM6000_INPUT_TV,
608  .vmux = TM6000_VMUX_VIDEO_B,
609  .amux = TM6000_AMUX_SIF1,
610  },
611  },
612  .rinput = {
613  .type = TM6000_INPUT_RADIO,
614  .amux = TM6000_AMUX_ADC1,
615  },
616  },
617 };
618 
619 /* table of devices that work with this driver */
620 static struct usb_device_id tm6000_id_table[] = {
621  { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC },
622  { USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC },
623  { USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV },
624  { USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR },
625  { USB_DEVICE(0x06e1, 0xb339), .driver_info = TM6000_BOARD_ADSTECH_MINI_DUAL_TV },
626  { USB_DEVICE(0x2040, 0x6600), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
627  { USB_DEVICE(0x2040, 0x6601), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
628  { USB_DEVICE(0x2040, 0x6610), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
629  { USB_DEVICE(0x2040, 0x6611), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
630  { USB_DEVICE(0x6000, 0xdec0), .driver_info = TM6010_BOARD_BEHOLD_WANDER },
631  { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER },
632  { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
633  { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
634  { USB_DEVICE(0x0ccd, 0x0079), .driver_info = TM5600_BOARD_TERRATEC_GRABSTER },
635  { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
636  { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
637  { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
638  { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
639  { USB_DEVICE(0x6000, 0xdec2), .driver_info = TM6010_BOARD_BEHOLD_WANDER_LITE },
640  { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE },
641  { }
642 };
643 MODULE_DEVICE_TABLE(usb, tm6000_id_table);
644 
645 /* Control power led for show some activity */
647 {
648  /* Power LED unconfigured */
649  if (!dev->gpio.power_led)
650  return;
651 
652  /* ON Power LED */
653  if (state) {
654  switch (dev->model) {
659  dev->gpio.power_led, 0x00);
660  break;
666  dev->gpio.power_led, 0x01);
667  break;
668  }
669  }
670  /* OFF Power LED */
671  else {
672  switch (dev->model) {
677  dev->gpio.power_led, 0x01);
678  break;
684  dev->gpio.power_led, 0x00);
685  break;
686  }
687  }
688 }
689 
690 /* Tuner callback to provide the proper gpio changes needed for xc5000 */
691 int tm6000_xc5000_callback(void *ptr, int component, int command, int arg)
692 {
693  int rc = 0;
694  struct tm6000_core *dev = ptr;
695 
696  if (dev->tuner_type != TUNER_XC5000)
697  return 0;
698 
699  switch (command) {
700  case XC5000_TUNER_RESET:
702  dev->gpio.tuner_reset, 0x01);
703  msleep(15);
705  dev->gpio.tuner_reset, 0x00);
706  msleep(15);
708  dev->gpio.tuner_reset, 0x01);
709  break;
710  }
711  return rc;
712 }
714 
715 /* Tuner callback to provide the proper gpio changes needed for xc2028 */
716 
717 int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
718 {
719  int rc = 0;
720  struct tm6000_core *dev = ptr;
721 
722  if (dev->tuner_type != TUNER_XC2028)
723  return 0;
724 
725  switch (command) {
726  case XC2028_RESET_CLK:
727  tm6000_ir_wait(dev, 0);
728 
730  0x02, arg);
731  msleep(10);
732  rc = tm6000_i2c_reset(dev, 10);
733  break;
734  case XC2028_TUNER_RESET:
735  /* Reset codes during load firmware */
736  switch (arg) {
737  case 0:
738  /* newer tuner can faster reset */
739  switch (dev->model) {
742  dev->gpio.tuner_reset, 0x01);
744  0x300, 0x01);
745  msleep(10);
747  dev->gpio.tuner_reset, 0x00);
749  0x300, 0x00);
750  msleep(10);
752  dev->gpio.tuner_reset, 0x01);
754  0x300, 0x01);
755  break;
760  dev->gpio.tuner_reset, 0x01);
761  msleep(60);
763  dev->gpio.tuner_reset, 0x00);
764  msleep(75);
766  dev->gpio.tuner_reset, 0x01);
767  msleep(60);
768  break;
769  default:
771  dev->gpio.tuner_reset, 0x00);
772  msleep(130);
774  dev->gpio.tuner_reset, 0x01);
775  msleep(130);
776  break;
777  }
778 
779  tm6000_ir_wait(dev, 1);
780  break;
781  case 1:
783  0x02, 0x01);
784  msleep(10);
785  break;
786  case 2:
787  rc = tm6000_i2c_reset(dev, 100);
788  break;
789  }
790  break;
791  case XC2028_I2C_FLUSH:
792  tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
793  tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
794  break;
795  }
796  return rc;
797 }
799 
801 {
802  /*
803  * Board-specific initialization sequence. Handles all GPIO
804  * initialization sequences that are board-specific.
805  * Up to now, all found devices use GPIO1 and GPIO4 at the same way.
806  * Probably, they're all based on some reference device. Due to that,
807  * there's a common routine at the end to handle those GPIO's. Devices
808  * that use different pinups or init sequences can just return at
809  * the board-specific session.
810  */
811  switch (dev->model) {
816  /* Turn xceive 3028 on */
817  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.tuner_on, 0x01);
818  msleep(15);
819  /* Turn zarlink zl10353 on */
820  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00);
821  msleep(15);
822  /* Reset zarlink zl10353 */
823  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00);
824  msleep(50);
825  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01);
826  msleep(15);
827  /* Turn zarlink zl10353 off */
828  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x01);
829  msleep(15);
830  /* ir ? */
831  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.ir, 0x01);
832  msleep(15);
833  /* Power led on (blue) */
834  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x00);
835  msleep(15);
836  /* DVB led off (orange) */
837  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.dvb_led, 0x01);
838  msleep(15);
839  /* Turn zarlink zl10353 on */
840  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00);
841  msleep(15);
842  break;
845  /* Power led on (blue) */
846  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
847  msleep(15);
848  /* Reset zarlink zl10353 */
849  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00);
850  msleep(50);
851  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01);
852  msleep(15);
853  break;
856  /* Power led on (blue) */
857  tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
858  msleep(15);
859  break;
860  default:
861  break;
862  }
863 
864  /*
865  * Default initialization. Most of the devices seem to use GPIO1
866  * and GPIO4.on the same way, so, this handles the common sequence
867  * used by most devices.
868  * If a device uses a different sequence or different GPIO pins for
869  * reset, just add the code at the board-specific part
870  */
871 
872  if (dev->gpio.tuner_reset) {
873  int rc;
874  int i;
875 
876  for (i = 0; i < 2; i++) {
878  dev->gpio.tuner_reset, 0x00);
879  if (rc < 0) {
880  printk(KERN_ERR "Error %i doing tuner reset\n", rc);
881  return rc;
882  }
883 
884  msleep(10); /* Just to be conservative */
886  dev->gpio.tuner_reset, 0x01);
887  if (rc < 0) {
888  printk(KERN_ERR "Error %i doing tuner reset\n", rc);
889  return rc;
890  }
891  }
892  } else {
893  printk(KERN_ERR "Tuner reset is not configured\n");
894  return -1;
895  }
896 
897  msleep(50);
898 
899  return 0;
900 };
901 
902 static void tm6000_config_tuner(struct tm6000_core *dev)
903 {
904  struct tuner_setup tun_setup;
905 
906  /* Load tuner module */
908  "tuner", dev->tuner_addr, NULL);
909 
910  memset(&tun_setup, 0, sizeof(tun_setup));
911  tun_setup.type = dev->tuner_type;
912  tun_setup.addr = dev->tuner_addr;
913 
914  tun_setup.mode_mask = 0;
915  if (dev->caps.has_tuner)
916  tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO);
917 
918  switch (dev->tuner_type) {
919  case TUNER_XC2028:
920  tun_setup.tuner_callback = tm6000_tuner_callback;
921  break;
922  case TUNER_XC5000:
923  tun_setup.tuner_callback = tm6000_xc5000_callback;
924  break;
925  }
926 
927  v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
928 
929  switch (dev->tuner_type) {
930  case TUNER_XC2028: {
931  struct v4l2_priv_tun_config xc2028_cfg;
932  struct xc2028_ctrl ctl;
933 
934  memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
935  memset(&ctl, 0, sizeof(ctl));
936 
937  ctl.demod = XC3028_FE_ZARLINK456;
938 
939  xc2028_cfg.tuner = TUNER_XC2028;
940  xc2028_cfg.priv = &ctl;
941 
942  switch (dev->model) {
946  ctl.max_len = 80;
947  ctl.fname = "xc3028L-v36.fw";
948  break;
949  default:
950  if (dev->dev_type == TM6010)
951  ctl.fname = "xc3028-v27.fw";
952  else
953  ctl.fname = "xc3028-v24.fw";
954  }
955 
956  printk(KERN_INFO "Setting firmware parameters for xc2028\n");
957  v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
958  &xc2028_cfg);
959 
960  }
961  break;
962  case TUNER_XC5000:
963  {
964  struct v4l2_priv_tun_config xc5000_cfg;
965  struct xc5000_config ctl = {
966  .i2c_address = dev->tuner_addr,
967  .if_khz = 4570,
968  .radio_input = XC5000_RADIO_FM1_MONO,
969  };
970 
971  xc5000_cfg.tuner = TUNER_XC5000;
972  xc5000_cfg.priv = &ctl;
973 
974  v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
975  &xc5000_cfg);
976  }
977  break;
978  default:
979  printk(KERN_INFO "Unknown tuner type. Tuner is not configured.\n");
980  break;
981  }
982 }
983 
984 static int fill_board_specific_data(struct tm6000_core *dev)
985 {
986  int rc;
987 
988  dev->dev_type = tm6000_boards[dev->model].type;
989  dev->tuner_type = tm6000_boards[dev->model].tuner_type;
990  dev->tuner_addr = tm6000_boards[dev->model].tuner_addr;
991 
992  dev->gpio = tm6000_boards[dev->model].gpio;
993 
994  dev->ir_codes = tm6000_boards[dev->model].ir_codes;
995 
996  dev->demod_addr = tm6000_boards[dev->model].demod_addr;
997 
998  dev->caps = tm6000_boards[dev->model].caps;
999 
1000  dev->vinput[0] = tm6000_boards[dev->model].vinput[0];
1001  dev->vinput[1] = tm6000_boards[dev->model].vinput[1];
1002  dev->vinput[2] = tm6000_boards[dev->model].vinput[2];
1003  dev->rinput = tm6000_boards[dev->model].rinput;
1004 
1005  /* setup per-model quirks */
1006  switch (dev->model) {
1010  break;
1011 
1012  default:
1013  break;
1014  }
1015 
1016  /* initialize hardware */
1017  rc = tm6000_init(dev);
1018  if (rc < 0)
1019  return rc;
1020 
1021  return v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
1022 }
1023 
1024 
1025 static void use_alternative_detection_method(struct tm6000_core *dev)
1026 {
1027  int i, model = -1;
1028 
1029  if (!dev->eedata_size)
1030  return;
1031 
1032  for (i = 0; i < ARRAY_SIZE(tm6000_boards); i++) {
1033  if (!tm6000_boards[i].eename_size)
1034  continue;
1035  if (dev->eedata_size < tm6000_boards[i].eename_pos +
1036  tm6000_boards[i].eename_size)
1037  continue;
1038 
1039  if (!memcmp(&dev->eedata[tm6000_boards[i].eename_pos],
1040  tm6000_boards[i].eename,
1041  tm6000_boards[i].eename_size)) {
1042  model = i;
1043  break;
1044  }
1045  }
1046  if (model < 0) {
1047  printk(KERN_INFO "Device has eeprom but is currently unknown\n");
1048  return;
1049  }
1050 
1051  dev->model = model;
1052 
1053  printk(KERN_INFO "Device identified via eeprom as %s (type = %d)\n",
1054  tm6000_boards[model].name, model);
1055 }
1056 
1057 #if defined(CONFIG_MODULES) && defined(MODULE)
1058 static void request_module_async(struct work_struct *work)
1059 {
1060  struct tm6000_core *dev = container_of(work, struct tm6000_core,
1062 
1063  request_module("tm6000-alsa");
1064 
1065  if (dev->caps.has_dvb)
1066  request_module("tm6000-dvb");
1067 }
1068 
1069 static void request_modules(struct tm6000_core *dev)
1070 {
1071  INIT_WORK(&dev->request_module_wk, request_module_async);
1073 }
1074 
1075 static void flush_request_modules(struct tm6000_core *dev)
1076 {
1078 }
1079 #else
1080 #define request_modules(dev)
1081 #define flush_request_modules(dev)
1082 #endif /* CONFIG_MODULES */
1083 
1084 static int tm6000_init_dev(struct tm6000_core *dev)
1085 {
1086  struct v4l2_frequency f;
1087  int rc = 0;
1088 
1089  mutex_init(&dev->lock);
1090  mutex_lock(&dev->lock);
1091 
1092  if (!is_generic(dev->model)) {
1093  rc = fill_board_specific_data(dev);
1094  if (rc < 0)
1095  goto err;
1096 
1097  /* register i2c bus */
1098  rc = tm6000_i2c_register(dev);
1099  if (rc < 0)
1100  goto err;
1101  } else {
1102  /* register i2c bus */
1103  rc = tm6000_i2c_register(dev);
1104  if (rc < 0)
1105  goto err;
1106 
1107  use_alternative_detection_method(dev);
1108 
1109  rc = fill_board_specific_data(dev);
1110  if (rc < 0)
1111  goto err;
1112  }
1113 
1114  /* Default values for STD and resolutions */
1115  dev->width = 720;
1116  dev->height = 480;
1117  dev->norm = V4L2_STD_PAL_M;
1118 
1119  /* Configure tuner */
1120  tm6000_config_tuner(dev);
1121 
1122  /* Set video standard */
1123  v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
1124 
1125  /* Set tuner frequency - also loads firmware on xc2028/xc3028 */
1126  f.tuner = 0;
1128  f.frequency = 3092; /* 193.25 MHz */
1129  dev->freq = f.frequency;
1130  v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
1131 
1132  if (dev->caps.has_tda9874)
1133  v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
1134  "tvaudio", I2C_ADDR_TDA9874, NULL);
1135 
1136  /* register and initialize V4L2 */
1137  rc = tm6000_v4l2_register(dev);
1138  if (rc < 0)
1139  goto err;
1140 
1142  tm6000_init_extension(dev);
1143 
1144  tm6000_ir_init(dev);
1145 
1146  request_modules(dev);
1147 
1148  mutex_unlock(&dev->lock);
1149  return 0;
1150 
1151 err:
1152  mutex_unlock(&dev->lock);
1153  return rc;
1154 }
1155 
1156 /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
1157 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
1158 
1159 static void get_max_endpoint(struct usb_device *udev,
1160  struct usb_host_interface *alt,
1161  char *msgtype,
1162  struct usb_host_endpoint *curr_e,
1163  struct tm6000_endpoint *tm_ep)
1164 {
1165  u16 tmp = le16_to_cpu(curr_e->desc.wMaxPacketSize);
1166  unsigned int size = tmp & 0x7ff;
1167 
1168  if (udev->speed == USB_SPEED_HIGH)
1169  size = size * hb_mult(tmp);
1170 
1171  if (size > tm_ep->maxsize) {
1172  tm_ep->endp = curr_e;
1173  tm_ep->maxsize = size;
1174  tm_ep->bInterfaceNumber = alt->desc.bInterfaceNumber;
1175  tm_ep->bAlternateSetting = alt->desc.bAlternateSetting;
1176 
1177  printk(KERN_INFO "tm6000: %s endpoint: 0x%02x (max size=%u bytes)\n",
1178  msgtype, curr_e->desc.bEndpointAddress,
1179  size);
1180  }
1181 }
1182 
1183 /*
1184  * tm6000_usb_probe()
1185  * checks for supported devices
1186  */
1187 static int tm6000_usb_probe(struct usb_interface *interface,
1188  const struct usb_device_id *id)
1189 {
1190  struct usb_device *usbdev;
1191  struct tm6000_core *dev = NULL;
1192  int i, rc = 0;
1193  int nr = 0;
1194  char *speed;
1195 
1196  usbdev = usb_get_dev(interface_to_usbdev(interface));
1197 
1198  /* Selects the proper interface */
1199  rc = usb_set_interface(usbdev, 0, 1);
1200  if (rc < 0)
1201  goto err;
1202 
1203  /* Check to see next free device and mark as used */
1204  nr = find_first_zero_bit(&tm6000_devused, TM6000_MAXBOARDS);
1205  if (nr >= TM6000_MAXBOARDS) {
1206  printk(KERN_ERR "tm6000: Supports only %i tm60xx boards.\n", TM6000_MAXBOARDS);
1207  usb_put_dev(usbdev);
1208  return -ENOMEM;
1209  }
1210 
1211  /* Create and initialize dev struct */
1212  dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1213  if (dev == NULL) {
1214  printk(KERN_ERR "tm6000" ": out of memory!\n");
1215  usb_put_dev(usbdev);
1216  return -ENOMEM;
1217  }
1218  spin_lock_init(&dev->slock);
1219  mutex_init(&dev->usb_lock);
1220 
1221  /* Increment usage count */
1222  set_bit(nr, &tm6000_devused);
1223  snprintf(dev->name, 29, "tm6000 #%d", nr);
1224 
1225  dev->model = id->driver_info;
1226  if (card[nr] < ARRAY_SIZE(tm6000_boards))
1227  dev->model = card[nr];
1228 
1229  dev->udev = usbdev;
1230  dev->devno = nr;
1231 
1232  switch (usbdev->speed) {
1233  case USB_SPEED_LOW:
1234  speed = "1.5";
1235  break;
1236  case USB_SPEED_UNKNOWN:
1237  case USB_SPEED_FULL:
1238  speed = "12";
1239  break;
1240  case USB_SPEED_HIGH:
1241  speed = "480";
1242  break;
1243  default:
1244  speed = "unknown";
1245  }
1246 
1247  /* Get endpoints */
1248  for (i = 0; i < interface->num_altsetting; i++) {
1249  int ep;
1250 
1251  for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
1252  struct usb_host_endpoint *e;
1253  int dir_out;
1254 
1255  e = &interface->altsetting[i].endpoint[ep];
1256 
1257  dir_out = ((e->desc.bEndpointAddress &
1259 
1260  printk(KERN_INFO "tm6000: alt %d, interface %i, class %i\n",
1261  i,
1262  interface->altsetting[i].desc.bInterfaceNumber,
1263  interface->altsetting[i].desc.bInterfaceClass);
1264 
1265  switch (e->desc.bmAttributes) {
1267  if (!dir_out) {
1268  get_max_endpoint(usbdev,
1269  &interface->altsetting[i],
1270  "Bulk IN", e,
1271  &dev->bulk_in);
1272  } else {
1273  get_max_endpoint(usbdev,
1274  &interface->altsetting[i],
1275  "Bulk OUT", e,
1276  &dev->bulk_out);
1277  }
1278  break;
1280  if (!dir_out) {
1281  get_max_endpoint(usbdev,
1282  &interface->altsetting[i],
1283  "ISOC IN", e,
1284  &dev->isoc_in);
1285  } else {
1286  get_max_endpoint(usbdev,
1287  &interface->altsetting[i],
1288  "ISOC OUT", e,
1289  &dev->isoc_out);
1290  }
1291  break;
1292  case USB_ENDPOINT_XFER_INT:
1293  if (!dir_out) {
1294  get_max_endpoint(usbdev,
1295  &interface->altsetting[i],
1296  "INT IN", e,
1297  &dev->int_in);
1298  } else {
1299  get_max_endpoint(usbdev,
1300  &interface->altsetting[i],
1301  "INT OUT", e,
1302  &dev->int_out);
1303  }
1304  break;
1305  }
1306  }
1307  }
1308 
1309 
1310  printk(KERN_INFO "tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n",
1311  speed,
1312  le16_to_cpu(dev->udev->descriptor.idVendor),
1313  le16_to_cpu(dev->udev->descriptor.idProduct),
1314  interface->altsetting->desc.bInterfaceNumber);
1315 
1316 /* check if the the device has the iso in endpoint at the correct place */
1317  if (!dev->isoc_in.endp) {
1318  printk(KERN_ERR "tm6000: probing error: no IN ISOC endpoint!\n");
1319  rc = -ENODEV;
1320 
1321  goto err;
1322  }
1323 
1324  /* save our data pointer in this interface device */
1325  usb_set_intfdata(interface, dev);
1326 
1327  printk(KERN_INFO "tm6000: Found %s\n", tm6000_boards[dev->model].name);
1328 
1329  rc = tm6000_init_dev(dev);
1330  if (rc < 0)
1331  goto err;
1332 
1333  return 0;
1334 
1335 err:
1336  printk(KERN_ERR "tm6000: Error %d while registering\n", rc);
1337 
1338  clear_bit(nr, &tm6000_devused);
1339  usb_put_dev(usbdev);
1340 
1341  kfree(dev);
1342  return rc;
1343 }
1344 
1345 /*
1346  * tm6000_usb_disconnect()
1347  * called when the device gets diconencted
1348  * video device will be unregistered on v4l2_close in case it is still open
1349  */
1350 static void tm6000_usb_disconnect(struct usb_interface *interface)
1351 {
1352  struct tm6000_core *dev = usb_get_intfdata(interface);
1353  usb_set_intfdata(interface, NULL);
1354 
1355  if (!dev)
1356  return;
1357 
1358  printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name);
1359 
1360  flush_request_modules(dev);
1361 
1362  tm6000_ir_fini(dev);
1363 
1364  if (dev->gpio.power_led) {
1365  switch (dev->model) {
1369  /* Power led off */
1371  dev->gpio.power_led, 0x01);
1372  msleep(15);
1373  break;
1378  /* Power led off */
1380  dev->gpio.power_led, 0x00);
1381  msleep(15);
1382  break;
1383  }
1384  }
1386 
1387  tm6000_i2c_unregister(dev);
1388 
1390 
1391  dev->state |= DEV_DISCONNECTED;
1392 
1393  usb_put_dev(dev->udev);
1394 
1397 
1398  clear_bit(dev->devno, &tm6000_devused);
1399  kfree(dev);
1400 }
1401 
1402 static struct usb_driver tm6000_usb_driver = {
1403  .name = "tm6000",
1404  .probe = tm6000_usb_probe,
1405  .disconnect = tm6000_usb_disconnect,
1406  .id_table = tm6000_id_table,
1407 };
1408 
1409 module_usb_driver(tm6000_usb_driver);
1410 
1411 MODULE_DESCRIPTION("Trident TVMaster TM5600/TM6000/TM6010 USB2 adapter");
1412 MODULE_AUTHOR("Mauro Carvalho Chehab");
1413 MODULE_LICENSE("GPL");