added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / media / video / em28xx / em28xx-cards.c
blob3b3ca3f46d52e1f78e67a94dc831d0565be92dd4
1 /*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB
3 video capture devices
5 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
6 Markus Rechberger <mrechberger@gmail.com>
7 Mauro Carvalho Chehab <mchehab@infradead.org>
8 Sascha Sommer <saschasommer@freenet.de>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/delay.h>
28 #include <linux/i2c.h>
29 #include <linux/usb.h>
30 #include <media/tuner.h>
31 #include <media/msp3400.h>
32 #include <media/saa7115.h>
33 #include <media/tvp5150.h>
34 #include <media/tveeprom.h>
35 #include <media/v4l2-common.h>
36 #include <media/v4l2-chip-ident.h>
38 #include "em28xx.h"
40 #define DRIVER_NAME "em28xx"
42 static int tuner = -1;
43 module_param(tuner, int, 0444);
44 MODULE_PARM_DESC(tuner, "tuner type");
46 static unsigned int disable_ir;
47 module_param(disable_ir, int, 0444);
48 MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
50 static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
51 module_param_array(card, int, NULL, 0444);
52 MODULE_PARM_DESC(card, "card type");
54 /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
55 static unsigned long em28xx_devused;
57 struct em28xx_hash_table {
58 unsigned long hash;
59 unsigned int model;
60 unsigned int tuner;
64 * Reset sequences for analog/digital modes
67 /* Reset for the most [analog] boards */
68 static struct em28xx_reg_seq default_analog[] = {
69 {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
70 { -1, -1, -1, -1},
73 /* Reset for the most [digital] boards */
74 static struct em28xx_reg_seq default_digital[] = {
75 {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
76 { -1, -1, -1, -1},
79 /* Board Hauppauge WinTV HVR 900 analog */
80 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
81 {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
82 {0x05, 0xff, 0x10, 10},
83 { -1, -1, -1, -1},
86 /* Board Hauppauge WinTV HVR 900 digital */
87 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
88 {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
89 {EM2880_R04_GPO, 0x04, 0x0f, 10},
90 {EM2880_R04_GPO, 0x0c, 0x0f, 10},
91 { -1, -1, -1, -1},
94 /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
95 static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
96 {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
97 { -1, -1, -1, -1},
100 /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
102 /* Board - EM2870 Kworld 355u
103 Analog - No input analog */
105 static struct em28xx_reg_seq kworld_330u_analog[] = {
106 {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
107 {EM2880_R04_GPO, 0x00, 0xff, 10},
108 { -1, -1, -1, -1},
111 static struct em28xx_reg_seq kworld_330u_digital[] = {
112 {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
113 {EM2880_R04_GPO, 0x08, 0xff, 10},
114 { -1, -1, -1, -1},
117 /* Callback for the most boards */
118 static struct em28xx_reg_seq default_tuner_gpio[] = {
119 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
120 {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
121 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
122 { -1, -1, -1, -1},
126 * Board definitions
128 struct em28xx_board em28xx_boards[] = {
129 [EM2750_BOARD_UNKNOWN] = {
130 .name = "Unknown EM2750/EM2751 webcam grabber",
131 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
132 .tuner_type = TUNER_ABSENT, /* This is a webcam */
133 .input = { {
134 .type = EM28XX_VMUX_COMPOSITE1,
135 .vmux = 0,
136 .amux = EM28XX_AMUX_VIDEO,
137 } },
139 [EM2800_BOARD_UNKNOWN] = {
140 .name = "Unknown EM2800 video grabber",
141 .is_em2800 = 1,
142 .tda9887_conf = TDA9887_PRESENT,
143 .decoder = EM28XX_SAA711X,
144 .tuner_type = TUNER_ABSENT,
145 .input = { {
146 .type = EM28XX_VMUX_COMPOSITE1,
147 .vmux = SAA7115_COMPOSITE0,
148 .amux = EM28XX_AMUX_LINE_IN,
149 }, {
150 .type = EM28XX_VMUX_SVIDEO,
151 .vmux = SAA7115_SVIDEO3,
152 .amux = EM28XX_AMUX_LINE_IN,
153 } },
155 [EM2820_BOARD_UNKNOWN] = {
156 .name = "Unknown EM2750/28xx video grabber",
157 .tuner_type = TUNER_ABSENT,
159 [EM2750_BOARD_DLCW_130] = {
160 /* Beijing Huaqi Information Digital Technology Co., Ltd */
161 .name = "Huaqi DLCW-130",
162 .valid = EM28XX_BOARD_NOT_VALIDATED,
163 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
164 .tuner_type = TUNER_ABSENT, /* This is a webcam */
165 .input = { {
166 .type = EM28XX_VMUX_COMPOSITE1,
167 .vmux = 0,
168 .amux = EM28XX_AMUX_VIDEO,
169 } },
171 [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
172 .name = "Kworld PVR TV 2800 RF",
173 .tuner_type = TUNER_TEMIC_PAL,
174 .tda9887_conf = TDA9887_PRESENT,
175 .decoder = EM28XX_SAA711X,
176 .input = { {
177 .type = EM28XX_VMUX_COMPOSITE1,
178 .vmux = SAA7115_COMPOSITE0,
179 .amux = EM28XX_AMUX_LINE_IN,
180 }, {
181 .type = EM28XX_VMUX_SVIDEO,
182 .vmux = SAA7115_SVIDEO3,
183 .amux = EM28XX_AMUX_LINE_IN,
184 } },
186 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
187 .name = "Terratec Cinergy 250 USB",
188 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
189 .tda9887_conf = TDA9887_PRESENT,
190 .decoder = EM28XX_SAA711X,
191 .input = { {
192 .type = EM28XX_VMUX_TELEVISION,
193 .vmux = SAA7115_COMPOSITE2,
194 .amux = EM28XX_AMUX_LINE_IN,
195 }, {
196 .type = EM28XX_VMUX_COMPOSITE1,
197 .vmux = SAA7115_COMPOSITE0,
198 .amux = EM28XX_AMUX_LINE_IN,
199 }, {
200 .type = EM28XX_VMUX_SVIDEO,
201 .vmux = SAA7115_SVIDEO3,
202 .amux = EM28XX_AMUX_LINE_IN,
203 } },
205 [EM2820_BOARD_PINNACLE_USB_2] = {
206 .name = "Pinnacle PCTV USB 2",
207 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
208 .tda9887_conf = TDA9887_PRESENT,
209 .decoder = EM28XX_SAA711X,
210 .input = { {
211 .type = EM28XX_VMUX_TELEVISION,
212 .vmux = SAA7115_COMPOSITE2,
213 .amux = EM28XX_AMUX_VIDEO,
214 }, {
215 .type = EM28XX_VMUX_COMPOSITE1,
216 .vmux = SAA7115_COMPOSITE0,
217 .amux = EM28XX_AMUX_LINE_IN,
218 }, {
219 .type = EM28XX_VMUX_SVIDEO,
220 .vmux = SAA7115_SVIDEO3,
221 .amux = EM28XX_AMUX_LINE_IN,
222 } },
224 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
225 .name = "Hauppauge WinTV USB 2",
226 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
227 .tda9887_conf = TDA9887_PRESENT |
228 TDA9887_PORT1_ACTIVE|
229 TDA9887_PORT2_ACTIVE,
230 .decoder = EM28XX_TVP5150,
231 .has_msp34xx = 1,
232 .input = { {
233 .type = EM28XX_VMUX_TELEVISION,
234 .vmux = TVP5150_COMPOSITE0,
235 .amux = MSP_INPUT_DEFAULT,
236 }, {
237 .type = EM28XX_VMUX_SVIDEO,
238 .vmux = TVP5150_SVIDEO,
239 .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
240 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
241 } },
243 [EM2820_BOARD_DLINK_USB_TV] = {
244 .name = "D-Link DUB-T210 TV Tuner",
245 .valid = EM28XX_BOARD_NOT_VALIDATED,
246 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
247 .tda9887_conf = TDA9887_PRESENT,
248 .decoder = EM28XX_SAA711X,
249 .input = { {
250 .type = EM28XX_VMUX_TELEVISION,
251 .vmux = SAA7115_COMPOSITE2,
252 .amux = EM28XX_AMUX_LINE_IN,
253 }, {
254 .type = EM28XX_VMUX_COMPOSITE1,
255 .vmux = SAA7115_COMPOSITE0,
256 .amux = EM28XX_AMUX_LINE_IN,
257 }, {
258 .type = EM28XX_VMUX_SVIDEO,
259 .vmux = SAA7115_SVIDEO3,
260 .amux = EM28XX_AMUX_LINE_IN,
261 } },
263 [EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
264 .name = "Hercules Smart TV USB 2.0",
265 .valid = EM28XX_BOARD_NOT_VALIDATED,
266 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
267 .tda9887_conf = TDA9887_PRESENT,
268 .decoder = EM28XX_SAA711X,
269 .input = { {
270 .type = EM28XX_VMUX_TELEVISION,
271 .vmux = SAA7115_COMPOSITE2,
272 .amux = EM28XX_AMUX_LINE_IN,
273 }, {
274 .type = EM28XX_VMUX_COMPOSITE1,
275 .vmux = SAA7115_COMPOSITE0,
276 .amux = EM28XX_AMUX_LINE_IN,
277 }, {
278 .type = EM28XX_VMUX_SVIDEO,
279 .vmux = SAA7115_SVIDEO3,
280 .amux = EM28XX_AMUX_LINE_IN,
281 } },
283 [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
284 .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
285 .valid = EM28XX_BOARD_NOT_VALIDATED,
286 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
287 .tda9887_conf = TDA9887_PRESENT,
288 .decoder = EM28XX_SAA711X,
289 .input = { {
290 .type = EM28XX_VMUX_TELEVISION,
291 .vmux = SAA7115_COMPOSITE2,
292 .amux = EM28XX_AMUX_VIDEO,
293 }, {
294 .type = EM28XX_VMUX_COMPOSITE1,
295 .vmux = SAA7115_COMPOSITE0,
296 .amux = EM28XX_AMUX_LINE_IN,
297 }, {
298 .type = EM28XX_VMUX_SVIDEO,
299 .vmux = SAA7115_SVIDEO3,
300 .amux = EM28XX_AMUX_LINE_IN,
301 } },
303 [EM2820_BOARD_GADMEI_UTV310] = {
304 .name = "Gadmei UTV310",
305 .valid = EM28XX_BOARD_NOT_VALIDATED,
306 .tuner_type = TUNER_TNF_5335MF,
307 .tda9887_conf = TDA9887_PRESENT,
308 .decoder = EM28XX_SAA711X,
309 .input = { {
310 .type = EM28XX_VMUX_TELEVISION,
311 .vmux = SAA7115_COMPOSITE1,
312 .amux = EM28XX_AMUX_LINE_IN,
313 }, {
314 .type = EM28XX_VMUX_COMPOSITE1,
315 .vmux = SAA7115_COMPOSITE0,
316 .amux = EM28XX_AMUX_LINE_IN,
317 }, {
318 .type = EM28XX_VMUX_SVIDEO,
319 .vmux = SAA7115_SVIDEO3,
320 .amux = EM28XX_AMUX_LINE_IN,
321 } },
323 [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
324 .name = "Leadtek Winfast USB II Deluxe",
325 .valid = EM28XX_BOARD_NOT_VALIDATED,
326 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
327 .tda9887_conf = TDA9887_PRESENT,
328 .decoder = EM28XX_SAA711X,
329 .input = { {
330 .type = EM28XX_VMUX_TELEVISION,
331 .vmux = SAA7115_COMPOSITE2,
332 .amux = EM28XX_AMUX_VIDEO,
333 }, {
334 .type = EM28XX_VMUX_COMPOSITE1,
335 .vmux = SAA7115_COMPOSITE0,
336 .amux = EM28XX_AMUX_LINE_IN,
337 }, {
338 .type = EM28XX_VMUX_SVIDEO,
339 .vmux = SAA7115_COMPOSITE0,
340 .amux = EM28XX_AMUX_LINE_IN,
341 } },
343 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
344 .name = "Videology 20K14XUSB USB2.0",
345 .valid = EM28XX_BOARD_NOT_VALIDATED,
346 .tuner_type = TUNER_ABSENT, /* This is a webcam */
347 .input = { {
348 .type = EM28XX_VMUX_COMPOSITE1,
349 .vmux = 0,
350 .amux = EM28XX_AMUX_VIDEO,
351 } },
353 [EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
354 .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
355 .valid = EM28XX_BOARD_NOT_VALIDATED,
356 .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */
357 .tda9887_conf = TDA9887_PRESENT, /* unknown? */
358 .decoder = EM28XX_SAA711X,
359 .input = { {
360 .type = EM28XX_VMUX_TELEVISION,
361 .vmux = SAA7115_COMPOSITE2,
362 .amux = EM28XX_AMUX_LINE_IN,
363 }, {
364 .type = EM28XX_VMUX_COMPOSITE1,
365 .vmux = SAA7115_COMPOSITE0,
366 .amux = EM28XX_AMUX_LINE_IN,
367 }, {
368 .type = EM28XX_VMUX_SVIDEO,
369 .vmux = SAA7115_SVIDEO3,
370 .amux = EM28XX_AMUX_LINE_IN,
371 } },
373 [EM2821_BOARD_SUPERCOMP_USB_2] = {
374 .name = "Supercomp USB 2.0 TV",
375 .valid = EM28XX_BOARD_NOT_VALIDATED,
376 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
377 .tda9887_conf = TDA9887_PRESENT |
378 TDA9887_PORT1_ACTIVE |
379 TDA9887_PORT2_ACTIVE,
380 .decoder = EM28XX_SAA711X,
381 .input = { {
382 .type = EM28XX_VMUX_TELEVISION,
383 .vmux = SAA7115_COMPOSITE2,
384 .amux = EM28XX_AMUX_LINE_IN,
385 }, {
386 .type = EM28XX_VMUX_COMPOSITE1,
387 .vmux = SAA7115_COMPOSITE0,
388 .amux = EM28XX_AMUX_VIDEO,
389 }, {
390 .type = EM28XX_VMUX_SVIDEO,
391 .vmux = SAA7115_SVIDEO3,
392 .amux = EM28XX_AMUX_LINE_IN,
393 } },
395 [EM2821_BOARD_USBGEAR_VD204] = {
396 .name = "Usbgear VD204v9",
397 .valid = EM28XX_BOARD_NOT_VALIDATED,
398 .tuner_type = TUNER_ABSENT, /* Capture only device */
399 .decoder = EM28XX_SAA711X,
400 .input = { {
401 .type = EM28XX_VMUX_COMPOSITE1,
402 .vmux = SAA7115_COMPOSITE0,
403 .amux = EM28XX_AMUX_LINE_IN,
404 }, {
405 .type = EM28XX_VMUX_SVIDEO,
406 .vmux = SAA7115_SVIDEO3,
407 .amux = EM28XX_AMUX_LINE_IN,
408 } },
410 [EM2860_BOARD_NETGMBH_CAM] = {
411 /* Beijing Huaqi Information Digital Technology Co., Ltd */
412 .name = "NetGMBH Cam",
413 .valid = EM28XX_BOARD_NOT_VALIDATED,
414 .tuner_type = TUNER_ABSENT, /* This is a webcam */
415 .input = { {
416 .type = EM28XX_VMUX_COMPOSITE1,
417 .vmux = 0,
418 .amux = EM28XX_AMUX_VIDEO,
419 } },
421 [EM2860_BOARD_TYPHOON_DVD_MAKER] = {
422 .name = "Typhoon DVD Maker",
423 .decoder = EM28XX_SAA711X,
424 .tuner_type = TUNER_ABSENT, /* Capture only device */
425 .input = { {
426 .type = EM28XX_VMUX_COMPOSITE1,
427 .vmux = SAA7115_COMPOSITE0,
428 .amux = EM28XX_AMUX_LINE_IN,
429 }, {
430 .type = EM28XX_VMUX_SVIDEO,
431 .vmux = SAA7115_SVIDEO3,
432 .amux = EM28XX_AMUX_LINE_IN,
433 } },
435 [EM2860_BOARD_GADMEI_UTV330] = {
436 .name = "Gadmei UTV330",
437 .valid = EM28XX_BOARD_NOT_VALIDATED,
438 .tuner_type = TUNER_TNF_5335MF,
439 .tda9887_conf = TDA9887_PRESENT,
440 .decoder = EM28XX_SAA711X,
441 .input = { {
442 .type = EM28XX_VMUX_TELEVISION,
443 .vmux = SAA7115_COMPOSITE2,
444 .amux = EM28XX_AMUX_VIDEO,
445 }, {
446 .type = EM28XX_VMUX_COMPOSITE1,
447 .vmux = SAA7115_COMPOSITE0,
448 .amux = EM28XX_AMUX_LINE_IN,
449 }, {
450 .type = EM28XX_VMUX_SVIDEO,
451 .vmux = SAA7115_SVIDEO3,
452 .amux = EM28XX_AMUX_LINE_IN,
453 } },
455 [EM2860_BOARD_TERRATEC_HYBRID_XS] = {
456 .name = "Terratec Cinergy A Hybrid XS",
457 .valid = EM28XX_BOARD_NOT_VALIDATED,
458 .tuner_type = TUNER_XC2028,
459 .tuner_gpio = default_tuner_gpio,
460 .decoder = EM28XX_TVP5150,
462 .input = { {
463 .type = EM28XX_VMUX_TELEVISION,
464 .vmux = TVP5150_COMPOSITE0,
465 .amux = EM28XX_AMUX_VIDEO,
466 .gpio = hauppauge_wintv_hvr_900_analog,
467 }, {
468 .type = EM28XX_VMUX_COMPOSITE1,
469 .vmux = TVP5150_COMPOSITE1,
470 .amux = EM28XX_AMUX_LINE_IN,
471 .gpio = hauppauge_wintv_hvr_900_analog,
472 }, {
473 .type = EM28XX_VMUX_SVIDEO,
474 .vmux = TVP5150_SVIDEO,
475 .amux = EM28XX_AMUX_LINE_IN,
476 .gpio = hauppauge_wintv_hvr_900_analog,
477 } },
479 [EM2861_BOARD_KWORLD_PVRTV_300U] = {
480 .name = "KWorld PVRTV 300U",
481 .valid = EM28XX_BOARD_NOT_VALIDATED,
482 .tuner_type = TUNER_XC2028,
483 .tuner_gpio = default_tuner_gpio,
484 .decoder = EM28XX_TVP5150,
485 .input = { {
486 .type = EM28XX_VMUX_TELEVISION,
487 .vmux = TVP5150_COMPOSITE0,
488 .amux = EM28XX_AMUX_VIDEO,
489 }, {
490 .type = EM28XX_VMUX_COMPOSITE1,
491 .vmux = TVP5150_COMPOSITE1,
492 .amux = EM28XX_AMUX_LINE_IN,
493 }, {
494 .type = EM28XX_VMUX_SVIDEO,
495 .vmux = TVP5150_SVIDEO,
496 .amux = EM28XX_AMUX_LINE_IN,
497 } },
499 [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
500 .name = "Yakumo MovieMixer",
501 .tuner_type = TUNER_ABSENT, /* Capture only device */
502 .decoder = EM28XX_TVP5150,
503 .input = { {
504 .type = EM28XX_VMUX_TELEVISION,
505 .vmux = TVP5150_COMPOSITE0,
506 .amux = EM28XX_AMUX_VIDEO,
507 }, {
508 .type = EM28XX_VMUX_COMPOSITE1,
509 .vmux = TVP5150_COMPOSITE1,
510 .amux = EM28XX_AMUX_LINE_IN,
511 }, {
512 .type = EM28XX_VMUX_SVIDEO,
513 .vmux = TVP5150_SVIDEO,
514 .amux = EM28XX_AMUX_LINE_IN,
515 } },
517 [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
518 .name = "Plextor ConvertX PX-TV100U",
519 .valid = EM28XX_BOARD_NOT_VALIDATED,
520 .tuner_type = TUNER_TNF_5335MF,
521 .tda9887_conf = TDA9887_PRESENT,
522 .decoder = EM28XX_TVP5150,
523 .input = { {
524 .type = EM28XX_VMUX_TELEVISION,
525 .vmux = TVP5150_COMPOSITE0,
526 .amux = EM28XX_AMUX_LINE_IN,
527 }, {
528 .type = EM28XX_VMUX_COMPOSITE1,
529 .vmux = TVP5150_COMPOSITE1,
530 .amux = EM28XX_AMUX_LINE_IN,
531 }, {
532 .type = EM28XX_VMUX_SVIDEO,
533 .vmux = TVP5150_SVIDEO,
534 .amux = EM28XX_AMUX_LINE_IN,
535 } },
538 /* Those boards with em2870 are DVB Only*/
540 [EM2870_BOARD_TERRATEC_XS] = {
541 .name = "Terratec Cinergy T XS",
542 .valid = EM28XX_BOARD_NOT_VALIDATED,
543 .tuner_type = TUNER_XC2028,
544 .tuner_gpio = default_tuner_gpio,
546 [EM2870_BOARD_TERRATEC_XS_MT2060] = {
547 .name = "Terratec Cinergy T XS (MT2060)",
548 .valid = EM28XX_BOARD_NOT_VALIDATED,
549 .tuner_type = TUNER_ABSENT, /* MT2060 */
551 [EM2870_BOARD_KWORLD_350U] = {
552 .name = "Kworld 350 U DVB-T",
553 .valid = EM28XX_BOARD_NOT_VALIDATED,
554 .tuner_type = TUNER_XC2028,
555 .tuner_gpio = default_tuner_gpio,
557 [EM2870_BOARD_KWORLD_355U] = {
558 .name = "Kworld 355 U DVB-T",
559 .valid = EM28XX_BOARD_NOT_VALIDATED,
561 [EM2870_BOARD_PINNACLE_PCTV_DVB] = {
562 .name = "Pinnacle PCTV DVB-T",
563 .valid = EM28XX_BOARD_NOT_VALIDATED,
564 .tuner_type = TUNER_ABSENT, /* MT2060 */
565 /* djh - I have serious doubts this is right... */
566 .xclk = EM28XX_XCLK_IR_RC5_MODE |
567 EM28XX_XCLK_FREQUENCY_10MHZ,
569 [EM2870_BOARD_COMPRO_VIDEOMATE] = {
570 .name = "Compro, VideoMate U3",
571 .valid = EM28XX_BOARD_NOT_VALIDATED,
572 .tuner_type = TUNER_ABSENT, /* MT2060 */
575 [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
576 .name = "Terratec Hybrid XS Secam",
577 .valid = EM28XX_BOARD_NOT_VALIDATED,
578 .has_msp34xx = 1,
579 .tuner_type = TUNER_XC2028,
580 .tuner_gpio = default_tuner_gpio,
581 .decoder = EM28XX_TVP5150,
582 .input = { {
583 .type = EM28XX_VMUX_TELEVISION,
584 .vmux = TVP5150_COMPOSITE0,
585 .amux = EM28XX_AMUX_VIDEO,
586 .gpio = default_analog,
587 }, {
588 .type = EM28XX_VMUX_COMPOSITE1,
589 .vmux = TVP5150_COMPOSITE1,
590 .amux = EM28XX_AMUX_LINE_IN,
591 .gpio = default_analog,
592 }, {
593 .type = EM28XX_VMUX_SVIDEO,
594 .vmux = TVP5150_SVIDEO,
595 .amux = EM28XX_AMUX_LINE_IN,
596 .gpio = default_analog,
597 } },
599 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
600 .name = "Hauppauge WinTV HVR 900",
601 .tda9887_conf = TDA9887_PRESENT,
602 .tuner_type = TUNER_XC2028,
603 .tuner_gpio = default_tuner_gpio,
604 .mts_firmware = 1,
605 .has_dvb = 1,
606 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
607 .decoder = EM28XX_TVP5150,
608 .input = { {
609 .type = EM28XX_VMUX_TELEVISION,
610 .vmux = TVP5150_COMPOSITE0,
611 .amux = EM28XX_AMUX_VIDEO,
612 .gpio = hauppauge_wintv_hvr_900_analog,
613 }, {
614 .type = EM28XX_VMUX_COMPOSITE1,
615 .vmux = TVP5150_COMPOSITE1,
616 .amux = EM28XX_AMUX_LINE_IN,
617 .gpio = hauppauge_wintv_hvr_900_analog,
618 }, {
619 .type = EM28XX_VMUX_SVIDEO,
620 .vmux = TVP5150_SVIDEO,
621 .amux = EM28XX_AMUX_LINE_IN,
622 .gpio = hauppauge_wintv_hvr_900_analog,
623 } },
625 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
626 .name = "Hauppauge WinTV HVR 900 (R2)",
627 .tda9887_conf = TDA9887_PRESENT,
628 .tuner_type = TUNER_XC2028,
629 .tuner_gpio = default_tuner_gpio,
630 .mts_firmware = 1,
631 .decoder = EM28XX_TVP5150,
632 .input = { {
633 .type = EM28XX_VMUX_TELEVISION,
634 .vmux = TVP5150_COMPOSITE0,
635 .amux = EM28XX_AMUX_VIDEO,
636 .gpio = hauppauge_wintv_hvr_900_analog,
637 }, {
638 .type = EM28XX_VMUX_COMPOSITE1,
639 .vmux = TVP5150_COMPOSITE1,
640 .amux = EM28XX_AMUX_LINE_IN,
641 .gpio = hauppauge_wintv_hvr_900_analog,
642 }, {
643 .type = EM28XX_VMUX_SVIDEO,
644 .vmux = TVP5150_SVIDEO,
645 .amux = EM28XX_AMUX_LINE_IN,
646 .gpio = hauppauge_wintv_hvr_900_analog,
647 } },
649 [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = {
650 .name = "Hauppauge WinTV HVR 850",
651 .tuner_type = TUNER_XC2028,
652 .tuner_gpio = default_tuner_gpio,
653 .mts_firmware = 1,
654 .has_dvb = 1,
655 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
656 .ir_codes = ir_codes_hauppauge_new,
657 .decoder = EM28XX_TVP5150,
658 .input = { {
659 .type = EM28XX_VMUX_TELEVISION,
660 .vmux = TVP5150_COMPOSITE0,
661 .amux = EM28XX_AMUX_VIDEO,
662 .gpio = hauppauge_wintv_hvr_900_analog,
663 }, {
664 .type = EM28XX_VMUX_COMPOSITE1,
665 .vmux = TVP5150_COMPOSITE1,
666 .amux = EM28XX_AMUX_LINE_IN,
667 .gpio = hauppauge_wintv_hvr_900_analog,
668 }, {
669 .type = EM28XX_VMUX_SVIDEO,
670 .vmux = TVP5150_SVIDEO,
671 .amux = EM28XX_AMUX_LINE_IN,
672 .gpio = hauppauge_wintv_hvr_900_analog,
673 } },
675 [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
676 .name = "Hauppauge WinTV HVR 950",
677 .tuner_type = TUNER_XC2028,
678 .tuner_gpio = default_tuner_gpio,
679 .mts_firmware = 1,
680 .has_dvb = 1,
681 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
682 .ir_codes = ir_codes_hauppauge_new,
683 .decoder = EM28XX_TVP5150,
684 .input = { {
685 .type = EM28XX_VMUX_TELEVISION,
686 .vmux = TVP5150_COMPOSITE0,
687 .amux = EM28XX_AMUX_VIDEO,
688 .gpio = hauppauge_wintv_hvr_900_analog,
689 }, {
690 .type = EM28XX_VMUX_COMPOSITE1,
691 .vmux = TVP5150_COMPOSITE1,
692 .amux = EM28XX_AMUX_LINE_IN,
693 .gpio = hauppauge_wintv_hvr_900_analog,
694 }, {
695 .type = EM28XX_VMUX_SVIDEO,
696 .vmux = TVP5150_SVIDEO,
697 .amux = EM28XX_AMUX_LINE_IN,
698 .gpio = hauppauge_wintv_hvr_900_analog,
699 } },
701 [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
702 .name = "Pinnacle PCTV HD Pro Stick",
703 .tuner_type = TUNER_XC2028,
704 .tuner_gpio = default_tuner_gpio,
705 .mts_firmware = 1,
706 .has_dvb = 1,
707 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
708 .ir_codes = ir_codes_pinnacle_pctv_hd,
709 .decoder = EM28XX_TVP5150,
710 .input = { {
711 .type = EM28XX_VMUX_TELEVISION,
712 .vmux = TVP5150_COMPOSITE0,
713 .amux = EM28XX_AMUX_VIDEO,
714 .gpio = hauppauge_wintv_hvr_900_analog,
715 }, {
716 .type = EM28XX_VMUX_COMPOSITE1,
717 .vmux = TVP5150_COMPOSITE1,
718 .amux = EM28XX_AMUX_LINE_IN,
719 .gpio = hauppauge_wintv_hvr_900_analog,
720 }, {
721 .type = EM28XX_VMUX_SVIDEO,
722 .vmux = TVP5150_SVIDEO,
723 .amux = EM28XX_AMUX_LINE_IN,
724 .gpio = hauppauge_wintv_hvr_900_analog,
725 } },
727 [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
728 .name = "AMD ATI TV Wonder HD 600",
729 .tuner_type = TUNER_XC2028,
730 .tuner_gpio = default_tuner_gpio,
731 .mts_firmware = 1,
732 .has_dvb = 1,
733 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
734 .ir_codes = ir_codes_ati_tv_wonder_hd_600,
735 .decoder = EM28XX_TVP5150,
736 .input = { {
737 .type = EM28XX_VMUX_TELEVISION,
738 .vmux = TVP5150_COMPOSITE0,
739 .amux = EM28XX_AMUX_VIDEO,
740 .gpio = hauppauge_wintv_hvr_900_analog,
741 }, {
742 .type = EM28XX_VMUX_COMPOSITE1,
743 .vmux = TVP5150_COMPOSITE1,
744 .amux = EM28XX_AMUX_LINE_IN,
745 .gpio = hauppauge_wintv_hvr_900_analog,
746 }, {
747 .type = EM28XX_VMUX_SVIDEO,
748 .vmux = TVP5150_SVIDEO,
749 .amux = EM28XX_AMUX_LINE_IN,
750 .gpio = hauppauge_wintv_hvr_900_analog,
751 } },
753 [EM2880_BOARD_TERRATEC_HYBRID_XS] = {
754 .name = "Terratec Hybrid XS",
755 .tuner_type = TUNER_XC2028,
756 .tuner_gpio = default_tuner_gpio,
757 .decoder = EM28XX_TVP5150,
758 .has_dvb = 1,
759 .dvb_gpio = default_analog,
760 .input = { {
761 .type = EM28XX_VMUX_TELEVISION,
762 .vmux = TVP5150_COMPOSITE0,
763 .amux = EM28XX_AMUX_VIDEO,
764 .gpio = default_analog,
765 }, {
766 .type = EM28XX_VMUX_COMPOSITE1,
767 .vmux = TVP5150_COMPOSITE1,
768 .amux = EM28XX_AMUX_LINE_IN,
769 .gpio = default_analog,
770 }, {
771 .type = EM28XX_VMUX_SVIDEO,
772 .vmux = TVP5150_SVIDEO,
773 .amux = EM28XX_AMUX_LINE_IN,
774 .gpio = default_analog,
775 } },
777 /* maybe there's a reason behind it why Terratec sells the Hybrid XS
778 as Prodigy XS with a different PID, let's keep it separated for now
779 maybe we'll need it lateron */
780 [EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
781 .name = "Terratec Prodigy XS",
782 .tuner_type = TUNER_XC2028,
783 .tuner_gpio = default_tuner_gpio,
784 .decoder = EM28XX_TVP5150,
785 .input = { {
786 .type = EM28XX_VMUX_TELEVISION,
787 .vmux = TVP5150_COMPOSITE0,
788 .amux = EM28XX_AMUX_VIDEO,
789 .gpio = hauppauge_wintv_hvr_900_analog,
790 }, {
791 .type = EM28XX_VMUX_COMPOSITE1,
792 .vmux = TVP5150_COMPOSITE1,
793 .amux = EM28XX_AMUX_LINE_IN,
794 .gpio = hauppauge_wintv_hvr_900_analog,
795 }, {
796 .type = EM28XX_VMUX_SVIDEO,
797 .vmux = TVP5150_SVIDEO,
798 .amux = EM28XX_AMUX_LINE_IN,
799 .gpio = hauppauge_wintv_hvr_900_analog,
800 } },
802 [EM2820_BOARD_MSI_VOX_USB_2] = {
803 .name = "MSI VOX USB 2.0",
804 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
805 .tda9887_conf = TDA9887_PRESENT |
806 TDA9887_PORT1_ACTIVE |
807 TDA9887_PORT2_ACTIVE,
808 .max_range_640_480 = 1,
809 .decoder = EM28XX_SAA711X,
810 .input = { {
811 .type = EM28XX_VMUX_TELEVISION,
812 .vmux = SAA7115_COMPOSITE4,
813 .amux = EM28XX_AMUX_VIDEO,
814 }, {
815 .type = EM28XX_VMUX_COMPOSITE1,
816 .vmux = SAA7115_COMPOSITE0,
817 .amux = EM28XX_AMUX_LINE_IN,
818 }, {
819 .type = EM28XX_VMUX_SVIDEO,
820 .vmux = SAA7115_SVIDEO3,
821 .amux = EM28XX_AMUX_LINE_IN,
822 } },
824 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
825 .name = "Terratec Cinergy 200 USB",
826 .is_em2800 = 1,
827 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
828 .tda9887_conf = TDA9887_PRESENT,
829 .decoder = EM28XX_SAA711X,
830 .input = { {
831 .type = EM28XX_VMUX_TELEVISION,
832 .vmux = SAA7115_COMPOSITE2,
833 .amux = EM28XX_AMUX_VIDEO,
834 }, {
835 .type = EM28XX_VMUX_COMPOSITE1,
836 .vmux = SAA7115_COMPOSITE0,
837 .amux = EM28XX_AMUX_LINE_IN,
838 }, {
839 .type = EM28XX_VMUX_SVIDEO,
840 .vmux = SAA7115_SVIDEO3,
841 .amux = EM28XX_AMUX_LINE_IN,
842 } },
844 [EM2800_BOARD_GRABBEEX_USB2800] = {
845 .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
846 .is_em2800 = 1,
847 .decoder = EM28XX_SAA711X,
848 .tuner_type = TUNER_ABSENT, /* capture only board */
849 .input = { {
850 .type = EM28XX_VMUX_COMPOSITE1,
851 .vmux = SAA7115_COMPOSITE0,
852 .amux = EM28XX_AMUX_LINE_IN,
853 }, {
854 .type = EM28XX_VMUX_SVIDEO,
855 .vmux = SAA7115_SVIDEO3,
856 .amux = EM28XX_AMUX_LINE_IN,
857 } },
859 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
860 .name = "Leadtek Winfast USB II",
861 .is_em2800 = 1,
862 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
863 .tda9887_conf = TDA9887_PRESENT,
864 .decoder = EM28XX_SAA711X,
865 .input = { {
866 .type = EM28XX_VMUX_TELEVISION,
867 .vmux = SAA7115_COMPOSITE2,
868 .amux = EM28XX_AMUX_VIDEO,
869 }, {
870 .type = EM28XX_VMUX_COMPOSITE1,
871 .vmux = SAA7115_COMPOSITE0,
872 .amux = EM28XX_AMUX_LINE_IN,
873 }, {
874 .type = EM28XX_VMUX_SVIDEO,
875 .vmux = SAA7115_SVIDEO3,
876 .amux = EM28XX_AMUX_LINE_IN,
877 } },
879 [EM2800_BOARD_KWORLD_USB2800] = {
880 .name = "Kworld USB2800",
881 .is_em2800 = 1,
882 .tuner_type = TUNER_PHILIPS_FCV1236D,
883 .tda9887_conf = TDA9887_PRESENT,
884 .decoder = EM28XX_SAA711X,
885 .input = { {
886 .type = EM28XX_VMUX_TELEVISION,
887 .vmux = SAA7115_COMPOSITE2,
888 .amux = EM28XX_AMUX_VIDEO,
889 }, {
890 .type = EM28XX_VMUX_COMPOSITE1,
891 .vmux = SAA7115_COMPOSITE0,
892 .amux = EM28XX_AMUX_LINE_IN,
893 }, {
894 .type = EM28XX_VMUX_SVIDEO,
895 .vmux = SAA7115_SVIDEO3,
896 .amux = EM28XX_AMUX_LINE_IN,
897 } },
899 [EM2820_BOARD_PINNACLE_DVC_90] = {
900 .name = "Pinnacle Dazzle DVC 90/DVC 100",
901 .tuner_type = TUNER_ABSENT, /* capture only board */
902 .decoder = EM28XX_SAA711X,
903 .input = { {
904 .type = EM28XX_VMUX_COMPOSITE1,
905 .vmux = SAA7115_COMPOSITE0,
906 .amux = EM28XX_AMUX_LINE_IN,
907 }, {
908 .type = EM28XX_VMUX_SVIDEO,
909 .vmux = SAA7115_SVIDEO3,
910 .amux = EM28XX_AMUX_LINE_IN,
911 } },
913 [EM2800_BOARD_VGEAR_POCKETTV] = {
914 .name = "V-Gear PocketTV",
915 .is_em2800 = 1,
916 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
917 .tda9887_conf = TDA9887_PRESENT,
918 .decoder = EM28XX_SAA711X,
919 .input = { {
920 .type = EM28XX_VMUX_TELEVISION,
921 .vmux = SAA7115_COMPOSITE2,
922 .amux = EM28XX_AMUX_VIDEO,
923 }, {
924 .type = EM28XX_VMUX_COMPOSITE1,
925 .vmux = SAA7115_COMPOSITE0,
926 .amux = EM28XX_AMUX_LINE_IN,
927 }, {
928 .type = EM28XX_VMUX_SVIDEO,
929 .vmux = SAA7115_SVIDEO3,
930 .amux = EM28XX_AMUX_LINE_IN,
931 } },
933 [EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = {
934 .name = "Pixelview PlayTV Box 4 USB 2.0",
935 .tda9887_conf = TDA9887_PRESENT,
936 .tuner_type = TUNER_YMEC_TVF_5533MF,
937 .decoder = EM28XX_SAA711X,
938 .input = { {
939 .type = EM28XX_VMUX_TELEVISION,
940 .vmux = SAA7115_COMPOSITE2,
941 .amux = EM28XX_AMUX_VIDEO,
942 .aout = EM28XX_AOUT_MONO | /* I2S */
943 EM28XX_AOUT_MASTER, /* Line out pin */
944 }, {
945 .type = EM28XX_VMUX_COMPOSITE1,
946 .vmux = SAA7115_COMPOSITE0,
947 .amux = EM28XX_AMUX_LINE_IN,
948 }, {
949 .type = EM28XX_VMUX_SVIDEO,
950 .vmux = SAA7115_SVIDEO3,
951 .amux = EM28XX_AMUX_LINE_IN,
952 } },
954 [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
955 .name = "Pixelview Prolink PlayTV USB 2.0",
956 .has_snapshot_button = 1,
957 .tda9887_conf = TDA9887_PRESENT,
958 .tuner_type = TUNER_YMEC_TVF_5533MF,
959 .decoder = EM28XX_SAA711X,
960 .input = { {
961 .type = EM28XX_VMUX_TELEVISION,
962 .vmux = SAA7115_COMPOSITE2,
963 .amux = EM28XX_AMUX_VIDEO,
964 .aout = EM28XX_AOUT_MONO | /* I2S */
965 EM28XX_AOUT_MASTER, /* Line out pin */
966 }, {
967 .type = EM28XX_VMUX_COMPOSITE1,
968 .vmux = SAA7115_COMPOSITE0,
969 .amux = EM28XX_AMUX_LINE_IN,
970 }, {
971 .type = EM28XX_VMUX_SVIDEO,
972 .vmux = SAA7115_SVIDEO3,
973 .amux = EM28XX_AMUX_LINE_IN,
974 } },
976 [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = {
977 .name = "PointNix Intra-Oral Camera",
978 .has_snapshot_button = 1,
979 .tda9887_conf = TDA9887_PRESENT,
980 .tuner_type = TUNER_ABSENT,
981 .decoder = EM28XX_SAA711X,
982 .input = { {
983 .type = EM28XX_VMUX_SVIDEO,
984 .vmux = SAA7115_SVIDEO3,
985 .amux = EM28XX_AMUX_VIDEO,
986 } },
988 [EM2880_BOARD_MSI_DIGIVOX_AD] = {
989 .name = "MSI DigiVox A/D",
990 .valid = EM28XX_BOARD_NOT_VALIDATED,
991 .tuner_type = TUNER_XC2028,
992 .tuner_gpio = default_tuner_gpio,
993 .decoder = EM28XX_TVP5150,
994 .input = { {
995 .type = EM28XX_VMUX_TELEVISION,
996 .vmux = TVP5150_COMPOSITE0,
997 .amux = EM28XX_AMUX_VIDEO,
998 .gpio = em2880_msi_digivox_ad_analog,
999 }, {
1000 .type = EM28XX_VMUX_COMPOSITE1,
1001 .vmux = TVP5150_COMPOSITE1,
1002 .amux = EM28XX_AMUX_LINE_IN,
1003 .gpio = em2880_msi_digivox_ad_analog,
1004 }, {
1005 .type = EM28XX_VMUX_SVIDEO,
1006 .vmux = TVP5150_SVIDEO,
1007 .amux = EM28XX_AMUX_LINE_IN,
1008 .gpio = em2880_msi_digivox_ad_analog,
1009 } },
1011 [EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
1012 .name = "MSI DigiVox A/D II",
1013 .valid = EM28XX_BOARD_NOT_VALIDATED,
1014 .tuner_type = TUNER_XC2028,
1015 .tuner_gpio = default_tuner_gpio,
1016 .decoder = EM28XX_TVP5150,
1017 .input = { {
1018 .type = EM28XX_VMUX_TELEVISION,
1019 .vmux = TVP5150_COMPOSITE0,
1020 .amux = EM28XX_AMUX_VIDEO,
1021 .gpio = em2880_msi_digivox_ad_analog,
1022 }, {
1023 .type = EM28XX_VMUX_COMPOSITE1,
1024 .vmux = TVP5150_COMPOSITE1,
1025 .amux = EM28XX_AMUX_LINE_IN,
1026 .gpio = em2880_msi_digivox_ad_analog,
1027 }, {
1028 .type = EM28XX_VMUX_SVIDEO,
1029 .vmux = TVP5150_SVIDEO,
1030 .amux = EM28XX_AMUX_LINE_IN,
1031 .gpio = em2880_msi_digivox_ad_analog,
1032 } },
1034 [EM2880_BOARD_KWORLD_DVB_305U] = {
1035 .name = "KWorld DVB-T 305U",
1036 .valid = EM28XX_BOARD_NOT_VALIDATED,
1037 .tuner_type = TUNER_XC2028,
1038 .tuner_gpio = default_tuner_gpio,
1039 .decoder = EM28XX_TVP5150,
1040 .input = { {
1041 .type = EM28XX_VMUX_TELEVISION,
1042 .vmux = TVP5150_COMPOSITE0,
1043 .amux = EM28XX_AMUX_VIDEO,
1044 }, {
1045 .type = EM28XX_VMUX_COMPOSITE1,
1046 .vmux = TVP5150_COMPOSITE1,
1047 .amux = EM28XX_AMUX_LINE_IN,
1048 }, {
1049 .type = EM28XX_VMUX_SVIDEO,
1050 .vmux = TVP5150_SVIDEO,
1051 .amux = EM28XX_AMUX_LINE_IN,
1052 } },
1054 [EM2880_BOARD_KWORLD_DVB_310U] = {
1055 .name = "KWorld DVB-T 310U",
1056 .tuner_type = TUNER_XC2028,
1057 .tuner_gpio = default_tuner_gpio,
1058 .has_dvb = 1,
1059 .dvb_gpio = default_digital,
1060 .mts_firmware = 1,
1061 .decoder = EM28XX_TVP5150,
1062 .input = { {
1063 .type = EM28XX_VMUX_TELEVISION,
1064 .vmux = TVP5150_COMPOSITE0,
1065 .amux = EM28XX_AMUX_VIDEO,
1066 .gpio = default_analog,
1067 }, {
1068 .type = EM28XX_VMUX_COMPOSITE1,
1069 .vmux = TVP5150_COMPOSITE1,
1070 .amux = EM28XX_AMUX_LINE_IN,
1071 .gpio = default_analog,
1072 }, { /* S-video has not been tested yet */
1073 .type = EM28XX_VMUX_SVIDEO,
1074 .vmux = TVP5150_SVIDEO,
1075 .amux = EM28XX_AMUX_LINE_IN,
1076 .gpio = default_analog,
1077 } },
1079 [EM2881_BOARD_DNT_DA2_HYBRID] = {
1080 .name = "DNT DA2 Hybrid",
1081 .valid = EM28XX_BOARD_NOT_VALIDATED,
1082 .tuner_type = TUNER_XC2028,
1083 .tuner_gpio = default_tuner_gpio,
1084 .decoder = EM28XX_TVP5150,
1085 .input = { {
1086 .type = EM28XX_VMUX_TELEVISION,
1087 .vmux = TVP5150_COMPOSITE0,
1088 .amux = EM28XX_AMUX_VIDEO,
1089 .gpio = default_analog,
1090 }, {
1091 .type = EM28XX_VMUX_COMPOSITE1,
1092 .vmux = TVP5150_COMPOSITE1,
1093 .amux = EM28XX_AMUX_LINE_IN,
1094 .gpio = default_analog,
1095 }, {
1096 .type = EM28XX_VMUX_SVIDEO,
1097 .vmux = TVP5150_SVIDEO,
1098 .amux = EM28XX_AMUX_LINE_IN,
1099 .gpio = default_analog,
1100 } },
1102 [EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
1103 .name = "Pinnacle Hybrid Pro",
1104 .valid = EM28XX_BOARD_NOT_VALIDATED,
1105 .tuner_type = TUNER_XC2028,
1106 .tuner_gpio = default_tuner_gpio,
1107 .decoder = EM28XX_TVP5150,
1108 .input = { {
1109 .type = EM28XX_VMUX_TELEVISION,
1110 .vmux = TVP5150_COMPOSITE0,
1111 .amux = EM28XX_AMUX_VIDEO,
1112 .gpio = default_analog,
1113 }, {
1114 .type = EM28XX_VMUX_COMPOSITE1,
1115 .vmux = TVP5150_COMPOSITE1,
1116 .amux = EM28XX_AMUX_LINE_IN,
1117 .gpio = default_analog,
1118 }, {
1119 .type = EM28XX_VMUX_SVIDEO,
1120 .vmux = TVP5150_SVIDEO,
1121 .amux = EM28XX_AMUX_LINE_IN,
1122 .gpio = default_analog,
1123 } },
1125 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
1126 .name = "Pinnacle Hybrid Pro (2)",
1127 .valid = EM28XX_BOARD_NOT_VALIDATED,
1128 .tuner_type = TUNER_XC2028,
1129 .tuner_gpio = default_tuner_gpio,
1130 .mts_firmware = 1,
1131 .decoder = EM28XX_TVP5150,
1132 .input = { {
1133 .type = EM28XX_VMUX_TELEVISION,
1134 .vmux = TVP5150_COMPOSITE0,
1135 .amux = EM28XX_AMUX_VIDEO,
1136 .gpio = hauppauge_wintv_hvr_900_analog,
1137 }, {
1138 .type = EM28XX_VMUX_COMPOSITE1,
1139 .vmux = TVP5150_COMPOSITE1,
1140 .amux = EM28XX_AMUX_LINE_IN,
1141 .gpio = hauppauge_wintv_hvr_900_analog,
1142 }, {
1143 .type = EM28XX_VMUX_SVIDEO,
1144 .vmux = TVP5150_SVIDEO,
1145 .amux = EM28XX_AMUX_LINE_IN,
1146 .gpio = hauppauge_wintv_hvr_900_analog,
1147 } },
1149 [EM2882_BOARD_KWORLD_VS_DVBT] = {
1150 .name = "Kworld VS-DVB-T 323UR",
1151 .valid = EM28XX_BOARD_NOT_VALIDATED,
1152 .tuner_type = TUNER_XC2028,
1153 .tuner_gpio = default_tuner_gpio,
1154 .decoder = EM28XX_TVP5150,
1155 .input = { {
1156 .type = EM28XX_VMUX_TELEVISION,
1157 .vmux = TVP5150_COMPOSITE0,
1158 .amux = EM28XX_AMUX_VIDEO,
1159 }, {
1160 .type = EM28XX_VMUX_COMPOSITE1,
1161 .vmux = TVP5150_COMPOSITE1,
1162 .amux = EM28XX_AMUX_LINE_IN,
1163 }, {
1164 .type = EM28XX_VMUX_SVIDEO,
1165 .vmux = TVP5150_SVIDEO,
1166 .amux = EM28XX_AMUX_LINE_IN,
1167 } },
1169 [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
1170 .name = "Terratec Hybrid XS (em2882)",
1171 .valid = EM28XX_BOARD_NOT_VALIDATED,
1172 .tuner_type = TUNER_XC2028,
1173 .tuner_gpio = default_tuner_gpio,
1174 .decoder = EM28XX_TVP5150,
1175 .input = { {
1176 .type = EM28XX_VMUX_TELEVISION,
1177 .vmux = TVP5150_COMPOSITE0,
1178 .amux = EM28XX_AMUX_VIDEO,
1179 .gpio = hauppauge_wintv_hvr_900_analog,
1180 }, {
1181 .type = EM28XX_VMUX_COMPOSITE1,
1182 .vmux = TVP5150_COMPOSITE1,
1183 .amux = EM28XX_AMUX_LINE_IN,
1184 .gpio = hauppauge_wintv_hvr_900_analog,
1185 }, {
1186 .type = EM28XX_VMUX_SVIDEO,
1187 .vmux = TVP5150_SVIDEO,
1188 .amux = EM28XX_AMUX_LINE_IN,
1189 .gpio = hauppauge_wintv_hvr_900_analog,
1190 } },
1192 [EM2883_BOARD_KWORLD_HYBRID_330U] = {
1193 .name = "Kworld PlusTV HD Hybrid 330",
1194 .tuner_type = TUNER_XC2028,
1195 .tuner_gpio = default_tuner_gpio,
1196 .decoder = EM28XX_TVP5150,
1197 .mts_firmware = 1,
1198 .has_dvb = 1,
1199 .dvb_gpio = kworld_330u_digital,
1200 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1201 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
1202 .input = { {
1203 .type = EM28XX_VMUX_TELEVISION,
1204 .vmux = TVP5150_COMPOSITE0,
1205 .amux = EM28XX_AMUX_VIDEO,
1206 .gpio = kworld_330u_analog,
1207 .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
1208 }, {
1209 .type = EM28XX_VMUX_COMPOSITE1,
1210 .vmux = TVP5150_COMPOSITE1,
1211 .amux = EM28XX_AMUX_LINE_IN,
1212 .gpio = kworld_330u_analog,
1213 .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
1214 }, {
1215 .type = EM28XX_VMUX_SVIDEO,
1216 .vmux = TVP5150_SVIDEO,
1217 .amux = EM28XX_AMUX_LINE_IN,
1218 .gpio = kworld_330u_analog,
1219 } },
1221 [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
1222 .name = "Compro VideoMate ForYou/Stereo",
1223 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
1224 .tda9887_conf = TDA9887_PRESENT,
1225 .decoder = EM28XX_TVP5150,
1226 .input = { {
1227 .type = EM28XX_VMUX_TELEVISION,
1228 .vmux = TVP5150_COMPOSITE0,
1229 .amux = EM28XX_AMUX_LINE_IN,
1230 }, {
1231 .type = EM28XX_VMUX_SVIDEO,
1232 .vmux = TVP5150_SVIDEO,
1233 .amux = EM28XX_AMUX_LINE_IN,
1234 } },
1237 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
1239 /* table of devices that work with this driver */
1240 struct usb_device_id em28xx_id_table [] = {
1241 { USB_DEVICE(0xeb1a, 0x2750),
1242 .driver_info = EM2750_BOARD_UNKNOWN },
1243 { USB_DEVICE(0xeb1a, 0x2751),
1244 .driver_info = EM2750_BOARD_UNKNOWN },
1245 { USB_DEVICE(0xeb1a, 0x2800),
1246 .driver_info = EM2800_BOARD_UNKNOWN },
1247 { USB_DEVICE(0xeb1a, 0x2820),
1248 .driver_info = EM2820_BOARD_UNKNOWN },
1249 { USB_DEVICE(0xeb1a, 0x2821),
1250 .driver_info = EM2820_BOARD_UNKNOWN },
1251 { USB_DEVICE(0xeb1a, 0x2860),
1252 .driver_info = EM2820_BOARD_UNKNOWN },
1253 { USB_DEVICE(0xeb1a, 0x2861),
1254 .driver_info = EM2820_BOARD_UNKNOWN },
1255 { USB_DEVICE(0xeb1a, 0x2870),
1256 .driver_info = EM2820_BOARD_UNKNOWN },
1257 { USB_DEVICE(0xeb1a, 0x2881),
1258 .driver_info = EM2820_BOARD_UNKNOWN },
1259 { USB_DEVICE(0xeb1a, 0x2883),
1260 .driver_info = EM2820_BOARD_UNKNOWN },
1261 { USB_DEVICE(0xeb1a, 0xe300),
1262 .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
1263 { USB_DEVICE(0xeb1a, 0xe305),
1264 .driver_info = EM2880_BOARD_KWORLD_DVB_305U },
1265 { USB_DEVICE(0xeb1a, 0xe310),
1266 .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
1267 { USB_DEVICE(0xeb1a, 0xa316),
1268 .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
1269 { USB_DEVICE(0xeb1a, 0xe320),
1270 .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
1271 { USB_DEVICE(0xeb1a, 0xe323),
1272 .driver_info = EM2882_BOARD_KWORLD_VS_DVBT },
1273 { USB_DEVICE(0xeb1a, 0xe350),
1274 .driver_info = EM2870_BOARD_KWORLD_350U },
1275 { USB_DEVICE(0xeb1a, 0xe355),
1276 .driver_info = EM2870_BOARD_KWORLD_355U },
1277 { USB_DEVICE(0xeb1a, 0x2801),
1278 .driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
1279 { USB_DEVICE(0xeb1a, 0xe357),
1280 .driver_info = EM2870_BOARD_KWORLD_355U },
1281 { USB_DEVICE(0x0ccd, 0x0036),
1282 .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
1283 { USB_DEVICE(0x0ccd, 0x004c),
1284 .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR },
1285 { USB_DEVICE(0x0ccd, 0x004f),
1286 .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS },
1287 { USB_DEVICE(0x0ccd, 0x005e),
1288 .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
1289 { USB_DEVICE(0x0ccd, 0x0042),
1290 .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
1291 { USB_DEVICE(0x0ccd, 0x0043),
1292 .driver_info = EM2870_BOARD_TERRATEC_XS },
1293 { USB_DEVICE(0x0ccd, 0x0047),
1294 .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
1295 { USB_DEVICE(0x185b, 0x2870),
1296 .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
1297 { USB_DEVICE(0x185b, 0x2041),
1298 .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU },
1299 { USB_DEVICE(0x2040, 0x4200),
1300 .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
1301 { USB_DEVICE(0x2040, 0x4201),
1302 .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
1303 { USB_DEVICE(0x2040, 0x6500),
1304 .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
1305 { USB_DEVICE(0x2040, 0x6502),
1306 .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
1307 { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
1308 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
1309 { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */
1310 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
1311 { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */
1312 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
1313 { USB_DEVICE(0x2040, 0x651f),
1314 .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 },
1315 { USB_DEVICE(0x0438, 0xb002),
1316 .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
1317 { USB_DEVICE(0x2001, 0xf112),
1318 .driver_info = EM2820_BOARD_DLINK_USB_TV },
1319 { USB_DEVICE(0x2304, 0x0207),
1320 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
1321 { USB_DEVICE(0x2304, 0x0208),
1322 .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
1323 { USB_DEVICE(0x2304, 0x021a),
1324 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
1325 { USB_DEVICE(0x2304, 0x0226),
1326 .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO },
1327 { USB_DEVICE(0x2304, 0x0227),
1328 .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
1329 { USB_DEVICE(0x0413, 0x6023),
1330 .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
1331 { USB_DEVICE(0x093b, 0xa005),
1332 .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
1333 { },
1335 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
1338 * EEPROM hash table for devices with generic USB IDs
1340 static struct em28xx_hash_table em28xx_eeprom_hash [] = {
1341 /* P/N: SA 60002070465 Tuner: TVF7533-MF */
1342 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
1343 {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
1344 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
1347 /* I2C devicelist hash table for devices with generic USB IDs */
1348 static struct em28xx_hash_table em28xx_i2c_hash[] = {
1349 {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
1350 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
1351 {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
1354 int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
1356 int rc = 0;
1357 struct em28xx *dev = ptr;
1359 if (dev->tuner_type != TUNER_XC2028)
1360 return 0;
1362 if (command != XC2028_TUNER_RESET)
1363 return 0;
1365 rc = em28xx_gpio_set(dev, dev->board.tuner_gpio);
1367 return rc;
1369 EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
1371 static void inline em28xx_set_model(struct em28xx *dev)
1373 memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
1375 /* Those are the default values for the majority of boards
1376 Use those values if not specified otherwise at boards entry
1378 if (!dev->board.xclk)
1379 dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE |
1380 EM28XX_XCLK_FREQUENCY_12MHZ;
1382 if (!dev->board.i2c_speed)
1383 dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
1384 EM28XX_I2C_FREQ_100_KHZ;
1387 /* Since em28xx_pre_card_setup() requires a proper dev->model,
1388 * this won't work for boards with generic PCI IDs
1390 void em28xx_pre_card_setup(struct em28xx *dev)
1392 int rc;
1394 em28xx_set_model(dev);
1396 em28xx_info("Identified as %s (card=%d)\n",
1397 dev->board.name, dev->model);
1399 /* Set the default GPO/GPIO for legacy devices */
1400 dev->reg_gpo_num = EM2880_R04_GPO;
1401 dev->reg_gpio_num = EM28XX_R08_GPIO;
1403 dev->wait_after_write = 5;
1405 /* Based on the Chip ID, set the device configuration */
1406 rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
1407 if (rc > 0) {
1408 dev->chip_id = rc;
1410 switch (dev->chip_id) {
1411 case CHIP_ID_EM2750:
1412 em28xx_info("chip ID is em2750\n");
1413 break;
1414 case CHIP_ID_EM2820:
1415 em28xx_info("chip ID is em2820\n");
1416 break;
1417 case CHIP_ID_EM2840:
1418 em28xx_info("chip ID is em2840\n");
1419 break;
1420 case CHIP_ID_EM2860:
1421 em28xx_info("chip ID is em2860\n");
1422 break;
1423 case CHIP_ID_EM2870:
1424 em28xx_info("chip ID is em2870\n");
1425 dev->wait_after_write = 0;
1426 break;
1427 case CHIP_ID_EM2874:
1428 em28xx_info("chip ID is em2874\n");
1429 dev->reg_gpio_num = EM2874_R80_GPIO;
1430 dev->wait_after_write = 0;
1431 break;
1432 case CHIP_ID_EM2883:
1433 em28xx_info("chip ID is em2882/em2883\n");
1434 dev->wait_after_write = 0;
1435 break;
1436 default:
1437 em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
1441 /* Prepopulate cached GPO register content */
1442 rc = em28xx_read_reg(dev, dev->reg_gpo_num);
1443 if (rc >= 0)
1444 dev->reg_gpo = rc;
1446 /* Set the initial XCLK and I2C clock values based on the board
1447 definition */
1448 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f);
1449 em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
1450 msleep(50);
1452 /* request some modules */
1453 switch (dev->model) {
1454 case EM2861_BOARD_PLEXTOR_PX_TV100U:
1455 /* FIXME guess */
1456 /* Turn on analog audio output */
1457 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1458 break;
1459 case EM2861_BOARD_KWORLD_PVRTV_300U:
1460 case EM2880_BOARD_KWORLD_DVB_305U:
1461 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d);
1462 msleep(10);
1463 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d);
1464 msleep(10);
1465 break;
1466 case EM2870_BOARD_COMPRO_VIDEOMATE:
1467 /* TODO: someone can do some cleanup here...
1468 not everything's needed */
1469 em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
1470 msleep(10);
1471 em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
1472 msleep(10);
1473 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1474 mdelay(70);
1475 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
1476 mdelay(70);
1477 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc);
1478 mdelay(70);
1479 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
1480 mdelay(70);
1481 break;
1482 case EM2870_BOARD_TERRATEC_XS_MT2060:
1483 /* this device needs some gpio writes to get the DVB-T
1484 demod work */
1485 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1486 mdelay(70);
1487 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
1488 mdelay(70);
1489 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1490 mdelay(70);
1491 break;
1492 case EM2870_BOARD_PINNACLE_PCTV_DVB:
1493 /* this device needs some gpio writes to get the
1494 DVB-T demod work */
1495 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1496 mdelay(70);
1497 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
1498 mdelay(70);
1499 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1500 mdelay(70);
1501 break;
1502 case EM2820_BOARD_GADMEI_UTV310:
1503 case EM2820_BOARD_MSI_VOX_USB_2:
1504 /* enables audio for that devices */
1505 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1506 break;
1509 em28xx_gpio_set(dev, dev->board.tuner_gpio);
1510 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
1512 /* Unlock device */
1513 em28xx_set_mode(dev, EM28XX_SUSPEND);
1516 static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
1518 memset(ctl, 0, sizeof(*ctl));
1520 ctl->fname = XC2028_DEFAULT_FIRMWARE;
1521 ctl->max_len = 64;
1522 ctl->mts = em28xx_boards[dev->model].mts_firmware;
1524 switch (dev->model) {
1525 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
1526 ctl->demod = XC3028_FE_ZARLINK456;
1527 break;
1528 case EM2880_BOARD_TERRATEC_HYBRID_XS:
1529 ctl->demod = XC3028_FE_ZARLINK456;
1530 break;
1531 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
1532 /* djh - Not sure which demod we need here */
1533 ctl->demod = XC3028_FE_DEFAULT;
1534 break;
1535 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
1536 ctl->demod = XC3028_FE_DEFAULT;
1537 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
1538 break;
1539 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
1540 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
1541 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
1542 /* FIXME: Better to specify the needed IF */
1543 ctl->demod = XC3028_FE_DEFAULT;
1544 break;
1545 case EM2883_BOARD_KWORLD_HYBRID_330U:
1546 ctl->demod = XC3028_FE_CHINA;
1547 ctl->fname = XC2028_DEFAULT_FIRMWARE;
1548 break;
1549 default:
1550 ctl->demod = XC3028_FE_OREN538;
1554 static void em28xx_config_tuner(struct em28xx *dev)
1556 struct v4l2_priv_tun_config xc2028_cfg;
1557 struct tuner_setup tun_setup;
1558 struct v4l2_frequency f;
1560 if (dev->tuner_type == TUNER_ABSENT)
1561 return;
1563 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
1564 tun_setup.type = dev->tuner_type;
1565 tun_setup.addr = dev->tuner_addr;
1566 tun_setup.tuner_callback = em28xx_tuner_callback;
1568 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
1570 if (dev->tuner_type == TUNER_XC2028) {
1571 struct xc2028_ctrl ctl;
1573 em28xx_setup_xc3028(dev, &ctl);
1575 xc2028_cfg.tuner = TUNER_XC2028;
1576 xc2028_cfg.priv = &ctl;
1578 em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
1581 /* configure tuner */
1582 f.tuner = 0;
1583 f.type = V4L2_TUNER_ANALOG_TV;
1584 f.frequency = 9076; /* just a magic number */
1585 dev->ctl_freq = f.frequency;
1586 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
1589 static int em28xx_hint_board(struct em28xx *dev)
1591 int i;
1593 /* HINT method: EEPROM
1595 * This method works only for boards with eeprom.
1596 * Uses a hash of all eeprom bytes. The hash should be
1597 * unique for a vendor/tuner pair.
1598 * There are a high chance that tuners for different
1599 * video standards produce different hashes.
1601 for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) {
1602 if (dev->hash == em28xx_eeprom_hash[i].hash) {
1603 dev->model = em28xx_eeprom_hash[i].model;
1604 dev->tuner_type = em28xx_eeprom_hash[i].tuner;
1606 em28xx_errdev("Your board has no unique USB ID.\n");
1607 em28xx_errdev("A hint were successfully done, "
1608 "based on eeprom hash.\n");
1609 em28xx_errdev("This method is not 100%% failproof.\n");
1610 em28xx_errdev("If the board were missdetected, "
1611 "please email this log to:\n");
1612 em28xx_errdev("\tV4L Mailing List "
1613 " <video4linux-list@redhat.com>\n");
1614 em28xx_errdev("Board detected as %s\n",
1615 em28xx_boards[dev->model].name);
1617 return 0;
1621 /* HINT method: I2C attached devices
1623 * This method works for all boards.
1624 * Uses a hash of i2c scanned devices.
1625 * Devices with the same i2c attached chips will
1626 * be considered equal.
1627 * This method is less precise than the eeprom one.
1630 /* user did not request i2c scanning => do it now */
1631 if (!dev->i2c_hash)
1632 em28xx_do_i2c_scan(dev);
1634 for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) {
1635 if (dev->i2c_hash == em28xx_i2c_hash[i].hash) {
1636 dev->model = em28xx_i2c_hash[i].model;
1637 dev->tuner_type = em28xx_i2c_hash[i].tuner;
1638 em28xx_errdev("Your board has no unique USB ID.\n");
1639 em28xx_errdev("A hint were successfully done, "
1640 "based on i2c devicelist hash.\n");
1641 em28xx_errdev("This method is not 100%% failproof.\n");
1642 em28xx_errdev("If the board were missdetected, "
1643 "please email this log to:\n");
1644 em28xx_errdev("\tV4L Mailing List "
1645 " <video4linux-list@redhat.com>\n");
1646 em28xx_errdev("Board detected as %s\n",
1647 em28xx_boards[dev->model].name);
1649 return 0;
1653 em28xx_errdev("Your board has no unique USB ID and thus need a "
1654 "hint to be detected.\n");
1655 em28xx_errdev("You may try to use card=<n> insmod option to "
1656 "workaround that.\n");
1657 em28xx_errdev("Please send an email with this log to:\n");
1658 em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
1659 em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
1660 em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
1662 em28xx_errdev("Here is a list of valid choices for the card=<n>"
1663 " insmod option:\n");
1664 for (i = 0; i < em28xx_bcount; i++) {
1665 em28xx_errdev(" card=%d -> %s\n",
1666 i, em28xx_boards[i].name);
1668 return -1;
1671 /* ----------------------------------------------------------------------- */
1672 void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
1674 if (disable_ir) {
1675 ir->get_key = NULL;
1676 return ;
1679 /* detect & configure */
1680 switch (dev->model) {
1681 case (EM2800_BOARD_UNKNOWN):
1682 break;
1683 case (EM2820_BOARD_UNKNOWN):
1684 break;
1685 case (EM2800_BOARD_TERRATEC_CINERGY_200):
1686 case (EM2820_BOARD_TERRATEC_CINERGY_250):
1687 ir->ir_codes = ir_codes_em_terratec;
1688 ir->get_key = em28xx_get_key_terratec;
1689 snprintf(ir->c.name, sizeof(ir->c.name),
1690 "i2c IR (EM28XX Terratec)");
1691 break;
1692 case (EM2820_BOARD_PINNACLE_USB_2):
1693 ir->ir_codes = ir_codes_pinnacle_grey;
1694 ir->get_key = em28xx_get_key_pinnacle_usb_grey;
1695 snprintf(ir->c.name, sizeof(ir->c.name),
1696 "i2c IR (EM28XX Pinnacle PCTV)");
1697 break;
1698 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
1699 ir->ir_codes = ir_codes_hauppauge_new;
1700 ir->get_key = em28xx_get_key_em_haup;
1701 snprintf(ir->c.name, sizeof(ir->c.name),
1702 "i2c IR (EM2840 Hauppauge)");
1703 break;
1704 case (EM2820_BOARD_MSI_VOX_USB_2):
1705 break;
1706 case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
1707 break;
1708 case (EM2800_BOARD_KWORLD_USB2800):
1709 break;
1710 case (EM2800_BOARD_GRABBEEX_USB2800):
1711 break;
1715 void em28xx_card_setup(struct em28xx *dev)
1717 em28xx_set_model(dev);
1719 dev->tuner_type = em28xx_boards[dev->model].tuner_type;
1720 if (em28xx_boards[dev->model].tuner_addr)
1721 dev->tuner_addr = em28xx_boards[dev->model].tuner_addr;
1723 /* request some modules */
1724 switch (dev->model) {
1725 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
1726 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
1727 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
1728 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
1729 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
1731 struct tveeprom tv;
1732 #ifdef CONFIG_MODULES
1733 request_module("tveeprom");
1734 #endif
1735 /* Call first TVeeprom */
1737 dev->i2c_client.addr = 0xa0 >> 1;
1738 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
1740 dev->tuner_type = tv.tuner_type;
1742 if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
1743 dev->i2s_speed = 2048000;
1744 dev->board.has_msp34xx = 1;
1746 #ifdef CONFIG_MODULES
1747 if (tv.has_ir)
1748 request_module("ir-kbd-i2c");
1749 #endif
1750 break;
1752 case EM2820_BOARD_KWORLD_PVRTV2800RF:
1753 /* GPIO enables sound on KWORLD PVR TV 2800RF */
1754 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
1755 break;
1756 case EM2820_BOARD_UNKNOWN:
1757 case EM2800_BOARD_UNKNOWN:
1759 * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
1761 * This occurs because they share identical USB vendor and
1762 * product IDs.
1764 * What we do here is look up the EEPROM hash of the K-WORLD
1765 * and if it is found then we decide that we do not have
1766 * a DIGIVOX and reset the device to the K-WORLD instead.
1768 * This solution is only valid if they do not share eeprom
1769 * hash identities which has not been determined as yet.
1771 case EM2880_BOARD_MSI_DIGIVOX_AD:
1772 if (!em28xx_hint_board(dev))
1773 em28xx_set_model(dev);
1774 break;
1777 if (dev->board.has_snapshot_button)
1778 em28xx_register_snapshot_button(dev);
1780 if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) {
1781 em28xx_errdev("\n\n");
1782 em28xx_errdev("The support for this board weren't "
1783 "valid yet.\n");
1784 em28xx_errdev("Please send a report of having this working\n");
1785 em28xx_errdev("not to V4L mailing list (and/or to other "
1786 "addresses)\n\n");
1789 /* Allow override tuner type by a module parameter */
1790 if (tuner >= 0)
1791 dev->tuner_type = tuner;
1793 #ifdef CONFIG_MODULES
1794 /* request some modules */
1795 if (dev->board.has_msp34xx)
1796 request_module("msp3400");
1797 if (dev->board.decoder == EM28XX_SAA711X)
1798 request_module("saa7115");
1799 if (dev->board.decoder == EM28XX_TVP5150)
1800 request_module("tvp5150");
1801 if (dev->board.tuner_type != TUNER_ABSENT)
1802 request_module("tuner");
1803 #endif
1805 em28xx_config_tuner(dev);
1807 em28xx_ir_init(dev);
1811 #if defined(CONFIG_MODULES) && defined(MODULE)
1812 static void request_module_async(struct work_struct *work)
1814 struct em28xx *dev = container_of(work,
1815 struct em28xx, request_module_wk);
1817 if (dev->has_audio_class)
1818 request_module("snd-usb-audio");
1819 else if (dev->has_alsa_audio)
1820 request_module("em28xx-alsa");
1822 if (dev->board.has_dvb)
1823 request_module("em28xx-dvb");
1826 static void request_modules(struct em28xx *dev)
1828 INIT_WORK(&dev->request_module_wk, request_module_async);
1829 schedule_work(&dev->request_module_wk);
1831 #else
1832 #define request_modules(dev)
1833 #endif /* CONFIG_MODULES */
1836 * em28xx_realease_resources()
1837 * unregisters the v4l2,i2c and usb devices
1838 * called when the device gets disconected or at module unload
1840 void em28xx_release_resources(struct em28xx *dev)
1842 if (dev->sbutton_input_dev)
1843 em28xx_deregister_snapshot_button(dev);
1845 if (dev->ir)
1846 em28xx_ir_fini(dev);
1848 /*FIXME: I2C IR should be disconnected */
1850 em28xx_release_analog_resources(dev);
1852 em28xx_remove_from_devlist(dev);
1854 em28xx_i2c_unregister(dev);
1855 usb_put_dev(dev->udev);
1857 /* Mark device as unused */
1858 em28xx_devused &= ~(1 << dev->devno);
1862 * em28xx_init_dev()
1863 * allocates and inits the device structs, registers i2c bus and v4l device
1865 static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1866 int minor)
1868 struct em28xx *dev = *devhandle;
1869 int retval = -ENOMEM;
1870 int errCode;
1872 dev->udev = udev;
1873 mutex_init(&dev->ctrl_urb_lock);
1874 spin_lock_init(&dev->slock);
1875 init_waitqueue_head(&dev->open);
1876 init_waitqueue_head(&dev->wait_frame);
1877 init_waitqueue_head(&dev->wait_stream);
1879 dev->em28xx_write_regs = em28xx_write_regs;
1880 dev->em28xx_read_reg = em28xx_read_reg;
1881 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
1882 dev->em28xx_write_regs_req = em28xx_write_regs_req;
1883 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1884 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
1886 em28xx_pre_card_setup(dev);
1888 if (!dev->board.is_em2800) {
1889 /* Sets I2C speed to 100 KHz */
1890 retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
1891 if (retval < 0) {
1892 em28xx_errdev("%s: em28xx_write_regs_req failed!"
1893 " retval [%d]\n",
1894 __func__, retval);
1895 return retval;
1899 /* register i2c bus */
1900 errCode = em28xx_i2c_register(dev);
1901 if (errCode < 0) {
1902 em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
1903 __func__, errCode);
1904 return errCode;
1907 /* Do board specific init and eeprom reading */
1908 em28xx_card_setup(dev);
1910 /* Configure audio */
1911 errCode = em28xx_audio_setup(dev);
1912 if (errCode < 0) {
1913 em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
1914 __func__, errCode);
1917 /* wake i2c devices */
1918 em28xx_wake_i2c(dev);
1920 /* init video dma queues */
1921 INIT_LIST_HEAD(&dev->vidq.active);
1922 INIT_LIST_HEAD(&dev->vidq.queued);
1925 if (dev->board.has_msp34xx) {
1926 /* Send a reset to other chips via gpio */
1927 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
1928 if (errCode < 0) {
1929 em28xx_errdev("%s: em28xx_write_regs_req - "
1930 "msp34xx(1) failed! errCode [%d]\n",
1931 __func__, errCode);
1932 return errCode;
1934 msleep(3);
1936 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
1937 if (errCode < 0) {
1938 em28xx_errdev("%s: em28xx_write_regs_req - "
1939 "msp34xx(2) failed! errCode [%d]\n",
1940 __func__, errCode);
1941 return errCode;
1943 msleep(3);
1946 em28xx_add_into_devlist(dev);
1948 retval = em28xx_register_analog_devices(dev);
1949 if (retval < 0) {
1950 em28xx_release_resources(dev);
1951 goto fail_reg_devices;
1954 em28xx_init_extension(dev);
1956 /* Save some power by putting tuner to sleep */
1957 em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
1959 return 0;
1961 fail_reg_devices:
1962 return retval;
1966 * em28xx_usb_probe()
1967 * checks for supported devices
1969 static int em28xx_usb_probe(struct usb_interface *interface,
1970 const struct usb_device_id *id)
1972 const struct usb_endpoint_descriptor *endpoint;
1973 struct usb_device *udev;
1974 struct usb_interface *uif;
1975 struct em28xx *dev = NULL;
1976 int retval = -ENODEV;
1977 int i, nr, ifnum, isoc_pipe;
1978 char *speed;
1979 char descr[255] = "";
1981 udev = usb_get_dev(interface_to_usbdev(interface));
1982 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1984 /* Check to see next free device and mark as used */
1985 nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
1986 em28xx_devused |= 1<<nr;
1988 /* Don't register audio interfaces */
1989 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1990 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): "
1991 "interface %i, class %i\n",
1992 le16_to_cpu(udev->descriptor.idVendor),
1993 le16_to_cpu(udev->descriptor.idProduct),
1994 ifnum,
1995 interface->altsetting[0].desc.bInterfaceClass);
1997 em28xx_devused &= ~(1<<nr);
1998 return -ENODEV;
2001 endpoint = &interface->cur_altsetting->endpoint[0].desc;
2003 /* check if the device has the iso in endpoint at the correct place */
2004 if (usb_endpoint_xfer_isoc(endpoint)
2006 (interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) {
2007 /* It's a newer em2874/em2875 device */
2008 isoc_pipe = 0;
2009 } else {
2010 int check_interface = 1;
2011 isoc_pipe = 1;
2012 endpoint = &interface->cur_altsetting->endpoint[1].desc;
2013 if (!usb_endpoint_xfer_isoc(endpoint))
2014 check_interface = 0;
2016 if (usb_endpoint_dir_out(endpoint))
2017 check_interface = 0;
2019 if (!check_interface) {
2020 em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
2021 "interface %i, class %i found.\n",
2022 le16_to_cpu(udev->descriptor.idVendor),
2023 le16_to_cpu(udev->descriptor.idProduct),
2024 ifnum,
2025 interface->altsetting[0].desc.bInterfaceClass);
2027 em28xx_err(DRIVER_NAME " This is an anciliary "
2028 "interface not used by the driver\n");
2030 em28xx_devused &= ~(1<<nr);
2031 return -ENODEV;
2035 switch (udev->speed) {
2036 case USB_SPEED_LOW:
2037 speed = "1.5";
2038 break;
2039 case USB_SPEED_UNKNOWN:
2040 case USB_SPEED_FULL:
2041 speed = "12";
2042 break;
2043 case USB_SPEED_HIGH:
2044 speed = "480";
2045 break;
2046 default:
2047 speed = "unknown";
2050 if (udev->manufacturer)
2051 strlcpy(descr, udev->manufacturer, sizeof(descr));
2053 if (udev->product) {
2054 if (*descr)
2055 strlcat(descr, " ", sizeof(descr));
2056 strlcat(descr, udev->product, sizeof(descr));
2058 if (*descr)
2059 strlcat(descr, " ", sizeof(descr));
2061 printk(DRIVER_NAME ": New device %s@ %s Mbps "
2062 "(%04x:%04x, interface %d, class %d)\n",
2063 descr,
2064 speed,
2065 le16_to_cpu(udev->descriptor.idVendor),
2066 le16_to_cpu(udev->descriptor.idProduct),
2067 ifnum,
2068 interface->altsetting->desc.bInterfaceNumber);
2070 if (nr >= EM28XX_MAXBOARDS) {
2071 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
2072 EM28XX_MAXBOARDS);
2073 em28xx_devused &= ~(1<<nr);
2074 return -ENOMEM;
2077 /* allocate memory for our device state and initialize it */
2078 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2079 if (dev == NULL) {
2080 em28xx_err(DRIVER_NAME ": out of memory!\n");
2081 em28xx_devused &= ~(1<<nr);
2082 return -ENOMEM;
2085 snprintf(dev->name, 29, "em28xx #%d", nr);
2086 dev->devno = nr;
2087 dev->model = id->driver_info;
2088 dev->alt = -1;
2090 /* Checks if audio is provided by some interface */
2091 for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
2092 uif = udev->config->interface[i];
2093 if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
2094 dev->has_audio_class = 1;
2095 break;
2099 /* compute alternate max packet sizes */
2100 uif = udev->actconfig->interface[0];
2102 dev->num_alt = uif->num_altsetting;
2103 dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
2105 if (dev->alt_max_pkt_size == NULL) {
2106 em28xx_errdev("out of memory!\n");
2107 em28xx_devused &= ~(1<<nr);
2108 kfree(dev);
2109 return -ENOMEM;
2112 for (i = 0; i < dev->num_alt ; i++) {
2113 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
2114 dev->alt_max_pkt_size[i] =
2115 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
2118 if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
2119 dev->model = card[nr];
2121 /* allocate device struct */
2122 mutex_init(&dev->lock);
2123 mutex_lock(&dev->lock);
2124 retval = em28xx_init_dev(&dev, udev, nr);
2125 if (retval) {
2126 em28xx_devused &= ~(1<<dev->devno);
2127 kfree(dev);
2129 return retval;
2132 /* save our data pointer in this interface device */
2133 usb_set_intfdata(interface, dev);
2135 request_modules(dev);
2137 /* Should be the last thing to do, to avoid newer udev's to
2138 open the device before fully initializing it
2140 mutex_unlock(&dev->lock);
2142 return 0;
2146 * em28xx_usb_disconnect()
2147 * called when the device gets diconencted
2148 * video device will be unregistered on v4l2_close in case it is still open
2150 static void em28xx_usb_disconnect(struct usb_interface *interface)
2152 struct em28xx *dev;
2154 dev = usb_get_intfdata(interface);
2155 usb_set_intfdata(interface, NULL);
2157 if (!dev)
2158 return;
2160 em28xx_info("disconnecting %s\n", dev->vdev->name);
2162 /* wait until all current v4l2 io is finished then deallocate
2163 resources */
2164 mutex_lock(&dev->lock);
2166 wake_up_interruptible_all(&dev->open);
2168 if (dev->users) {
2169 em28xx_warn
2170 ("device /dev/video%d is open! Deregistration and memory "
2171 "deallocation are deferred on close.\n",
2172 dev->vdev->num);
2174 dev->state |= DEV_MISCONFIGURED;
2175 em28xx_uninit_isoc(dev);
2176 dev->state |= DEV_DISCONNECTED;
2177 wake_up_interruptible(&dev->wait_frame);
2178 wake_up_interruptible(&dev->wait_stream);
2179 } else {
2180 dev->state |= DEV_DISCONNECTED;
2181 em28xx_release_resources(dev);
2184 em28xx_close_extension(dev);
2186 mutex_unlock(&dev->lock);
2188 if (!dev->users) {
2189 kfree(dev->alt_max_pkt_size);
2190 kfree(dev);
2194 static struct usb_driver em28xx_usb_driver = {
2195 .name = "em28xx",
2196 .probe = em28xx_usb_probe,
2197 .disconnect = em28xx_usb_disconnect,
2198 .id_table = em28xx_id_table,
2201 static int __init em28xx_module_init(void)
2203 int result;
2205 /* register this driver with the USB subsystem */
2206 result = usb_register(&em28xx_usb_driver);
2207 if (result)
2208 em28xx_err(DRIVER_NAME
2209 " usb_register failed. Error number %d.\n", result);
2211 printk(KERN_INFO DRIVER_NAME " driver loaded\n");
2213 return result;
2216 static void __exit em28xx_module_exit(void)
2218 /* deregister this driver with the USB subsystem */
2219 usb_deregister(&em28xx_usb_driver);
2222 module_init(em28xx_module_init);
2223 module_exit(em28xx_module_exit);