]> Pileus Git - ~andy/linux/blob - drivers/media/video/em28xx/em28xx-cards.c
V4L/DVB (8538): em28xx-cards: Add GrabBeeX+ USB2800 model
[~andy/linux] / drivers / media / video / em28xx / em28xx-cards.c
1 /*
2    em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB
3                     video capture devices
4
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>
9
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.
14
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.
19
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.
23  */
24
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>
37
38 #include "em28xx.h"
39
40 static int tuner = -1;
41 module_param(tuner, int, 0444);
42 MODULE_PARM_DESC(tuner, "tuner type");
43
44 static unsigned int disable_ir;
45 module_param(disable_ir, int, 0444);
46 MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
47
48 struct em28xx_hash_table {
49         unsigned long hash;
50         unsigned int  model;
51         unsigned int  tuner;
52 };
53
54 struct em28xx_board em28xx_boards[] = {
55         [EM2800_BOARD_UNKNOWN] = {
56                 .name         = "Unknown EM2800 video grabber",
57                 .is_em2800    = 1,
58                 .vchannels    = 2,
59                 .tda9887_conf = TDA9887_PRESENT,
60                 .decoder      = EM28XX_SAA7113,
61                 .input           = { {
62                         .type     = EM28XX_VMUX_COMPOSITE1,
63                         .vmux     = SAA7115_COMPOSITE0,
64                         .amux     = 1,
65                 }, {
66                         .type     = EM28XX_VMUX_SVIDEO,
67                         .vmux     = SAA7115_SVIDEO3,
68                         .amux     = 1,
69                 } },
70         },
71         [EM2820_BOARD_UNKNOWN] = {
72                 .name         = "Unknown EM2750/28xx video grabber",
73                 .is_em2800    = 0,
74                 .tuner_type   = TUNER_ABSENT,
75         },
76         [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
77                 .name         = "Kworld PVR TV 2800 RF",
78                 .is_em2800    = 0,
79                 .vchannels    = 2,
80                 .tuner_type   = TUNER_TEMIC_PAL,
81                 .tda9887_conf = TDA9887_PRESENT,
82                 .decoder      = EM28XX_SAA7113,
83                 .input           = { {
84                         .type     = EM28XX_VMUX_COMPOSITE1,
85                         .vmux     = SAA7115_COMPOSITE0,
86                         .amux     = 1,
87                 }, {
88                         .type     = EM28XX_VMUX_SVIDEO,
89                         .vmux     = SAA7115_SVIDEO3,
90                         .amux     = 1,
91                 } },
92         },
93         [EM2820_BOARD_TERRATEC_CINERGY_250] = {
94                 .name         = "Terratec Cinergy 250 USB",
95                 .vchannels    = 3,
96                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
97                 .tda9887_conf = TDA9887_PRESENT,
98                 .decoder      = EM28XX_SAA7113,
99                 .input          = { {
100                         .type     = EM28XX_VMUX_TELEVISION,
101                         .vmux     = SAA7115_COMPOSITE2,
102                         .amux     = 1,
103                 }, {
104                         .type     = EM28XX_VMUX_COMPOSITE1,
105                         .vmux     = SAA7115_COMPOSITE0,
106                         .amux     = 1,
107                 }, {
108                         .type     = EM28XX_VMUX_SVIDEO,
109                         .vmux     = SAA7115_SVIDEO3,
110                         .amux     = 1,
111                 } },
112         },
113         [EM2820_BOARD_PINNACLE_USB_2] = {
114                 .name         = "Pinnacle PCTV USB 2",
115                 .vchannels    = 3,
116                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
117                 .tda9887_conf = TDA9887_PRESENT,
118                 .decoder      = EM28XX_SAA7113,
119                 .input          = { {
120                         .type     = EM28XX_VMUX_TELEVISION,
121                         .vmux     = SAA7115_COMPOSITE2,
122                         .amux     = 0,
123                 }, {
124                         .type     = EM28XX_VMUX_COMPOSITE1,
125                         .vmux     = SAA7115_COMPOSITE0,
126                         .amux     = 1,
127                 }, {
128                         .type     = EM28XX_VMUX_SVIDEO,
129                         .vmux     = SAA7115_SVIDEO3,
130                         .amux     = 1,
131                 } },
132         },
133         [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
134                 .name         = "Hauppauge WinTV USB 2",
135                 .vchannels    = 3,
136                 .tuner_type   = TUNER_PHILIPS_FM1236_MK3,
137                 .tda9887_conf = TDA9887_PRESENT |
138                                 TDA9887_PORT1_ACTIVE|
139                                 TDA9887_PORT2_ACTIVE,
140                 .decoder      = EM28XX_TVP5150,
141                 .has_msp34xx  = 1,
142                 /*FIXME: S-Video not tested */
143                 .input          = { {
144                         .type     = EM28XX_VMUX_TELEVISION,
145                         .vmux     = TVP5150_COMPOSITE0,
146                         .amux     = MSP_INPUT_DEFAULT,
147                 }, {
148                         .type     = EM28XX_VMUX_SVIDEO,
149                         .vmux     = TVP5150_SVIDEO,
150                         .amux     = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
151                                         MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
152                 } },
153         },
154         [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
155                 .name         = "Hauppauge WinTV HVR 900",
156                 .vchannels    = 3,
157                 .tda9887_conf = TDA9887_PRESENT,
158                 .tuner_type   = TUNER_XC2028,
159                 .mts_firmware = 1,
160                 .has_dvb        = 1,
161                 .decoder      = EM28XX_TVP5150,
162                 .input          = { {
163                         .type     = EM28XX_VMUX_TELEVISION,
164                         .vmux     = TVP5150_COMPOSITE0,
165                         .amux     = 0,
166                 }, {
167                         .type     = EM28XX_VMUX_COMPOSITE1,
168                         .vmux     = TVP5150_COMPOSITE1,
169                         .amux     = 1,
170                 }, {
171                         .type     = EM28XX_VMUX_SVIDEO,
172                         .vmux     = TVP5150_SVIDEO,
173                         .amux     = 1,
174                 } },
175         },
176         [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
177                 .name         = "Hauppauge WinTV HVR 900 (R2)",
178                 .vchannels    = 3,
179                 .tda9887_conf = TDA9887_PRESENT,
180                 .tuner_type   = TUNER_XC2028,
181                 .mts_firmware = 1,
182                 .decoder      = EM28XX_TVP5150,
183                 .input          = { {
184                         .type     = EM28XX_VMUX_TELEVISION,
185                         .vmux     = TVP5150_COMPOSITE0,
186                         .amux     = 0,
187                 }, {
188                         .type     = EM28XX_VMUX_COMPOSITE1,
189                         .vmux     = TVP5150_COMPOSITE1,
190                         .amux     = 1,
191                 }, {
192                         .type     = EM28XX_VMUX_SVIDEO,
193                         .vmux     = TVP5150_SVIDEO,
194                         .amux     = 1,
195                 } },
196         },
197         [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
198                 .name           = "Hauppauge WinTV HVR 950",
199                 .vchannels      = 3,
200                 .tda9887_conf   = TDA9887_PRESENT,
201                 .tuner_type     = TUNER_XC2028,
202                 .mts_firmware   = 1,
203                 .has_12mhz_i2s  = 1,
204                 .has_dvb        = 1,
205                 .decoder        = EM28XX_TVP5150,
206                 .input          = { {
207                         .type     = EM28XX_VMUX_TELEVISION,
208                         .vmux     = TVP5150_COMPOSITE0,
209                         .amux     = 0,
210                 }, {
211                         .type     = EM28XX_VMUX_COMPOSITE1,
212                         .vmux     = TVP5150_COMPOSITE1,
213                         .amux     = 1,
214                 }, {
215                         .type     = EM28XX_VMUX_SVIDEO,
216                         .vmux     = TVP5150_SVIDEO,
217                         .amux     = 1,
218                 } },
219         },
220         [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
221                 .name           = "Pinnacle PCTV HD Pro Stick",
222                 .vchannels      = 3,
223                 .tda9887_conf   = TDA9887_PRESENT,
224                 .tuner_type     = TUNER_XC2028,
225                 .mts_firmware   = 1,
226                 .has_12mhz_i2s  = 1,
227                 .has_dvb        = 1,
228                 .decoder        = EM28XX_TVP5150,
229                 .input          = { {
230                         .type     = EM28XX_VMUX_TELEVISION,
231                         .vmux     = TVP5150_COMPOSITE0,
232                         .amux     = 0,
233                 }, {
234                         .type     = EM28XX_VMUX_COMPOSITE1,
235                         .vmux     = TVP5150_COMPOSITE1,
236                         .amux     = 1,
237                 }, {
238                         .type     = EM28XX_VMUX_SVIDEO,
239                         .vmux     = TVP5150_SVIDEO,
240                         .amux     = 1,
241                 } },
242         },
243         [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
244                 .name           = "AMD ATI TV Wonder HD 600",
245                 .vchannels      = 3,
246                 .tda9887_conf   = TDA9887_PRESENT,
247                 .tuner_type     = TUNER_XC2028,
248                 .mts_firmware   = 1,
249                 .has_12mhz_i2s  = 1,
250                 .has_dvb        = 1,
251                 .decoder        = EM28XX_TVP5150,
252                 .input          = { {
253                         .type     = EM28XX_VMUX_TELEVISION,
254                         .vmux     = TVP5150_COMPOSITE0,
255                         .amux     = 0,
256                 }, {
257                         .type     = EM28XX_VMUX_COMPOSITE1,
258                         .vmux     = TVP5150_COMPOSITE1,
259                         .amux     = 1,
260                 }, {
261                         .type     = EM28XX_VMUX_SVIDEO,
262                         .vmux     = TVP5150_SVIDEO,
263                         .amux     = 1,
264                 } },
265         },
266         [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
267                 .name           = "AMD ATI TV Wonder HD 600",
268                 .vchannels      = 3,
269                 .tda9887_conf   = TDA9887_PRESENT,
270                 .tuner_type     = TUNER_XC2028,
271                 .mts_firmware   = 1,
272                 .has_12mhz_i2s  = 1,
273                 .has_dvb        = 1,
274                 .decoder        = EM28XX_TVP5150,
275                 .input          = { {
276                         .type     = EM28XX_VMUX_TELEVISION,
277                         .vmux     = TVP5150_COMPOSITE0,
278                         .amux     = 0,
279                 }, {
280                         .type     = EM28XX_VMUX_COMPOSITE1,
281                         .vmux     = TVP5150_COMPOSITE1,
282                         .amux     = 1,
283                 }, {
284                         .type     = EM28XX_VMUX_SVIDEO,
285                         .vmux     = TVP5150_SVIDEO,
286                         .amux     = 1,
287                 } },
288         },
289         [EM2880_BOARD_TERRATEC_HYBRID_XS] = {
290                 .name         = "Terratec Hybrid XS",
291                 .vchannels    = 3,
292                 .tda9887_conf = TDA9887_PRESENT,
293                 .tuner_type   = TUNER_XC2028,
294                 .decoder      = EM28XX_TVP5150,
295                 .has_dvb        = 1,
296                 .input          = { {
297                         .type     = EM28XX_VMUX_TELEVISION,
298                         .vmux     = TVP5150_COMPOSITE0,
299                         .amux     = 0,
300                 }, {
301                         .type     = EM28XX_VMUX_COMPOSITE1,
302                         .vmux     = TVP5150_COMPOSITE1,
303                         .amux     = 1,
304                 }, {
305                         .type     = EM28XX_VMUX_SVIDEO,
306                         .vmux     = TVP5150_SVIDEO,
307                         .amux     = 1,
308                 } },
309         },
310         /* maybe there's a reason behind it why Terratec sells the Hybrid XS
311            as Prodigy XS with a different PID, let's keep it separated for now
312            maybe we'll need it lateron */
313         [EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
314                 .name         = "Terratec Prodigy XS",
315                 .vchannels    = 3,
316                 .tda9887_conf = TDA9887_PRESENT,
317                 .tuner_type   = TUNER_XC2028,
318                 .decoder      = EM28XX_TVP5150,
319                 .input          = { {
320                         .type     = EM28XX_VMUX_TELEVISION,
321                         .vmux     = TVP5150_COMPOSITE0,
322                         .amux     = 0,
323                 }, {
324                         .type     = EM28XX_VMUX_COMPOSITE1,
325                         .vmux     = TVP5150_COMPOSITE1,
326                         .amux     = 1,
327                 }, {
328                         .type     = EM28XX_VMUX_SVIDEO,
329                         .vmux     = TVP5150_SVIDEO,
330                         .amux     = 1,
331                 } },
332         },
333         [EM2820_BOARD_MSI_VOX_USB_2] = {
334                 .name              = "MSI VOX USB 2.0",
335                 .vchannels         = 3,
336                 .tuner_type        = TUNER_LG_PAL_NEW_TAPC,
337                 .tda9887_conf      = TDA9887_PRESENT      |
338                                      TDA9887_PORT1_ACTIVE |
339                                      TDA9887_PORT2_ACTIVE,
340                 .max_range_640_480 = 1,
341
342                 .decoder           = EM28XX_SAA7114,
343                 .input             = { {
344                         .type      = EM28XX_VMUX_TELEVISION,
345                         .vmux      = SAA7115_COMPOSITE4,
346                         .amux      = 0,
347                 }, {
348                         .type      = EM28XX_VMUX_COMPOSITE1,
349                         .vmux      = SAA7115_COMPOSITE0,
350                         .amux      = 1,
351                 }, {
352                         .type      = EM28XX_VMUX_SVIDEO,
353                         .vmux      = SAA7115_SVIDEO3,
354                         .amux      = 1,
355                 } },
356         },
357         [EM2800_BOARD_TERRATEC_CINERGY_200] = {
358                 .name         = "Terratec Cinergy 200 USB",
359                 .is_em2800    = 1,
360                 .vchannels    = 3,
361                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
362                 .tda9887_conf = TDA9887_PRESENT,
363                 .decoder      = EM28XX_SAA7113,
364                 .input          = { {
365                         .type     = EM28XX_VMUX_TELEVISION,
366                         .vmux     = SAA7115_COMPOSITE2,
367                         .amux     = 0,
368                 }, {
369                         .type     = EM28XX_VMUX_COMPOSITE1,
370                         .vmux     = SAA7115_COMPOSITE0,
371                         .amux     = 1,
372                 }, {
373                         .type     = EM28XX_VMUX_SVIDEO,
374                         .vmux     = SAA7115_SVIDEO3,
375                         .amux     = 1,
376                 } },
377         },
378         [EM2800_BOARD_GRABBEEX_USB2800] = {
379                 .name         = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
380                 .is_em2800    = 1,
381                 .vchannels    = 2,
382                 .decoder      = EM28XX_SAA7113,
383                 .input          = { {
384                         .type     = EM28XX_VMUX_COMPOSITE1,
385                         .vmux     = SAA7115_COMPOSITE0,
386                         .amux     = 1,
387                 }, {
388                         .type     = EM28XX_VMUX_SVIDEO,
389                         .vmux     = SAA7115_SVIDEO3,
390                         .amux     = 1,
391                 } },
392         },
393         [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
394                 .name         = "Leadtek Winfast USB II",
395                 .is_em2800    = 1,
396                 .vchannels    = 3,
397                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
398                 .tda9887_conf = TDA9887_PRESENT,
399                 .decoder      = EM28XX_SAA7113,
400                 .input          = { {
401                         .type     = EM28XX_VMUX_TELEVISION,
402                         .vmux     = SAA7115_COMPOSITE2,
403                         .amux     = 0,
404                 }, {
405                         .type     = EM28XX_VMUX_COMPOSITE1,
406                         .vmux     = SAA7115_COMPOSITE0,
407                         .amux     = 1,
408                 }, {
409                         .type     = EM28XX_VMUX_SVIDEO,
410                         .vmux     = SAA7115_SVIDEO3,
411                         .amux     = 1,
412                 } },
413         },
414         [EM2800_BOARD_KWORLD_USB2800] = {
415                 .name         = "Kworld USB2800",
416                 .is_em2800    = 1,
417                 .vchannels    = 3,
418                 .tuner_type   = TUNER_PHILIPS_FCV1236D,
419                 .tda9887_conf = TDA9887_PRESENT,
420                 .decoder      = EM28XX_SAA7113,
421                 .input          = { {
422                         .type     = EM28XX_VMUX_TELEVISION,
423                         .vmux     = SAA7115_COMPOSITE2,
424                         .amux     = 0,
425                 }, {
426                         .type     = EM28XX_VMUX_COMPOSITE1,
427                         .vmux     = SAA7115_COMPOSITE0,
428                         .amux     = 1,
429                 }, {
430                         .type     = EM28XX_VMUX_SVIDEO,
431                         .vmux     = SAA7115_SVIDEO3,
432                         .amux     = 1,
433                 } },
434         },
435         [EM2820_BOARD_PINNACLE_DVC_90] = {
436                 .name         = "Pinnacle Dazzle DVC 90/DVC 100",
437                 .vchannels    = 3,
438                 .tuner_type   = TUNER_ABSENT,
439                 .decoder      = EM28XX_SAA7113,
440                 .input          = { {
441                         .type     = EM28XX_VMUX_COMPOSITE1,
442                         .vmux     = SAA7115_COMPOSITE0,
443                         .amux     = 1,
444                 }, {
445                         .type     = EM28XX_VMUX_SVIDEO,
446                         .vmux     = SAA7115_SVIDEO3,
447                         .amux     = 1,
448                 } },
449         },
450         [EM2800_BOARD_VGEAR_POCKETTV] = {
451                 .name         = "V-Gear PocketTV",
452                 .is_em2800    = 1,
453                 .vchannels    = 3,
454                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
455                 .tda9887_conf = TDA9887_PRESENT,
456                 .decoder      = EM28XX_SAA7113,
457                 .input          = { {
458                         .type     = EM28XX_VMUX_TELEVISION,
459                         .vmux     = SAA7115_COMPOSITE2,
460                         .amux     = 0,
461                 }, {
462                         .type     = EM28XX_VMUX_COMPOSITE1,
463                         .vmux     = SAA7115_COMPOSITE0,
464                         .amux     = 1,
465                 }, {
466                         .type     = EM28XX_VMUX_SVIDEO,
467                         .vmux     = SAA7115_SVIDEO3,
468                         .amux     = 1,
469                 } },
470         },
471         [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
472                 .name         = "Pixelview Prolink PlayTV USB 2.0",
473                 .vchannels    = 3,
474                 .tda9887_conf = TDA9887_PRESENT,
475                 .tuner_type   = TUNER_YMEC_TVF_5533MF,
476                 .decoder      = EM28XX_SAA7113,
477                 .input          = { {
478                         .type     = EM28XX_VMUX_TELEVISION,
479                         .vmux     = SAA7115_COMPOSITE2,
480                         .amux     = EM28XX_AMUX_LINE_IN,
481                 }, {
482                         .type     = EM28XX_VMUX_COMPOSITE1,
483                         .vmux     = SAA7115_COMPOSITE0,
484                         .amux     = EM28XX_AMUX_LINE_IN,
485                 }, {
486                         .type     = EM28XX_VMUX_SVIDEO,
487                         .vmux     = SAA7115_SVIDEO3,
488                         .amux     = EM28XX_AMUX_LINE_IN,
489                 } },
490         },
491         [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = {
492                 .name         = "PointNix Intra-Oral Camera",
493                 .has_snapshot_button = 1,
494                 .vchannels    = 1,
495                 .tda9887_conf = TDA9887_PRESENT,
496                 .tuner_type   = TUNER_ABSENT,
497                 .decoder      = EM28XX_SAA7113,
498                 .input          = { {
499                         .type     = EM28XX_VMUX_SVIDEO,
500                         .vmux     = SAA7115_SVIDEO3,
501                         .amux     = 0,
502                 } },
503         },
504 };
505 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
506
507 /* table of devices that work with this driver */
508 struct usb_device_id em28xx_id_table [] = {
509         { USB_DEVICE(0xeb1a, 0x2750),
510                         .driver_info = EM2820_BOARD_UNKNOWN },
511         { USB_DEVICE(0xeb1a, 0x2800),
512                         .driver_info = EM2800_BOARD_UNKNOWN },
513         { USB_DEVICE(0xeb1a, 0x2820),
514                         .driver_info = EM2820_BOARD_UNKNOWN },
515         { USB_DEVICE(0xeb1a, 0x2821),
516                         .driver_info = EM2820_BOARD_UNKNOWN },
517         { USB_DEVICE(0xeb1a, 0x2860),
518                         .driver_info = EM2820_BOARD_UNKNOWN },
519         { USB_DEVICE(0xeb1a, 0x2861),
520                         .driver_info = EM2820_BOARD_UNKNOWN },
521         { USB_DEVICE(0xeb1a, 0x2870),
522                         .driver_info = EM2820_BOARD_UNKNOWN },
523         { USB_DEVICE(0xeb1a, 0x2881),
524                         .driver_info = EM2820_BOARD_UNKNOWN },
525         { USB_DEVICE(0xeb1a, 0x2883),
526                         .driver_info = EM2820_BOARD_UNKNOWN },
527         { USB_DEVICE(0x0ccd, 0x0036),
528                         .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
529         { USB_DEVICE(0x2304, 0x0208),
530                         .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
531         { USB_DEVICE(0x2040, 0x4200),
532                         .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
533         { USB_DEVICE(0x2040, 0x4201),
534                         .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
535         { USB_DEVICE(0x2304, 0x0207),
536                         .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
537         { USB_DEVICE(0x2304, 0x021a),
538                         .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
539         { USB_DEVICE(0x2304, 0x0227),
540                         .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
541         { USB_DEVICE(0x2040, 0x6500),
542                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
543         { USB_DEVICE(0x2040, 0x6502),
544                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
545         { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
546                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
547         { USB_DEVICE(0x2040, 0x6517), /* HP  HVR-950 */
548                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
549         { USB_DEVICE(0x2040, 0x651b), /* RP  HVR-950 */
550                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
551         { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
552                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
553         { USB_DEVICE(0x0ccd, 0x0042),
554                         .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
555         { USB_DEVICE(0x0ccd, 0x0047),
556                         .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
557         { USB_DEVICE(0x0438, 0xb002),
558                         .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
559         { USB_DEVICE(0xeb1a, 0x2801),
560                         .driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
561         { },
562 };
563 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
564
565 /*
566  *  Reset sequences for analog/digital modes
567  */
568
569 /* Board Hauppauge WinTV HVR 900 analog */
570 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
571         {EM28XX_R08_GPIO,       0x2d,   ~EM_GPIO_4,     10},
572         {0x05,                  0xff,   0x10,           10},
573         {  -1,                  -1,     -1,             -1},
574 };
575
576 /* Board Hauppauge WinTV HVR 900 digital */
577 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
578         {EM28XX_R08_GPIO,       0x2e,   ~EM_GPIO_4,     10},
579         {EM2880_R04_GPO,        0x04,   0x0f,           10},
580         {EM2880_R04_GPO,        0x0c,   0x0f,           10},
581         { -1,                   -1,     -1,             -1},
582 };
583
584 /* Board Hauppauge WinTV HVR 900 tuner_callback */
585 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = {
586         {EM28XX_R08_GPIO,       EM_GPIO_4,      EM_GPIO_4,      10},
587         {EM28XX_R08_GPIO,       0,              EM_GPIO_4,      10},
588         {EM28XX_R08_GPIO,       EM_GPIO_4,      EM_GPIO_4,      10},
589         {  -1,                  -1,             -1,             -1},
590 };
591
592 /*
593  * EEPROM hash table for devices with generic USB IDs
594  */
595 static struct em28xx_hash_table em28xx_eeprom_hash [] = {
596         /* P/N: SA 60002070465 Tuner: TVF7533-MF */
597         {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
598 };
599
600 /* I2C devicelist hash table for devices with generic USB IDs */
601 static struct em28xx_hash_table em28xx_i2c_hash[] = {
602         {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
603         {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
604         {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
605 };
606
607 int em28xx_tuner_callback(void *ptr, int command, int arg)
608 {
609         int rc = 0;
610         struct em28xx *dev = ptr;
611
612         if (dev->tuner_type != TUNER_XC2028)
613                 return 0;
614
615         if (command != XC2028_TUNER_RESET)
616                 return 0;
617
618         if (dev->mode == EM28XX_ANALOG_MODE)
619                 rc = em28xx_gpio_set(dev, dev->tun_analog_gpio);
620         else
621                 rc = em28xx_gpio_set(dev, dev->tun_digital_gpio);
622
623         return rc;
624 }
625 EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
626
627 static void em28xx_set_model(struct em28xx *dev)
628 {
629         dev->is_em2800 = em28xx_boards[dev->model].is_em2800;
630         dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx;
631         dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf;
632         dev->decoder = em28xx_boards[dev->model].decoder;
633         dev->video_inputs = em28xx_boards[dev->model].vchannels;
634         dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s;
635         dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
636         dev->has_dvb = em28xx_boards[dev->model].has_dvb;
637         dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button;
638 }
639
640 /* Since em28xx_pre_card_setup() requires a proper dev->model,
641  * this won't work for boards with generic PCI IDs
642  */
643 void em28xx_pre_card_setup(struct em28xx *dev)
644 {
645         int rc;
646
647         rc = em28xx_read_reg(dev, EM2880_R04_GPO);
648         if (rc >= 0)
649                 dev->reg_gpo = rc;
650
651         dev->wait_after_write = 5;
652         rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
653         if (rc > 0) {
654                 switch (rc) {
655                 case CHIP_ID_EM2860:
656                         em28xx_info("chip ID is em2860\n");
657                         break;
658                 case CHIP_ID_EM2883:
659                         em28xx_info("chip ID is em2882/em2883\n");
660                         dev->wait_after_write = 0;
661                         break;
662                 default:
663                         em28xx_info("em28xx chip ID = %d\n", rc);
664                 }
665         }
666         em28xx_set_model(dev);
667
668         /* request some modules */
669         switch (dev->model) {
670         case EM2880_BOARD_TERRATEC_PRODIGY_XS:
671         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
672         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
673         case EM2880_BOARD_TERRATEC_HYBRID_XS:
674         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
675         case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
676         case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
677                 em28xx_write_regs(dev, EM28XX_R0F_XCLK,    "\x27", 1);
678                 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
679                 msleep(50);
680
681                 /* Sets GPO/GPIO sequences for this device */
682                 dev->analog_gpio      = hauppauge_wintv_hvr_900_analog;
683                 dev->digital_gpio     = hauppauge_wintv_hvr_900_digital;
684                 dev->tun_analog_gpio  = hauppauge_wintv_hvr_900_tuner_callback;
685                 dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback;
686
687                 break;
688         }
689
690         em28xx_gpio_set(dev, dev->tun_analog_gpio);
691         em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
692
693         /* Unlock device */
694         em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
695 }
696
697 static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
698 {
699         memset(ctl, 0, sizeof(*ctl));
700
701         ctl->fname   = XC2028_DEFAULT_FIRMWARE;
702         ctl->max_len = 64;
703         ctl->mts = em28xx_boards[dev->model].mts_firmware;
704
705         switch (dev->model) {
706         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
707                 ctl->demod = XC3028_FE_ZARLINK456;
708                 break;
709         case EM2880_BOARD_TERRATEC_HYBRID_XS:
710                 ctl->demod = XC3028_FE_ZARLINK456;
711                 break;
712         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
713                 /* djh - Not sure which demod we need here */
714                 ctl->demod = XC3028_FE_DEFAULT;
715                 break;
716         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
717         case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
718         case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
719                 /* FIXME: Better to specify the needed IF */
720                 ctl->demod = XC3028_FE_DEFAULT;
721                 break;
722         default:
723                 ctl->demod = XC3028_FE_OREN538;
724         }
725 }
726
727 static void em28xx_config_tuner(struct em28xx *dev)
728 {
729         struct v4l2_priv_tun_config  xc2028_cfg;
730         struct tuner_setup           tun_setup;
731         struct v4l2_frequency        f;
732
733         if (dev->tuner_type == TUNER_ABSENT)
734                 return;
735
736         tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
737         tun_setup.type = dev->tuner_type;
738         tun_setup.addr = dev->tuner_addr;
739         tun_setup.tuner_callback = em28xx_tuner_callback;
740
741         em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
742
743         if (dev->tuner_type == TUNER_XC2028) {
744                 struct xc2028_ctrl           ctl;
745
746                 em28xx_setup_xc3028(dev, &ctl);
747
748                 xc2028_cfg.tuner = TUNER_XC2028;
749                 xc2028_cfg.priv  = &ctl;
750
751                 em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
752         }
753
754         /* configure tuner */
755         f.tuner = 0;
756         f.type = V4L2_TUNER_ANALOG_TV;
757         f.frequency = 9076;     /* just a magic number */
758         dev->ctl_freq = f.frequency;
759         em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
760 }
761
762 static int em28xx_hint_board(struct em28xx *dev)
763 {
764         int i;
765
766         /* HINT method: EEPROM
767          *
768          * This method works only for boards with eeprom.
769          * Uses a hash of all eeprom bytes. The hash should be
770          * unique for a vendor/tuner pair.
771          * There are a high chance that tuners for different
772          * video standards produce different hashes.
773          */
774         for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) {
775                 if (dev->hash == em28xx_eeprom_hash[i].hash) {
776                         dev->model = em28xx_eeprom_hash[i].model;
777                         dev->tuner_type = em28xx_eeprom_hash[i].tuner;
778
779                         em28xx_errdev("Your board has no unique USB ID.\n");
780                         em28xx_errdev("A hint were successfully done, "
781                                       "based on eeprom hash.\n");
782                         em28xx_errdev("This method is not 100%% failproof.\n");
783                         em28xx_errdev("If the board were missdetected, "
784                                       "please email this log to:\n");
785                         em28xx_errdev("\tV4L Mailing List "
786                                       " <video4linux-list@redhat.com>\n");
787                         em28xx_errdev("Board detected as %s\n",
788                                       em28xx_boards[dev->model].name);
789
790                         return 0;
791                 }
792         }
793
794         /* HINT method: I2C attached devices
795          *
796          * This method works for all boards.
797          * Uses a hash of i2c scanned devices.
798          * Devices with the same i2c attached chips will
799          * be considered equal.
800          * This method is less precise than the eeprom one.
801          */
802
803         /* user did not request i2c scanning => do it now */
804         if (!dev->i2c_hash)
805                 em28xx_do_i2c_scan(dev);
806
807         for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) {
808                 if (dev->i2c_hash == em28xx_i2c_hash[i].hash) {
809                         dev->model = em28xx_i2c_hash[i].model;
810                         dev->tuner_type = em28xx_i2c_hash[i].tuner;
811                         em28xx_errdev("Your board has no unique USB ID.\n");
812                         em28xx_errdev("A hint were successfully done, "
813                                       "based on i2c devicelist hash.\n");
814                         em28xx_errdev("This method is not 100%% failproof.\n");
815                         em28xx_errdev("If the board were missdetected, "
816                                       "please email this log to:\n");
817                         em28xx_errdev("\tV4L Mailing List "
818                                       " <video4linux-list@redhat.com>\n");
819                         em28xx_errdev("Board detected as %s\n",
820                                       em28xx_boards[dev->model].name);
821
822                         return 0;
823                 }
824         }
825
826         em28xx_errdev("Your board has no unique USB ID and thus need a "
827                       "hint to be detected.\n");
828         em28xx_errdev("You may try to use card=<n> insmod option to "
829                       "workaround that.\n");
830         em28xx_errdev("Please send an email with this log to:\n");
831         em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
832         em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
833         em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
834
835         em28xx_errdev("Here is a list of valid choices for the card=<n>"
836                       " insmod option:\n");
837         for (i = 0; i < em28xx_bcount; i++) {
838                 em28xx_errdev("    card=%d -> %s\n",
839                                 i, em28xx_boards[i].name);
840         }
841         return -1;
842 }
843
844 /* ----------------------------------------------------------------------- */
845 void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
846 {
847         if (disable_ir) {
848                 ir->get_key = NULL;
849                 return ;
850         }
851
852         /* detect & configure */
853         switch (dev->model) {
854         case (EM2800_BOARD_UNKNOWN):
855                 break;
856         case (EM2820_BOARD_UNKNOWN):
857                 break;
858         case (EM2800_BOARD_TERRATEC_CINERGY_200):
859         case (EM2820_BOARD_TERRATEC_CINERGY_250):
860                 ir->ir_codes = ir_codes_em_terratec;
861                 ir->get_key = em28xx_get_key_terratec;
862                 snprintf(ir->c.name, sizeof(ir->c.name),
863                          "i2c IR (EM28XX Terratec)");
864                 break;
865         case (EM2820_BOARD_PINNACLE_USB_2):
866                 ir->ir_codes = ir_codes_pinnacle_grey;
867                 ir->get_key = em28xx_get_key_pinnacle_usb_grey;
868                 snprintf(ir->c.name, sizeof(ir->c.name),
869                          "i2c IR (EM28XX Pinnacle PCTV)");
870                 break;
871         case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
872                 ir->ir_codes = ir_codes_hauppauge_new;
873                 ir->get_key = em28xx_get_key_em_haup;
874                 snprintf(ir->c.name, sizeof(ir->c.name),
875                          "i2c IR (EM2840 Hauppauge)");
876                 break;
877         case (EM2820_BOARD_MSI_VOX_USB_2):
878                 break;
879         case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
880                 break;
881         case (EM2800_BOARD_KWORLD_USB2800):
882                 break;
883         case (EM2800_BOARD_GRABBEEX_USB2800):
884                 break;
885         }
886 }
887
888 void em28xx_card_setup(struct em28xx *dev)
889 {
890         em28xx_set_model(dev);
891
892         dev->tuner_type = em28xx_boards[dev->model].tuner_type;
893
894         /* request some modules */
895         switch (dev->model) {
896         case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
897         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
898         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
899         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
900         {
901                 struct tveeprom tv;
902 #ifdef CONFIG_MODULES
903                 request_module("tveeprom");
904 #endif
905                 /* Call first TVeeprom */
906
907                 dev->i2c_client.addr = 0xa0 >> 1;
908                 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
909
910                 dev->tuner_type = tv.tuner_type;
911
912                 if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
913                         dev->i2s_speed = 2048000;
914                         dev->has_msp34xx = 1;
915                 }
916 #ifdef CONFIG_MODULES
917                 if (tv.has_ir)
918                         request_module("ir-kbd-i2c");
919 #endif
920                 break;
921         }
922         case EM2820_BOARD_KWORLD_PVRTV2800RF:
923                 /* GPIO enables sound on KWORLD PVR TV 2800RF */
924                 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf9", 1);
925                 break;
926         case EM2820_BOARD_UNKNOWN:
927         case EM2800_BOARD_UNKNOWN:
928                 if (!em28xx_hint_board(dev))
929                         em28xx_set_model(dev);
930         }
931
932         if (dev->has_snapshot_button)
933                 em28xx_register_snapshot_button(dev);
934
935         /* Allow override tuner type by a module parameter */
936         if (tuner >= 0)
937                 dev->tuner_type = tuner;
938
939 #ifdef CONFIG_MODULES
940         /* request some modules */
941         if (dev->has_msp34xx)
942                 request_module("msp3400");
943         if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
944                 request_module("saa7115");
945         if (dev->decoder == EM28XX_TVP5150)
946                 request_module("tvp5150");
947         if (dev->tuner_type != TUNER_ABSENT)
948                 request_module("tuner");
949 #endif
950
951         em28xx_config_tuner(dev);
952 }