diff options
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-cards.c')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-cards.c | 3417 |
1 files changed, 3417 insertions, 0 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c new file mode 100644 index 000000000000..ca62b9981380 --- /dev/null +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
@@ -0,0 +1,3417 @@ | |||
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/slab.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/usb.h> | ||
31 | #include <media/tuner.h> | ||
32 | #include <media/msp3400.h> | ||
33 | #include <media/saa7115.h> | ||
34 | #include <media/tvp5150.h> | ||
35 | #include <media/tvaudio.h> | ||
36 | #include <media/mt9v011.h> | ||
37 | #include <media/i2c-addr.h> | ||
38 | #include <media/tveeprom.h> | ||
39 | #include <media/v4l2-common.h> | ||
40 | #include <media/v4l2-chip-ident.h> | ||
41 | |||
42 | #include "em28xx.h" | ||
43 | |||
44 | #define DRIVER_NAME "em28xx" | ||
45 | |||
46 | static int tuner = -1; | ||
47 | module_param(tuner, int, 0444); | ||
48 | MODULE_PARM_DESC(tuner, "tuner type"); | ||
49 | |||
50 | static unsigned int disable_ir; | ||
51 | module_param(disable_ir, int, 0444); | ||
52 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); | ||
53 | |||
54 | static unsigned int disable_usb_speed_check; | ||
55 | module_param(disable_usb_speed_check, int, 0444); | ||
56 | MODULE_PARM_DESC(disable_usb_speed_check, | ||
57 | "override min bandwidth requirement of 480M bps"); | ||
58 | |||
59 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
60 | module_param_array(card, int, NULL, 0444); | ||
61 | MODULE_PARM_DESC(card, "card type"); | ||
62 | |||
63 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */ | ||
64 | static unsigned long em28xx_devused; | ||
65 | |||
66 | struct em28xx_hash_table { | ||
67 | unsigned long hash; | ||
68 | unsigned int model; | ||
69 | unsigned int tuner; | ||
70 | }; | ||
71 | |||
72 | static void em28xx_pre_card_setup(struct em28xx *dev); | ||
73 | |||
74 | /* | ||
75 | * Reset sequences for analog/digital modes | ||
76 | */ | ||
77 | |||
78 | /* Reset for the most [analog] boards */ | ||
79 | static struct em28xx_reg_seq default_analog[] = { | ||
80 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
81 | { -1, -1, -1, -1}, | ||
82 | }; | ||
83 | |||
84 | /* Reset for the most [digital] boards */ | ||
85 | static struct em28xx_reg_seq default_digital[] = { | ||
86 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
87 | { -1, -1, -1, -1}, | ||
88 | }; | ||
89 | |||
90 | /* Board Hauppauge WinTV HVR 900 analog */ | ||
91 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | ||
92 | {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, | ||
93 | {0x05, 0xff, 0x10, 10}, | ||
94 | { -1, -1, -1, -1}, | ||
95 | }; | ||
96 | |||
97 | /* Board Hauppauge WinTV HVR 900 digital */ | ||
98 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | ||
99 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, | ||
100 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, | ||
101 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | ||
102 | { -1, -1, -1, -1}, | ||
103 | }; | ||
104 | |||
105 | /* Board Hauppauge WinTV HVR 900 (R2) digital */ | ||
106 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { | ||
107 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, | ||
108 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | ||
109 | { -1, -1, -1, -1}, | ||
110 | }; | ||
111 | |||
112 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
113 | static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | ||
114 | {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, | ||
115 | { -1, -1, -1, -1}, | ||
116 | }; | ||
117 | |||
118 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
119 | |||
120 | /* Board - EM2870 Kworld 355u | ||
121 | Analog - No input analog */ | ||
122 | |||
123 | /* Board - EM2882 Kworld 315U digital */ | ||
124 | static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { | ||
125 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
126 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
127 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | ||
128 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
129 | {EM28XX_R08_GPIO, 0x7e, 0xff, 10}, | ||
130 | { -1, -1, -1, -1}, | ||
131 | }; | ||
132 | |||
133 | static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | ||
134 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
135 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
136 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
137 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
138 | { -1, -1, -1, -1}, | ||
139 | }; | ||
140 | |||
141 | static struct em28xx_reg_seq kworld_330u_analog[] = { | ||
142 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
143 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | ||
144 | { -1, -1, -1, -1}, | ||
145 | }; | ||
146 | |||
147 | static struct em28xx_reg_seq kworld_330u_digital[] = { | ||
148 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
149 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
150 | { -1, -1, -1, -1}, | ||
151 | }; | ||
152 | |||
153 | /* Evga inDtube | ||
154 | GPIO0 - Enable digital power (s5h1409) - low to enable | ||
155 | GPIO1 - Enable analog power (tvp5150/emp202) - low to enable | ||
156 | GPIO4 - xc3028 reset | ||
157 | GOP3 - s5h1409 reset | ||
158 | */ | ||
159 | static struct em28xx_reg_seq evga_indtube_analog[] = { | ||
160 | {EM28XX_R08_GPIO, 0x79, 0xff, 60}, | ||
161 | { -1, -1, -1, -1}, | ||
162 | }; | ||
163 | |||
164 | static struct em28xx_reg_seq evga_indtube_digital[] = { | ||
165 | {EM28XX_R08_GPIO, 0x7a, 0xff, 1}, | ||
166 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | ||
167 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | ||
168 | { -1, -1, -1, -1}, | ||
169 | }; | ||
170 | |||
171 | /* | ||
172 | * KWorld PlusTV 340U and UB435-Q (ATSC) GPIOs map: | ||
173 | * EM_GPIO_0 - currently unknown | ||
174 | * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on) | ||
175 | * EM_GPIO_2 - currently unknown | ||
176 | * EM_GPIO_3 - currently unknown | ||
177 | * EM_GPIO_4 - TDA18271HD/C1 tuner (1 = active, 0 = in reset) | ||
178 | * EM_GPIO_5 - LGDT3304 ATSC/QAM demod (1 = active, 0 = in reset) | ||
179 | * EM_GPIO_6 - currently unknown | ||
180 | * EM_GPIO_7 - currently unknown | ||
181 | */ | ||
182 | static struct em28xx_reg_seq kworld_a340_digital[] = { | ||
183 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
184 | { -1, -1, -1, -1}, | ||
185 | }; | ||
186 | |||
187 | /* Pinnacle Hybrid Pro eb1a:2881 */ | ||
188 | static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { | ||
189 | {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10}, | ||
190 | { -1, -1, -1, -1}, | ||
191 | }; | ||
192 | |||
193 | static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { | ||
194 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
195 | {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ | ||
196 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | ||
197 | { -1, -1, -1, -1}, | ||
198 | }; | ||
199 | |||
200 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { | ||
201 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
202 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | ||
203 | { -1, -1, -1, -1}, | ||
204 | }; | ||
205 | |||
206 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { | ||
207 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
208 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
209 | { -1, -1, -1, -1}, | ||
210 | }; | ||
211 | |||
212 | /* eb1a:2868 Reddo DVB-C USB TV Box | ||
213 | GPIO4 - CU1216L NIM | ||
214 | Other GPIOs seems to be don't care. */ | ||
215 | static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { | ||
216 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
217 | {EM28XX_R08_GPIO, 0xde, 0xff, 10}, | ||
218 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
219 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
220 | {EM28XX_R08_GPIO, 0x7f, 0xff, 10}, | ||
221 | {EM28XX_R08_GPIO, 0x6f, 0xff, 10}, | ||
222 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
223 | {-1, -1, -1, -1}, | ||
224 | }; | ||
225 | |||
226 | /* Callback for the most boards */ | ||
227 | static struct em28xx_reg_seq default_tuner_gpio[] = { | ||
228 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
229 | {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, | ||
230 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
231 | { -1, -1, -1, -1}, | ||
232 | }; | ||
233 | |||
234 | /* Mute/unmute */ | ||
235 | static struct em28xx_reg_seq compro_unmute_tv_gpio[] = { | ||
236 | {EM28XX_R08_GPIO, 5, 7, 10}, | ||
237 | { -1, -1, -1, -1}, | ||
238 | }; | ||
239 | |||
240 | static struct em28xx_reg_seq compro_unmute_svid_gpio[] = { | ||
241 | {EM28XX_R08_GPIO, 4, 7, 10}, | ||
242 | { -1, -1, -1, -1}, | ||
243 | }; | ||
244 | |||
245 | static struct em28xx_reg_seq compro_mute_gpio[] = { | ||
246 | {EM28XX_R08_GPIO, 6, 7, 10}, | ||
247 | { -1, -1, -1, -1}, | ||
248 | }; | ||
249 | |||
250 | /* Terratec AV350 */ | ||
251 | static struct em28xx_reg_seq terratec_av350_mute_gpio[] = { | ||
252 | {EM28XX_R08_GPIO, 0xff, 0x7f, 10}, | ||
253 | { -1, -1, -1, -1}, | ||
254 | }; | ||
255 | |||
256 | static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { | ||
257 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
258 | { -1, -1, -1, -1}, | ||
259 | }; | ||
260 | |||
261 | static struct em28xx_reg_seq silvercrest_reg_seq[] = { | ||
262 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
263 | {EM28XX_R08_GPIO, 0x01, 0xf7, 10}, | ||
264 | { -1, -1, -1, -1}, | ||
265 | }; | ||
266 | |||
267 | static struct em28xx_reg_seq vc211a_enable[] = { | ||
268 | {EM28XX_R08_GPIO, 0xff, 0x07, 10}, | ||
269 | {EM28XX_R08_GPIO, 0xff, 0x0f, 10}, | ||
270 | {EM28XX_R08_GPIO, 0xff, 0x0b, 10}, | ||
271 | { -1, -1, -1, -1}, | ||
272 | }; | ||
273 | |||
274 | static struct em28xx_reg_seq dikom_dk300_digital[] = { | ||
275 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
276 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
277 | { -1, -1, -1, -1}, | ||
278 | }; | ||
279 | |||
280 | |||
281 | /* Reset for the most [digital] boards */ | ||
282 | static struct em28xx_reg_seq leadership_digital[] = { | ||
283 | {EM2874_R80_GPIO, 0x70, 0xff, 10}, | ||
284 | { -1, -1, -1, -1}, | ||
285 | }; | ||
286 | |||
287 | static struct em28xx_reg_seq leadership_reset[] = { | ||
288 | {EM2874_R80_GPIO, 0xf0, 0xff, 10}, | ||
289 | {EM2874_R80_GPIO, 0xb0, 0xff, 10}, | ||
290 | {EM2874_R80_GPIO, 0xf0, 0xff, 10}, | ||
291 | { -1, -1, -1, -1}, | ||
292 | }; | ||
293 | |||
294 | /* 2013:024f PCTV nanoStick T2 290e | ||
295 | * GPIO_6 - demod reset | ||
296 | * GPIO_7 - LED | ||
297 | */ | ||
298 | static struct em28xx_reg_seq pctv_290e[] = { | ||
299 | {EM2874_R80_GPIO, 0x00, 0xff, 80}, | ||
300 | {EM2874_R80_GPIO, 0x40, 0xff, 80}, /* GPIO_6 = 1 */ | ||
301 | {EM2874_R80_GPIO, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */ | ||
302 | {-1, -1, -1, -1}, | ||
303 | }; | ||
304 | |||
305 | #if 0 | ||
306 | static struct em28xx_reg_seq terratec_h5_gpio[] = { | ||
307 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
308 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
309 | {EM2874_R80_GPIO, 0xf2, 0xff, 50}, | ||
310 | {EM2874_R80_GPIO, 0xf6, 0xff, 50}, | ||
311 | { -1, -1, -1, -1}, | ||
312 | }; | ||
313 | |||
314 | static struct em28xx_reg_seq terratec_h5_digital[] = { | ||
315 | {EM2874_R80_GPIO, 0xf6, 0xff, 10}, | ||
316 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
317 | {EM2874_R80_GPIO, 0xa6, 0xff, 10}, | ||
318 | { -1, -1, -1, -1}, | ||
319 | }; | ||
320 | #endif | ||
321 | |||
322 | /* 2013:024f PCTV DVB-S2 Stick 460e | ||
323 | * GPIO_0 - POWER_ON | ||
324 | * GPIO_1 - BOOST | ||
325 | * GPIO_2 - VUV_LNB (red LED) | ||
326 | * GPIO_3 - EXT_12V | ||
327 | * GPIO_4 - INT_DEM (DEMOD GPIO_0) | ||
328 | * GPIO_5 - INT_LNB | ||
329 | * GPIO_6 - RESET_DEM | ||
330 | * GPIO_7 - LED (green LED) | ||
331 | */ | ||
332 | static struct em28xx_reg_seq pctv_460e[] = { | ||
333 | {EM2874_R80_GPIO, 0x01, 0xff, 50}, | ||
334 | {0x0d, 0xff, 0xff, 50}, | ||
335 | {EM2874_R80_GPIO, 0x41, 0xff, 50}, /* GPIO_6=1 */ | ||
336 | {0x0d, 0x42, 0xff, 50}, | ||
337 | {EM2874_R80_GPIO, 0x61, 0xff, 50}, /* GPIO_5=1 */ | ||
338 | { -1, -1, -1, -1}, | ||
339 | }; | ||
340 | |||
341 | #if 0 | ||
342 | static struct em28xx_reg_seq hauppauge_930c_gpio[] = { | ||
343 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
344 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */ | ||
345 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
346 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, | ||
347 | { -1, -1, -1, -1}, | ||
348 | }; | ||
349 | |||
350 | static struct em28xx_reg_seq hauppauge_930c_digital[] = { | ||
351 | {EM2874_R80_GPIO, 0xf6, 0xff, 10}, | ||
352 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
353 | {EM2874_R80_GPIO, 0xa6, 0xff, 10}, | ||
354 | { -1, -1, -1, -1}, | ||
355 | }; | ||
356 | #endif | ||
357 | |||
358 | /* 1b80:e425 MaxMedia UB425-TC | ||
359 | * GPIO_6 - demod reset, 0=active | ||
360 | * GPIO_7 - LED, 0=active | ||
361 | */ | ||
362 | static struct em28xx_reg_seq maxmedia_ub425_tc[] = { | ||
363 | {EM2874_R80_GPIO, 0x83, 0xff, 100}, | ||
364 | {EM2874_R80_GPIO, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ | ||
365 | {EM2874_R80_GPIO, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ | ||
366 | {-1, -1, -1, -1}, | ||
367 | }; | ||
368 | |||
369 | /* 2304:0242 PCTV QuatroStick (510e) | ||
370 | * GPIO_2: decoder reset, 0=active | ||
371 | * GPIO_4: decoder suspend, 0=active | ||
372 | * GPIO_6: demod reset, 0=active | ||
373 | * GPIO_7: LED, 1=active | ||
374 | */ | ||
375 | static struct em28xx_reg_seq pctv_510e[] = { | ||
376 | {EM2874_R80_GPIO, 0x10, 0xff, 100}, | ||
377 | {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | ||
378 | {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | ||
379 | { -1, -1, -1, -1}, | ||
380 | }; | ||
381 | |||
382 | /* 2013:0251 PCTV QuatroStick nano (520e) | ||
383 | * GPIO_2: decoder reset, 0=active | ||
384 | * GPIO_4: decoder suspend, 0=active | ||
385 | * GPIO_6: demod reset, 0=active | ||
386 | * GPIO_7: LED, 1=active | ||
387 | */ | ||
388 | static struct em28xx_reg_seq pctv_520e[] = { | ||
389 | {EM2874_R80_GPIO, 0x10, 0xff, 100}, | ||
390 | {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | ||
391 | {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | ||
392 | {EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */ | ||
393 | { -1, -1, -1, -1}, | ||
394 | }; | ||
395 | |||
396 | /* | ||
397 | * Board definitions | ||
398 | */ | ||
399 | struct em28xx_board em28xx_boards[] = { | ||
400 | [EM2750_BOARD_UNKNOWN] = { | ||
401 | .name = "EM2710/EM2750/EM2751 webcam grabber", | ||
402 | .xclk = EM28XX_XCLK_FREQUENCY_20MHZ, | ||
403 | .tuner_type = TUNER_ABSENT, | ||
404 | .is_webcam = 1, | ||
405 | .input = { { | ||
406 | .type = EM28XX_VMUX_COMPOSITE1, | ||
407 | .vmux = 0, | ||
408 | .amux = EM28XX_AMUX_VIDEO, | ||
409 | .gpio = silvercrest_reg_seq, | ||
410 | } }, | ||
411 | }, | ||
412 | [EM2800_BOARD_UNKNOWN] = { | ||
413 | .name = "Unknown EM2800 video grabber", | ||
414 | .is_em2800 = 1, | ||
415 | .tda9887_conf = TDA9887_PRESENT, | ||
416 | .decoder = EM28XX_SAA711X, | ||
417 | .tuner_type = TUNER_ABSENT, | ||
418 | .input = { { | ||
419 | .type = EM28XX_VMUX_COMPOSITE1, | ||
420 | .vmux = SAA7115_COMPOSITE0, | ||
421 | .amux = EM28XX_AMUX_LINE_IN, | ||
422 | }, { | ||
423 | .type = EM28XX_VMUX_SVIDEO, | ||
424 | .vmux = SAA7115_SVIDEO3, | ||
425 | .amux = EM28XX_AMUX_LINE_IN, | ||
426 | } }, | ||
427 | }, | ||
428 | [EM2820_BOARD_UNKNOWN] = { | ||
429 | .name = "Unknown EM2750/28xx video grabber", | ||
430 | .tuner_type = TUNER_ABSENT, | ||
431 | .is_webcam = 1, /* To enable sensor probe */ | ||
432 | }, | ||
433 | [EM2750_BOARD_DLCW_130] = { | ||
434 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | ||
435 | .name = "Huaqi DLCW-130", | ||
436 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
437 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, | ||
438 | .tuner_type = TUNER_ABSENT, | ||
439 | .is_webcam = 1, | ||
440 | .input = { { | ||
441 | .type = EM28XX_VMUX_COMPOSITE1, | ||
442 | .vmux = 0, | ||
443 | .amux = EM28XX_AMUX_VIDEO, | ||
444 | } }, | ||
445 | }, | ||
446 | [EM2820_BOARD_KWORLD_PVRTV2800RF] = { | ||
447 | .name = "Kworld PVR TV 2800 RF", | ||
448 | .tuner_type = TUNER_TEMIC_PAL, | ||
449 | .tda9887_conf = TDA9887_PRESENT, | ||
450 | .decoder = EM28XX_SAA711X, | ||
451 | .input = { { | ||
452 | .type = EM28XX_VMUX_COMPOSITE1, | ||
453 | .vmux = SAA7115_COMPOSITE0, | ||
454 | .amux = EM28XX_AMUX_LINE_IN, | ||
455 | }, { | ||
456 | .type = EM28XX_VMUX_SVIDEO, | ||
457 | .vmux = SAA7115_SVIDEO3, | ||
458 | .amux = EM28XX_AMUX_LINE_IN, | ||
459 | } }, | ||
460 | }, | ||
461 | [EM2820_BOARD_GADMEI_TVR200] = { | ||
462 | .name = "Gadmei TVR200", | ||
463 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
464 | .tda9887_conf = TDA9887_PRESENT, | ||
465 | .decoder = EM28XX_SAA711X, | ||
466 | .input = { { | ||
467 | .type = EM28XX_VMUX_TELEVISION, | ||
468 | .vmux = SAA7115_COMPOSITE2, | ||
469 | .amux = EM28XX_AMUX_LINE_IN, | ||
470 | }, { | ||
471 | .type = EM28XX_VMUX_COMPOSITE1, | ||
472 | .vmux = SAA7115_COMPOSITE0, | ||
473 | .amux = EM28XX_AMUX_LINE_IN, | ||
474 | }, { | ||
475 | .type = EM28XX_VMUX_SVIDEO, | ||
476 | .vmux = SAA7115_SVIDEO3, | ||
477 | .amux = EM28XX_AMUX_LINE_IN, | ||
478 | } }, | ||
479 | }, | ||
480 | [EM2820_BOARD_TERRATEC_CINERGY_250] = { | ||
481 | .name = "Terratec Cinergy 250 USB", | ||
482 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
483 | .has_ir_i2c = 1, | ||
484 | .tda9887_conf = TDA9887_PRESENT, | ||
485 | .decoder = EM28XX_SAA711X, | ||
486 | .input = { { | ||
487 | .type = EM28XX_VMUX_TELEVISION, | ||
488 | .vmux = SAA7115_COMPOSITE2, | ||
489 | .amux = EM28XX_AMUX_LINE_IN, | ||
490 | }, { | ||
491 | .type = EM28XX_VMUX_COMPOSITE1, | ||
492 | .vmux = SAA7115_COMPOSITE0, | ||
493 | .amux = EM28XX_AMUX_LINE_IN, | ||
494 | }, { | ||
495 | .type = EM28XX_VMUX_SVIDEO, | ||
496 | .vmux = SAA7115_SVIDEO3, | ||
497 | .amux = EM28XX_AMUX_LINE_IN, | ||
498 | } }, | ||
499 | }, | ||
500 | [EM2820_BOARD_PINNACLE_USB_2] = { | ||
501 | .name = "Pinnacle PCTV USB 2", | ||
502 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
503 | .has_ir_i2c = 1, | ||
504 | .tda9887_conf = TDA9887_PRESENT, | ||
505 | .decoder = EM28XX_SAA711X, | ||
506 | .input = { { | ||
507 | .type = EM28XX_VMUX_TELEVISION, | ||
508 | .vmux = SAA7115_COMPOSITE2, | ||
509 | .amux = EM28XX_AMUX_VIDEO, | ||
510 | }, { | ||
511 | .type = EM28XX_VMUX_COMPOSITE1, | ||
512 | .vmux = SAA7115_COMPOSITE0, | ||
513 | .amux = EM28XX_AMUX_LINE_IN, | ||
514 | }, { | ||
515 | .type = EM28XX_VMUX_SVIDEO, | ||
516 | .vmux = SAA7115_SVIDEO3, | ||
517 | .amux = EM28XX_AMUX_LINE_IN, | ||
518 | } }, | ||
519 | }, | ||
520 | [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = { | ||
521 | .name = "Hauppauge WinTV USB 2", | ||
522 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
523 | .tda9887_conf = TDA9887_PRESENT | | ||
524 | TDA9887_PORT1_ACTIVE | | ||
525 | TDA9887_PORT2_ACTIVE, | ||
526 | .decoder = EM28XX_TVP5150, | ||
527 | .has_msp34xx = 1, | ||
528 | .has_ir_i2c = 1, | ||
529 | .input = { { | ||
530 | .type = EM28XX_VMUX_TELEVISION, | ||
531 | .vmux = TVP5150_COMPOSITE0, | ||
532 | .amux = MSP_INPUT_DEFAULT, | ||
533 | }, { | ||
534 | .type = EM28XX_VMUX_SVIDEO, | ||
535 | .vmux = TVP5150_SVIDEO, | ||
536 | .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, | ||
537 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), | ||
538 | } }, | ||
539 | }, | ||
540 | [EM2820_BOARD_DLINK_USB_TV] = { | ||
541 | .name = "D-Link DUB-T210 TV Tuner", | ||
542 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
543 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
544 | .tda9887_conf = TDA9887_PRESENT, | ||
545 | .decoder = EM28XX_SAA711X, | ||
546 | .input = { { | ||
547 | .type = EM28XX_VMUX_TELEVISION, | ||
548 | .vmux = SAA7115_COMPOSITE2, | ||
549 | .amux = EM28XX_AMUX_LINE_IN, | ||
550 | }, { | ||
551 | .type = EM28XX_VMUX_COMPOSITE1, | ||
552 | .vmux = SAA7115_COMPOSITE0, | ||
553 | .amux = EM28XX_AMUX_LINE_IN, | ||
554 | }, { | ||
555 | .type = EM28XX_VMUX_SVIDEO, | ||
556 | .vmux = SAA7115_SVIDEO3, | ||
557 | .amux = EM28XX_AMUX_LINE_IN, | ||
558 | } }, | ||
559 | }, | ||
560 | [EM2820_BOARD_HERCULES_SMART_TV_USB2] = { | ||
561 | .name = "Hercules Smart TV USB 2.0", | ||
562 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
563 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
564 | .tda9887_conf = TDA9887_PRESENT, | ||
565 | .decoder = EM28XX_SAA711X, | ||
566 | .input = { { | ||
567 | .type = EM28XX_VMUX_TELEVISION, | ||
568 | .vmux = SAA7115_COMPOSITE2, | ||
569 | .amux = EM28XX_AMUX_LINE_IN, | ||
570 | }, { | ||
571 | .type = EM28XX_VMUX_COMPOSITE1, | ||
572 | .vmux = SAA7115_COMPOSITE0, | ||
573 | .amux = EM28XX_AMUX_LINE_IN, | ||
574 | }, { | ||
575 | .type = EM28XX_VMUX_SVIDEO, | ||
576 | .vmux = SAA7115_SVIDEO3, | ||
577 | .amux = EM28XX_AMUX_LINE_IN, | ||
578 | } }, | ||
579 | }, | ||
580 | [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = { | ||
581 | .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)", | ||
582 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
583 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
584 | .tda9887_conf = TDA9887_PRESENT, | ||
585 | .decoder = EM28XX_SAA711X, | ||
586 | .input = { { | ||
587 | .type = EM28XX_VMUX_TELEVISION, | ||
588 | .vmux = SAA7115_COMPOSITE2, | ||
589 | .amux = EM28XX_AMUX_VIDEO, | ||
590 | }, { | ||
591 | .type = EM28XX_VMUX_COMPOSITE1, | ||
592 | .vmux = SAA7115_COMPOSITE0, | ||
593 | .amux = EM28XX_AMUX_LINE_IN, | ||
594 | }, { | ||
595 | .type = EM28XX_VMUX_SVIDEO, | ||
596 | .vmux = SAA7115_SVIDEO3, | ||
597 | .amux = EM28XX_AMUX_LINE_IN, | ||
598 | } }, | ||
599 | }, | ||
600 | [EM2820_BOARD_GADMEI_UTV310] = { | ||
601 | .name = "Gadmei UTV310", | ||
602 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
603 | .tuner_type = TUNER_TNF_5335MF, | ||
604 | .tda9887_conf = TDA9887_PRESENT, | ||
605 | .decoder = EM28XX_SAA711X, | ||
606 | .input = { { | ||
607 | .type = EM28XX_VMUX_TELEVISION, | ||
608 | .vmux = SAA7115_COMPOSITE1, | ||
609 | .amux = EM28XX_AMUX_LINE_IN, | ||
610 | }, { | ||
611 | .type = EM28XX_VMUX_COMPOSITE1, | ||
612 | .vmux = SAA7115_COMPOSITE0, | ||
613 | .amux = EM28XX_AMUX_LINE_IN, | ||
614 | }, { | ||
615 | .type = EM28XX_VMUX_SVIDEO, | ||
616 | .vmux = SAA7115_SVIDEO3, | ||
617 | .amux = EM28XX_AMUX_LINE_IN, | ||
618 | } }, | ||
619 | }, | ||
620 | [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = { | ||
621 | .name = "Leadtek Winfast USB II Deluxe", | ||
622 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
623 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
624 | .has_ir_i2c = 1, | ||
625 | .tvaudio_addr = 0x58, | ||
626 | .tda9887_conf = TDA9887_PRESENT | | ||
627 | TDA9887_PORT2_ACTIVE | | ||
628 | TDA9887_QSS, | ||
629 | .decoder = EM28XX_SAA711X, | ||
630 | .adecoder = EM28XX_TVAUDIO, | ||
631 | .input = { { | ||
632 | .type = EM28XX_VMUX_TELEVISION, | ||
633 | .vmux = SAA7115_COMPOSITE4, | ||
634 | .amux = EM28XX_AMUX_AUX, | ||
635 | }, { | ||
636 | .type = EM28XX_VMUX_COMPOSITE1, | ||
637 | .vmux = SAA7115_COMPOSITE5, | ||
638 | .amux = EM28XX_AMUX_LINE_IN, | ||
639 | }, { | ||
640 | .type = EM28XX_VMUX_SVIDEO, | ||
641 | .vmux = SAA7115_SVIDEO3, | ||
642 | .amux = EM28XX_AMUX_LINE_IN, | ||
643 | } }, | ||
644 | .radio = { | ||
645 | .type = EM28XX_RADIO, | ||
646 | .amux = EM28XX_AMUX_AUX, | ||
647 | } | ||
648 | }, | ||
649 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { | ||
650 | .name = "Videology 20K14XUSB USB2.0", | ||
651 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
652 | .tuner_type = TUNER_ABSENT, | ||
653 | .is_webcam = 1, | ||
654 | .input = { { | ||
655 | .type = EM28XX_VMUX_COMPOSITE1, | ||
656 | .vmux = 0, | ||
657 | .amux = EM28XX_AMUX_VIDEO, | ||
658 | } }, | ||
659 | }, | ||
660 | [EM2820_BOARD_SILVERCREST_WEBCAM] = { | ||
661 | .name = "Silvercrest Webcam 1.3mpix", | ||
662 | .tuner_type = TUNER_ABSENT, | ||
663 | .is_webcam = 1, | ||
664 | .input = { { | ||
665 | .type = EM28XX_VMUX_COMPOSITE1, | ||
666 | .vmux = 0, | ||
667 | .amux = EM28XX_AMUX_VIDEO, | ||
668 | .gpio = silvercrest_reg_seq, | ||
669 | } }, | ||
670 | }, | ||
671 | [EM2821_BOARD_SUPERCOMP_USB_2] = { | ||
672 | .name = "Supercomp USB 2.0 TV", | ||
673 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
674 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
675 | .tda9887_conf = TDA9887_PRESENT | | ||
676 | TDA9887_PORT1_ACTIVE | | ||
677 | TDA9887_PORT2_ACTIVE, | ||
678 | .decoder = EM28XX_SAA711X, | ||
679 | .input = { { | ||
680 | .type = EM28XX_VMUX_TELEVISION, | ||
681 | .vmux = SAA7115_COMPOSITE2, | ||
682 | .amux = EM28XX_AMUX_LINE_IN, | ||
683 | }, { | ||
684 | .type = EM28XX_VMUX_COMPOSITE1, | ||
685 | .vmux = SAA7115_COMPOSITE0, | ||
686 | .amux = EM28XX_AMUX_VIDEO, | ||
687 | }, { | ||
688 | .type = EM28XX_VMUX_SVIDEO, | ||
689 | .vmux = SAA7115_SVIDEO3, | ||
690 | .amux = EM28XX_AMUX_LINE_IN, | ||
691 | } }, | ||
692 | }, | ||
693 | [EM2821_BOARD_USBGEAR_VD204] = { | ||
694 | .name = "Usbgear VD204v9", | ||
695 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
696 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
697 | .decoder = EM28XX_SAA711X, | ||
698 | .input = { { | ||
699 | .type = EM28XX_VMUX_COMPOSITE1, | ||
700 | .vmux = SAA7115_COMPOSITE0, | ||
701 | .amux = EM28XX_AMUX_LINE_IN, | ||
702 | }, { | ||
703 | .type = EM28XX_VMUX_SVIDEO, | ||
704 | .vmux = SAA7115_SVIDEO3, | ||
705 | .amux = EM28XX_AMUX_LINE_IN, | ||
706 | } }, | ||
707 | }, | ||
708 | [EM2860_BOARD_NETGMBH_CAM] = { | ||
709 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | ||
710 | .name = "NetGMBH Cam", | ||
711 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
712 | .tuner_type = TUNER_ABSENT, | ||
713 | .is_webcam = 1, | ||
714 | .input = { { | ||
715 | .type = EM28XX_VMUX_COMPOSITE1, | ||
716 | .vmux = 0, | ||
717 | .amux = EM28XX_AMUX_VIDEO, | ||
718 | } }, | ||
719 | }, | ||
720 | [EM2860_BOARD_TYPHOON_DVD_MAKER] = { | ||
721 | .name = "Typhoon DVD Maker", | ||
722 | .decoder = EM28XX_SAA711X, | ||
723 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
724 | .input = { { | ||
725 | .type = EM28XX_VMUX_COMPOSITE1, | ||
726 | .vmux = SAA7115_COMPOSITE0, | ||
727 | .amux = EM28XX_AMUX_LINE_IN, | ||
728 | }, { | ||
729 | .type = EM28XX_VMUX_SVIDEO, | ||
730 | .vmux = SAA7115_SVIDEO3, | ||
731 | .amux = EM28XX_AMUX_LINE_IN, | ||
732 | } }, | ||
733 | }, | ||
734 | [EM2860_BOARD_GADMEI_UTV330] = { | ||
735 | .name = "Gadmei UTV330", | ||
736 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
737 | .tuner_type = TUNER_TNF_5335MF, | ||
738 | .tda9887_conf = TDA9887_PRESENT, | ||
739 | .decoder = EM28XX_SAA711X, | ||
740 | .input = { { | ||
741 | .type = EM28XX_VMUX_TELEVISION, | ||
742 | .vmux = SAA7115_COMPOSITE2, | ||
743 | .amux = EM28XX_AMUX_VIDEO, | ||
744 | }, { | ||
745 | .type = EM28XX_VMUX_COMPOSITE1, | ||
746 | .vmux = SAA7115_COMPOSITE0, | ||
747 | .amux = EM28XX_AMUX_LINE_IN, | ||
748 | }, { | ||
749 | .type = EM28XX_VMUX_SVIDEO, | ||
750 | .vmux = SAA7115_SVIDEO3, | ||
751 | .amux = EM28XX_AMUX_LINE_IN, | ||
752 | } }, | ||
753 | }, | ||
754 | [EM2861_BOARD_GADMEI_UTV330PLUS] = { | ||
755 | .name = "Gadmei UTV330+", | ||
756 | .tuner_type = TUNER_TNF_5335MF, | ||
757 | .tda9887_conf = TDA9887_PRESENT, | ||
758 | .ir_codes = RC_MAP_GADMEI_RM008Z, | ||
759 | .decoder = EM28XX_SAA711X, | ||
760 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
761 | .input = { { | ||
762 | .type = EM28XX_VMUX_TELEVISION, | ||
763 | .vmux = SAA7115_COMPOSITE2, | ||
764 | .amux = EM28XX_AMUX_VIDEO, | ||
765 | }, { | ||
766 | .type = EM28XX_VMUX_COMPOSITE1, | ||
767 | .vmux = SAA7115_COMPOSITE0, | ||
768 | .amux = EM28XX_AMUX_LINE_IN, | ||
769 | }, { | ||
770 | .type = EM28XX_VMUX_SVIDEO, | ||
771 | .vmux = SAA7115_SVIDEO3, | ||
772 | .amux = EM28XX_AMUX_LINE_IN, | ||
773 | } }, | ||
774 | }, | ||
775 | [EM2860_BOARD_TERRATEC_HYBRID_XS] = { | ||
776 | .name = "Terratec Cinergy A Hybrid XS", | ||
777 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
778 | .tuner_type = TUNER_XC2028, | ||
779 | .tuner_gpio = default_tuner_gpio, | ||
780 | .decoder = EM28XX_TVP5150, | ||
781 | |||
782 | .input = { { | ||
783 | .type = EM28XX_VMUX_TELEVISION, | ||
784 | .vmux = TVP5150_COMPOSITE0, | ||
785 | .amux = EM28XX_AMUX_VIDEO, | ||
786 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
787 | }, { | ||
788 | .type = EM28XX_VMUX_COMPOSITE1, | ||
789 | .vmux = TVP5150_COMPOSITE1, | ||
790 | .amux = EM28XX_AMUX_LINE_IN, | ||
791 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
792 | }, { | ||
793 | .type = EM28XX_VMUX_SVIDEO, | ||
794 | .vmux = TVP5150_SVIDEO, | ||
795 | .amux = EM28XX_AMUX_LINE_IN, | ||
796 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
797 | } }, | ||
798 | }, | ||
799 | [EM2861_BOARD_KWORLD_PVRTV_300U] = { | ||
800 | .name = "KWorld PVRTV 300U", | ||
801 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
802 | .tuner_type = TUNER_XC2028, | ||
803 | .tuner_gpio = default_tuner_gpio, | ||
804 | .decoder = EM28XX_TVP5150, | ||
805 | .input = { { | ||
806 | .type = EM28XX_VMUX_TELEVISION, | ||
807 | .vmux = TVP5150_COMPOSITE0, | ||
808 | .amux = EM28XX_AMUX_VIDEO, | ||
809 | }, { | ||
810 | .type = EM28XX_VMUX_COMPOSITE1, | ||
811 | .vmux = TVP5150_COMPOSITE1, | ||
812 | .amux = EM28XX_AMUX_LINE_IN, | ||
813 | }, { | ||
814 | .type = EM28XX_VMUX_SVIDEO, | ||
815 | .vmux = TVP5150_SVIDEO, | ||
816 | .amux = EM28XX_AMUX_LINE_IN, | ||
817 | } }, | ||
818 | }, | ||
819 | [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { | ||
820 | .name = "Yakumo MovieMixer", | ||
821 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
822 | .decoder = EM28XX_TVP5150, | ||
823 | .input = { { | ||
824 | .type = EM28XX_VMUX_TELEVISION, | ||
825 | .vmux = TVP5150_COMPOSITE0, | ||
826 | .amux = EM28XX_AMUX_VIDEO, | ||
827 | }, { | ||
828 | .type = EM28XX_VMUX_COMPOSITE1, | ||
829 | .vmux = TVP5150_COMPOSITE1, | ||
830 | .amux = EM28XX_AMUX_LINE_IN, | ||
831 | }, { | ||
832 | .type = EM28XX_VMUX_SVIDEO, | ||
833 | .vmux = TVP5150_SVIDEO, | ||
834 | .amux = EM28XX_AMUX_LINE_IN, | ||
835 | } }, | ||
836 | }, | ||
837 | [EM2860_BOARD_TVP5150_REFERENCE_DESIGN] = { | ||
838 | .name = "EM2860/TVP5150 Reference Design", | ||
839 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
840 | .decoder = EM28XX_TVP5150, | ||
841 | .input = { { | ||
842 | .type = EM28XX_VMUX_COMPOSITE1, | ||
843 | .vmux = TVP5150_COMPOSITE1, | ||
844 | .amux = EM28XX_AMUX_LINE_IN, | ||
845 | }, { | ||
846 | .type = EM28XX_VMUX_SVIDEO, | ||
847 | .vmux = TVP5150_SVIDEO, | ||
848 | .amux = EM28XX_AMUX_LINE_IN, | ||
849 | } }, | ||
850 | }, | ||
851 | [EM2861_BOARD_PLEXTOR_PX_TV100U] = { | ||
852 | .name = "Plextor ConvertX PX-TV100U", | ||
853 | .tuner_type = TUNER_TNF_5335MF, | ||
854 | .xclk = EM28XX_XCLK_I2S_MSB_TIMING | | ||
855 | EM28XX_XCLK_FREQUENCY_12MHZ, | ||
856 | .tda9887_conf = TDA9887_PRESENT, | ||
857 | .decoder = EM28XX_TVP5150, | ||
858 | .has_msp34xx = 1, | ||
859 | .input = { { | ||
860 | .type = EM28XX_VMUX_TELEVISION, | ||
861 | .vmux = TVP5150_COMPOSITE0, | ||
862 | .amux = EM28XX_AMUX_LINE_IN, | ||
863 | .gpio = pinnacle_hybrid_pro_analog, | ||
864 | }, { | ||
865 | .type = EM28XX_VMUX_COMPOSITE1, | ||
866 | .vmux = TVP5150_COMPOSITE1, | ||
867 | .amux = EM28XX_AMUX_LINE_IN, | ||
868 | .gpio = pinnacle_hybrid_pro_analog, | ||
869 | }, { | ||
870 | .type = EM28XX_VMUX_SVIDEO, | ||
871 | .vmux = TVP5150_SVIDEO, | ||
872 | .amux = EM28XX_AMUX_LINE_IN, | ||
873 | .gpio = pinnacle_hybrid_pro_analog, | ||
874 | } }, | ||
875 | }, | ||
876 | |||
877 | /* Those boards with em2870 are DVB Only*/ | ||
878 | |||
879 | [EM2870_BOARD_TERRATEC_XS] = { | ||
880 | .name = "Terratec Cinergy T XS", | ||
881 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
882 | .tuner_type = TUNER_XC2028, | ||
883 | .tuner_gpio = default_tuner_gpio, | ||
884 | }, | ||
885 | [EM2870_BOARD_TERRATEC_XS_MT2060] = { | ||
886 | .name = "Terratec Cinergy T XS (MT2060)", | ||
887 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
888 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | ||
889 | }, | ||
890 | [EM2870_BOARD_KWORLD_350U] = { | ||
891 | .name = "Kworld 350 U DVB-T", | ||
892 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
893 | .tuner_type = TUNER_XC2028, | ||
894 | .tuner_gpio = default_tuner_gpio, | ||
895 | }, | ||
896 | [EM2870_BOARD_KWORLD_355U] = { | ||
897 | .name = "Kworld 355 U DVB-T", | ||
898 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
899 | .tuner_type = TUNER_ABSENT, | ||
900 | .tuner_gpio = default_tuner_gpio, | ||
901 | .has_dvb = 1, | ||
902 | .dvb_gpio = default_digital, | ||
903 | }, | ||
904 | [EM2870_BOARD_PINNACLE_PCTV_DVB] = { | ||
905 | .name = "Pinnacle PCTV DVB-T", | ||
906 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
907 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | ||
908 | /* djh - I have serious doubts this is right... */ | ||
909 | .xclk = EM28XX_XCLK_IR_RC5_MODE | | ||
910 | EM28XX_XCLK_FREQUENCY_10MHZ, | ||
911 | }, | ||
912 | [EM2870_BOARD_COMPRO_VIDEOMATE] = { | ||
913 | .name = "Compro, VideoMate U3", | ||
914 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
915 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | ||
916 | }, | ||
917 | |||
918 | [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { | ||
919 | .name = "Terratec Hybrid XS Secam", | ||
920 | .has_msp34xx = 1, | ||
921 | .tuner_type = TUNER_XC2028, | ||
922 | .tuner_gpio = default_tuner_gpio, | ||
923 | .decoder = EM28XX_TVP5150, | ||
924 | .has_dvb = 1, | ||
925 | .dvb_gpio = terratec_cinergy_USB_XS_FR_digital, | ||
926 | .input = { { | ||
927 | .type = EM28XX_VMUX_TELEVISION, | ||
928 | .vmux = TVP5150_COMPOSITE0, | ||
929 | .amux = EM28XX_AMUX_VIDEO, | ||
930 | .gpio = terratec_cinergy_USB_XS_FR_analog, | ||
931 | }, { | ||
932 | .type = EM28XX_VMUX_COMPOSITE1, | ||
933 | .vmux = TVP5150_COMPOSITE1, | ||
934 | .amux = EM28XX_AMUX_LINE_IN, | ||
935 | .gpio = terratec_cinergy_USB_XS_FR_analog, | ||
936 | }, { | ||
937 | .type = EM28XX_VMUX_SVIDEO, | ||
938 | .vmux = TVP5150_SVIDEO, | ||
939 | .amux = EM28XX_AMUX_LINE_IN, | ||
940 | .gpio = terratec_cinergy_USB_XS_FR_analog, | ||
941 | } }, | ||
942 | }, | ||
943 | [EM2884_BOARD_TERRATEC_H5] = { | ||
944 | .name = "Terratec Cinergy H5", | ||
945 | .has_dvb = 1, | ||
946 | #if 0 | ||
947 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
948 | .tuner_addr = 0x41, | ||
949 | .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ | ||
950 | .tuner_gpio = terratec_h5_gpio, | ||
951 | #else | ||
952 | .tuner_type = TUNER_ABSENT, | ||
953 | #endif | ||
954 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
955 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
956 | EM28XX_I2C_FREQ_400_KHZ, | ||
957 | }, | ||
958 | [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { | ||
959 | .name = "Hauppauge WinTV HVR 930C", | ||
960 | .has_dvb = 1, | ||
961 | #if 0 /* FIXME: Add analog support */ | ||
962 | .tuner_type = TUNER_XC5000, | ||
963 | .tuner_addr = 0x41, | ||
964 | .dvb_gpio = hauppauge_930c_digital, | ||
965 | .tuner_gpio = hauppauge_930c_gpio, | ||
966 | #else | ||
967 | .tuner_type = TUNER_ABSENT, | ||
968 | #endif | ||
969 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
970 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
971 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
972 | EM28XX_I2C_FREQ_400_KHZ, | ||
973 | }, | ||
974 | [EM2884_BOARD_CINERGY_HTC_STICK] = { | ||
975 | .name = "Terratec Cinergy HTC Stick", | ||
976 | .has_dvb = 1, | ||
977 | .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, | ||
978 | .tuner_type = TUNER_ABSENT, | ||
979 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
980 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
981 | EM28XX_I2C_FREQ_400_KHZ, | ||
982 | }, | ||
983 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { | ||
984 | .name = "Hauppauge WinTV HVR 900", | ||
985 | .tda9887_conf = TDA9887_PRESENT, | ||
986 | .tuner_type = TUNER_XC2028, | ||
987 | .tuner_gpio = default_tuner_gpio, | ||
988 | .mts_firmware = 1, | ||
989 | .has_dvb = 1, | ||
990 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
991 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
992 | .decoder = EM28XX_TVP5150, | ||
993 | .input = { { | ||
994 | .type = EM28XX_VMUX_TELEVISION, | ||
995 | .vmux = TVP5150_COMPOSITE0, | ||
996 | .amux = EM28XX_AMUX_VIDEO, | ||
997 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
998 | }, { | ||
999 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1000 | .vmux = TVP5150_COMPOSITE1, | ||
1001 | .amux = EM28XX_AMUX_LINE_IN, | ||
1002 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1003 | }, { | ||
1004 | .type = EM28XX_VMUX_SVIDEO, | ||
1005 | .vmux = TVP5150_SVIDEO, | ||
1006 | .amux = EM28XX_AMUX_LINE_IN, | ||
1007 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1008 | } }, | ||
1009 | }, | ||
1010 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { | ||
1011 | .name = "Hauppauge WinTV HVR 900 (R2)", | ||
1012 | .tda9887_conf = TDA9887_PRESENT, | ||
1013 | .tuner_type = TUNER_XC2028, | ||
1014 | .tuner_gpio = default_tuner_gpio, | ||
1015 | .mts_firmware = 1, | ||
1016 | .has_dvb = 1, | ||
1017 | .dvb_gpio = hauppauge_wintv_hvr_900R2_digital, | ||
1018 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
1019 | .decoder = EM28XX_TVP5150, | ||
1020 | .input = { { | ||
1021 | .type = EM28XX_VMUX_TELEVISION, | ||
1022 | .vmux = TVP5150_COMPOSITE0, | ||
1023 | .amux = EM28XX_AMUX_VIDEO, | ||
1024 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1025 | }, { | ||
1026 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1027 | .vmux = TVP5150_COMPOSITE1, | ||
1028 | .amux = EM28XX_AMUX_LINE_IN, | ||
1029 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1030 | }, { | ||
1031 | .type = EM28XX_VMUX_SVIDEO, | ||
1032 | .vmux = TVP5150_SVIDEO, | ||
1033 | .amux = EM28XX_AMUX_LINE_IN, | ||
1034 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1035 | } }, | ||
1036 | }, | ||
1037 | [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = { | ||
1038 | .name = "Hauppauge WinTV HVR 850", | ||
1039 | .tuner_type = TUNER_XC2028, | ||
1040 | .tuner_gpio = default_tuner_gpio, | ||
1041 | .mts_firmware = 1, | ||
1042 | .has_dvb = 1, | ||
1043 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1044 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
1045 | .decoder = EM28XX_TVP5150, | ||
1046 | .input = { { | ||
1047 | .type = EM28XX_VMUX_TELEVISION, | ||
1048 | .vmux = TVP5150_COMPOSITE0, | ||
1049 | .amux = EM28XX_AMUX_VIDEO, | ||
1050 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1051 | }, { | ||
1052 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1053 | .vmux = TVP5150_COMPOSITE1, | ||
1054 | .amux = EM28XX_AMUX_LINE_IN, | ||
1055 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1056 | }, { | ||
1057 | .type = EM28XX_VMUX_SVIDEO, | ||
1058 | .vmux = TVP5150_SVIDEO, | ||
1059 | .amux = EM28XX_AMUX_LINE_IN, | ||
1060 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1061 | } }, | ||
1062 | }, | ||
1063 | [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { | ||
1064 | .name = "Hauppauge WinTV HVR 950", | ||
1065 | .tuner_type = TUNER_XC2028, | ||
1066 | .tuner_gpio = default_tuner_gpio, | ||
1067 | .mts_firmware = 1, | ||
1068 | .has_dvb = 1, | ||
1069 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1070 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
1071 | .decoder = EM28XX_TVP5150, | ||
1072 | .input = { { | ||
1073 | .type = EM28XX_VMUX_TELEVISION, | ||
1074 | .vmux = TVP5150_COMPOSITE0, | ||
1075 | .amux = EM28XX_AMUX_VIDEO, | ||
1076 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1077 | }, { | ||
1078 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1079 | .vmux = TVP5150_COMPOSITE1, | ||
1080 | .amux = EM28XX_AMUX_LINE_IN, | ||
1081 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1082 | }, { | ||
1083 | .type = EM28XX_VMUX_SVIDEO, | ||
1084 | .vmux = TVP5150_SVIDEO, | ||
1085 | .amux = EM28XX_AMUX_LINE_IN, | ||
1086 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1087 | } }, | ||
1088 | }, | ||
1089 | [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { | ||
1090 | .name = "Pinnacle PCTV HD Pro Stick", | ||
1091 | .tuner_type = TUNER_XC2028, | ||
1092 | .tuner_gpio = default_tuner_gpio, | ||
1093 | .mts_firmware = 1, | ||
1094 | .has_dvb = 1, | ||
1095 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1096 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1097 | .decoder = EM28XX_TVP5150, | ||
1098 | .input = { { | ||
1099 | .type = EM28XX_VMUX_TELEVISION, | ||
1100 | .vmux = TVP5150_COMPOSITE0, | ||
1101 | .amux = EM28XX_AMUX_VIDEO, | ||
1102 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1103 | }, { | ||
1104 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1105 | .vmux = TVP5150_COMPOSITE1, | ||
1106 | .amux = EM28XX_AMUX_LINE_IN, | ||
1107 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1108 | }, { | ||
1109 | .type = EM28XX_VMUX_SVIDEO, | ||
1110 | .vmux = TVP5150_SVIDEO, | ||
1111 | .amux = EM28XX_AMUX_LINE_IN, | ||
1112 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1113 | } }, | ||
1114 | }, | ||
1115 | [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { | ||
1116 | .name = "AMD ATI TV Wonder HD 600", | ||
1117 | .tuner_type = TUNER_XC2028, | ||
1118 | .tuner_gpio = default_tuner_gpio, | ||
1119 | .mts_firmware = 1, | ||
1120 | .has_dvb = 1, | ||
1121 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1122 | .ir_codes = RC_MAP_ATI_TV_WONDER_HD_600, | ||
1123 | .decoder = EM28XX_TVP5150, | ||
1124 | .input = { { | ||
1125 | .type = EM28XX_VMUX_TELEVISION, | ||
1126 | .vmux = TVP5150_COMPOSITE0, | ||
1127 | .amux = EM28XX_AMUX_VIDEO, | ||
1128 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1129 | }, { | ||
1130 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1131 | .vmux = TVP5150_COMPOSITE1, | ||
1132 | .amux = EM28XX_AMUX_LINE_IN, | ||
1133 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1134 | }, { | ||
1135 | .type = EM28XX_VMUX_SVIDEO, | ||
1136 | .vmux = TVP5150_SVIDEO, | ||
1137 | .amux = EM28XX_AMUX_LINE_IN, | ||
1138 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1139 | } }, | ||
1140 | }, | ||
1141 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { | ||
1142 | .name = "Terratec Hybrid XS", | ||
1143 | .tuner_type = TUNER_XC2028, | ||
1144 | .tuner_gpio = default_tuner_gpio, | ||
1145 | .decoder = EM28XX_TVP5150, | ||
1146 | .has_dvb = 1, | ||
1147 | .dvb_gpio = default_digital, | ||
1148 | .ir_codes = RC_MAP_TERRATEC_CINERGY_XS, | ||
1149 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ | ||
1150 | .input = { { | ||
1151 | .type = EM28XX_VMUX_TELEVISION, | ||
1152 | .vmux = TVP5150_COMPOSITE0, | ||
1153 | .amux = EM28XX_AMUX_VIDEO, | ||
1154 | .gpio = default_analog, | ||
1155 | }, { | ||
1156 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1157 | .vmux = TVP5150_COMPOSITE1, | ||
1158 | .amux = EM28XX_AMUX_LINE_IN, | ||
1159 | .gpio = default_analog, | ||
1160 | }, { | ||
1161 | .type = EM28XX_VMUX_SVIDEO, | ||
1162 | .vmux = TVP5150_SVIDEO, | ||
1163 | .amux = EM28XX_AMUX_LINE_IN, | ||
1164 | .gpio = default_analog, | ||
1165 | } }, | ||
1166 | }, | ||
1167 | /* maybe there's a reason behind it why Terratec sells the Hybrid XS | ||
1168 | as Prodigy XS with a different PID, let's keep it separated for now | ||
1169 | maybe we'll need it lateron */ | ||
1170 | [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { | ||
1171 | .name = "Terratec Prodigy XS", | ||
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 | } }, | ||
1191 | }, | ||
1192 | [EM2820_BOARD_MSI_VOX_USB_2] = { | ||
1193 | .name = "MSI VOX USB 2.0", | ||
1194 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1195 | .tda9887_conf = TDA9887_PRESENT | | ||
1196 | TDA9887_PORT1_ACTIVE | | ||
1197 | TDA9887_PORT2_ACTIVE, | ||
1198 | .max_range_640_480 = 1, | ||
1199 | .decoder = EM28XX_SAA711X, | ||
1200 | .input = { { | ||
1201 | .type = EM28XX_VMUX_TELEVISION, | ||
1202 | .vmux = SAA7115_COMPOSITE4, | ||
1203 | .amux = EM28XX_AMUX_VIDEO, | ||
1204 | }, { | ||
1205 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1206 | .vmux = SAA7115_COMPOSITE0, | ||
1207 | .amux = EM28XX_AMUX_LINE_IN, | ||
1208 | }, { | ||
1209 | .type = EM28XX_VMUX_SVIDEO, | ||
1210 | .vmux = SAA7115_SVIDEO3, | ||
1211 | .amux = EM28XX_AMUX_LINE_IN, | ||
1212 | } }, | ||
1213 | }, | ||
1214 | [EM2800_BOARD_TERRATEC_CINERGY_200] = { | ||
1215 | .name = "Terratec Cinergy 200 USB", | ||
1216 | .is_em2800 = 1, | ||
1217 | .has_ir_i2c = 1, | ||
1218 | .tuner_type = TUNER_LG_TALN, | ||
1219 | .tda9887_conf = TDA9887_PRESENT, | ||
1220 | .decoder = EM28XX_SAA711X, | ||
1221 | .input = { { | ||
1222 | .type = EM28XX_VMUX_TELEVISION, | ||
1223 | .vmux = SAA7115_COMPOSITE2, | ||
1224 | .amux = EM28XX_AMUX_VIDEO, | ||
1225 | }, { | ||
1226 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1227 | .vmux = SAA7115_COMPOSITE0, | ||
1228 | .amux = EM28XX_AMUX_LINE_IN, | ||
1229 | }, { | ||
1230 | .type = EM28XX_VMUX_SVIDEO, | ||
1231 | .vmux = SAA7115_SVIDEO3, | ||
1232 | .amux = EM28XX_AMUX_LINE_IN, | ||
1233 | } }, | ||
1234 | }, | ||
1235 | [EM2800_BOARD_GRABBEEX_USB2800] = { | ||
1236 | .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", | ||
1237 | .is_em2800 = 1, | ||
1238 | .decoder = EM28XX_SAA711X, | ||
1239 | .tuner_type = TUNER_ABSENT, /* capture only board */ | ||
1240 | .input = { { | ||
1241 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1242 | .vmux = SAA7115_COMPOSITE0, | ||
1243 | .amux = EM28XX_AMUX_LINE_IN, | ||
1244 | }, { | ||
1245 | .type = EM28XX_VMUX_SVIDEO, | ||
1246 | .vmux = SAA7115_SVIDEO3, | ||
1247 | .amux = EM28XX_AMUX_LINE_IN, | ||
1248 | } }, | ||
1249 | }, | ||
1250 | [EM2800_BOARD_VC211A] = { | ||
1251 | .name = "Actionmaster/LinXcel/Digitus VC211A", | ||
1252 | .is_em2800 = 1, | ||
1253 | .tuner_type = TUNER_ABSENT, /* Capture-only board */ | ||
1254 | .decoder = EM28XX_SAA711X, | ||
1255 | .input = { { | ||
1256 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1257 | .vmux = SAA7115_COMPOSITE0, | ||
1258 | .amux = EM28XX_AMUX_LINE_IN, | ||
1259 | .gpio = vc211a_enable, | ||
1260 | }, { | ||
1261 | .type = EM28XX_VMUX_SVIDEO, | ||
1262 | .vmux = SAA7115_SVIDEO3, | ||
1263 | .amux = EM28XX_AMUX_LINE_IN, | ||
1264 | .gpio = vc211a_enable, | ||
1265 | } }, | ||
1266 | }, | ||
1267 | [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { | ||
1268 | .name = "Leadtek Winfast USB II", | ||
1269 | .is_em2800 = 1, | ||
1270 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1271 | .tda9887_conf = TDA9887_PRESENT, | ||
1272 | .decoder = EM28XX_SAA711X, | ||
1273 | .input = { { | ||
1274 | .type = EM28XX_VMUX_TELEVISION, | ||
1275 | .vmux = SAA7115_COMPOSITE2, | ||
1276 | .amux = EM28XX_AMUX_VIDEO, | ||
1277 | }, { | ||
1278 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1279 | .vmux = SAA7115_COMPOSITE0, | ||
1280 | .amux = EM28XX_AMUX_LINE_IN, | ||
1281 | }, { | ||
1282 | .type = EM28XX_VMUX_SVIDEO, | ||
1283 | .vmux = SAA7115_SVIDEO3, | ||
1284 | .amux = EM28XX_AMUX_LINE_IN, | ||
1285 | } }, | ||
1286 | }, | ||
1287 | [EM2800_BOARD_KWORLD_USB2800] = { | ||
1288 | .name = "Kworld USB2800", | ||
1289 | .is_em2800 = 1, | ||
1290 | .tuner_type = TUNER_PHILIPS_FCV1236D, | ||
1291 | .tda9887_conf = TDA9887_PRESENT, | ||
1292 | .decoder = EM28XX_SAA711X, | ||
1293 | .input = { { | ||
1294 | .type = EM28XX_VMUX_TELEVISION, | ||
1295 | .vmux = SAA7115_COMPOSITE2, | ||
1296 | .amux = EM28XX_AMUX_VIDEO, | ||
1297 | }, { | ||
1298 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1299 | .vmux = SAA7115_COMPOSITE0, | ||
1300 | .amux = EM28XX_AMUX_LINE_IN, | ||
1301 | }, { | ||
1302 | .type = EM28XX_VMUX_SVIDEO, | ||
1303 | .vmux = SAA7115_SVIDEO3, | ||
1304 | .amux = EM28XX_AMUX_LINE_IN, | ||
1305 | } }, | ||
1306 | }, | ||
1307 | [EM2820_BOARD_PINNACLE_DVC_90] = { | ||
1308 | .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker " | ||
1309 | "/ Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U", | ||
1310 | .tuner_type = TUNER_ABSENT, /* capture only board */ | ||
1311 | .decoder = EM28XX_SAA711X, | ||
1312 | .input = { { | ||
1313 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1314 | .vmux = SAA7115_COMPOSITE0, | ||
1315 | .amux = EM28XX_AMUX_LINE_IN, | ||
1316 | }, { | ||
1317 | .type = EM28XX_VMUX_SVIDEO, | ||
1318 | .vmux = SAA7115_SVIDEO3, | ||
1319 | .amux = EM28XX_AMUX_LINE_IN, | ||
1320 | } }, | ||
1321 | }, | ||
1322 | [EM2800_BOARD_VGEAR_POCKETTV] = { | ||
1323 | .name = "V-Gear PocketTV", | ||
1324 | .is_em2800 = 1, | ||
1325 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1326 | .tda9887_conf = TDA9887_PRESENT, | ||
1327 | .decoder = EM28XX_SAA711X, | ||
1328 | .input = { { | ||
1329 | .type = EM28XX_VMUX_TELEVISION, | ||
1330 | .vmux = SAA7115_COMPOSITE2, | ||
1331 | .amux = EM28XX_AMUX_VIDEO, | ||
1332 | }, { | ||
1333 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1334 | .vmux = SAA7115_COMPOSITE0, | ||
1335 | .amux = EM28XX_AMUX_LINE_IN, | ||
1336 | }, { | ||
1337 | .type = EM28XX_VMUX_SVIDEO, | ||
1338 | .vmux = SAA7115_SVIDEO3, | ||
1339 | .amux = EM28XX_AMUX_LINE_IN, | ||
1340 | } }, | ||
1341 | }, | ||
1342 | [EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = { | ||
1343 | .name = "Pixelview PlayTV Box 4 USB 2.0", | ||
1344 | .tda9887_conf = TDA9887_PRESENT, | ||
1345 | .tuner_type = TUNER_YMEC_TVF_5533MF, | ||
1346 | .decoder = EM28XX_SAA711X, | ||
1347 | .input = { { | ||
1348 | .type = EM28XX_VMUX_TELEVISION, | ||
1349 | .vmux = SAA7115_COMPOSITE2, | ||
1350 | .amux = EM28XX_AMUX_VIDEO, | ||
1351 | .aout = EM28XX_AOUT_MONO | /* I2S */ | ||
1352 | EM28XX_AOUT_MASTER, /* Line out pin */ | ||
1353 | }, { | ||
1354 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1355 | .vmux = SAA7115_COMPOSITE0, | ||
1356 | .amux = EM28XX_AMUX_LINE_IN, | ||
1357 | }, { | ||
1358 | .type = EM28XX_VMUX_SVIDEO, | ||
1359 | .vmux = SAA7115_SVIDEO3, | ||
1360 | .amux = EM28XX_AMUX_LINE_IN, | ||
1361 | } }, | ||
1362 | }, | ||
1363 | [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { | ||
1364 | .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0", | ||
1365 | .has_snapshot_button = 1, | ||
1366 | .tda9887_conf = TDA9887_PRESENT, | ||
1367 | .tuner_type = TUNER_YMEC_TVF_5533MF, | ||
1368 | .decoder = EM28XX_SAA711X, | ||
1369 | .input = { { | ||
1370 | .type = EM28XX_VMUX_TELEVISION, | ||
1371 | .vmux = SAA7115_COMPOSITE2, | ||
1372 | .amux = EM28XX_AMUX_VIDEO, | ||
1373 | .aout = EM28XX_AOUT_MONO | /* I2S */ | ||
1374 | EM28XX_AOUT_MASTER, /* Line out pin */ | ||
1375 | }, { | ||
1376 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1377 | .vmux = SAA7115_COMPOSITE0, | ||
1378 | .amux = EM28XX_AMUX_LINE_IN, | ||
1379 | }, { | ||
1380 | .type = EM28XX_VMUX_SVIDEO, | ||
1381 | .vmux = SAA7115_SVIDEO3, | ||
1382 | .amux = EM28XX_AMUX_LINE_IN, | ||
1383 | } }, | ||
1384 | }, | ||
1385 | [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = { | ||
1386 | .name = "EM2860/SAA711X Reference Design", | ||
1387 | .has_snapshot_button = 1, | ||
1388 | .tuner_type = TUNER_ABSENT, | ||
1389 | .decoder = EM28XX_SAA711X, | ||
1390 | .input = { { | ||
1391 | .type = EM28XX_VMUX_SVIDEO, | ||
1392 | .vmux = SAA7115_SVIDEO3, | ||
1393 | }, { | ||
1394 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1395 | .vmux = SAA7115_COMPOSITE0, | ||
1396 | } }, | ||
1397 | }, | ||
1398 | |||
1399 | [EM2874_BOARD_LEADERSHIP_ISDBT] = { | ||
1400 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1401 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1402 | EM28XX_I2C_FREQ_100_KHZ, | ||
1403 | .xclk = EM28XX_XCLK_FREQUENCY_10MHZ, | ||
1404 | .name = "EM2874 Leadership ISDBT", | ||
1405 | .tuner_type = TUNER_ABSENT, | ||
1406 | .tuner_gpio = leadership_reset, | ||
1407 | .dvb_gpio = leadership_digital, | ||
1408 | .has_dvb = 1, | ||
1409 | }, | ||
1410 | |||
1411 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { | ||
1412 | .name = "MSI DigiVox A/D", | ||
1413 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1414 | .tuner_type = TUNER_XC2028, | ||
1415 | .tuner_gpio = default_tuner_gpio, | ||
1416 | .decoder = EM28XX_TVP5150, | ||
1417 | .input = { { | ||
1418 | .type = EM28XX_VMUX_TELEVISION, | ||
1419 | .vmux = TVP5150_COMPOSITE0, | ||
1420 | .amux = EM28XX_AMUX_VIDEO, | ||
1421 | .gpio = em2880_msi_digivox_ad_analog, | ||
1422 | }, { | ||
1423 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1424 | .vmux = TVP5150_COMPOSITE1, | ||
1425 | .amux = EM28XX_AMUX_LINE_IN, | ||
1426 | .gpio = em2880_msi_digivox_ad_analog, | ||
1427 | }, { | ||
1428 | .type = EM28XX_VMUX_SVIDEO, | ||
1429 | .vmux = TVP5150_SVIDEO, | ||
1430 | .amux = EM28XX_AMUX_LINE_IN, | ||
1431 | .gpio = em2880_msi_digivox_ad_analog, | ||
1432 | } }, | ||
1433 | }, | ||
1434 | [EM2880_BOARD_MSI_DIGIVOX_AD_II] = { | ||
1435 | .name = "MSI DigiVox A/D II", | ||
1436 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1437 | .tuner_type = TUNER_XC2028, | ||
1438 | .tuner_gpio = default_tuner_gpio, | ||
1439 | .decoder = EM28XX_TVP5150, | ||
1440 | .input = { { | ||
1441 | .type = EM28XX_VMUX_TELEVISION, | ||
1442 | .vmux = TVP5150_COMPOSITE0, | ||
1443 | .amux = EM28XX_AMUX_VIDEO, | ||
1444 | .gpio = em2880_msi_digivox_ad_analog, | ||
1445 | }, { | ||
1446 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1447 | .vmux = TVP5150_COMPOSITE1, | ||
1448 | .amux = EM28XX_AMUX_LINE_IN, | ||
1449 | .gpio = em2880_msi_digivox_ad_analog, | ||
1450 | }, { | ||
1451 | .type = EM28XX_VMUX_SVIDEO, | ||
1452 | .vmux = TVP5150_SVIDEO, | ||
1453 | .amux = EM28XX_AMUX_LINE_IN, | ||
1454 | .gpio = em2880_msi_digivox_ad_analog, | ||
1455 | } }, | ||
1456 | }, | ||
1457 | [EM2880_BOARD_KWORLD_DVB_305U] = { | ||
1458 | .name = "KWorld DVB-T 305U", | ||
1459 | .tuner_type = TUNER_XC2028, | ||
1460 | .tuner_gpio = default_tuner_gpio, | ||
1461 | .decoder = EM28XX_TVP5150, | ||
1462 | .input = { { | ||
1463 | .type = EM28XX_VMUX_TELEVISION, | ||
1464 | .vmux = TVP5150_COMPOSITE0, | ||
1465 | .amux = EM28XX_AMUX_VIDEO, | ||
1466 | }, { | ||
1467 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1468 | .vmux = TVP5150_COMPOSITE1, | ||
1469 | .amux = EM28XX_AMUX_LINE_IN, | ||
1470 | }, { | ||
1471 | .type = EM28XX_VMUX_SVIDEO, | ||
1472 | .vmux = TVP5150_SVIDEO, | ||
1473 | .amux = EM28XX_AMUX_LINE_IN, | ||
1474 | } }, | ||
1475 | }, | ||
1476 | [EM2880_BOARD_KWORLD_DVB_310U] = { | ||
1477 | .name = "KWorld DVB-T 310U", | ||
1478 | .tuner_type = TUNER_XC2028, | ||
1479 | .tuner_gpio = default_tuner_gpio, | ||
1480 | .has_dvb = 1, | ||
1481 | .dvb_gpio = default_digital, | ||
1482 | .mts_firmware = 1, | ||
1483 | .decoder = EM28XX_TVP5150, | ||
1484 | .input = { { | ||
1485 | .type = EM28XX_VMUX_TELEVISION, | ||
1486 | .vmux = TVP5150_COMPOSITE0, | ||
1487 | .amux = EM28XX_AMUX_VIDEO, | ||
1488 | .gpio = default_analog, | ||
1489 | }, { | ||
1490 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1491 | .vmux = TVP5150_COMPOSITE1, | ||
1492 | .amux = EM28XX_AMUX_LINE_IN, | ||
1493 | .gpio = default_analog, | ||
1494 | }, { /* S-video has not been tested yet */ | ||
1495 | .type = EM28XX_VMUX_SVIDEO, | ||
1496 | .vmux = TVP5150_SVIDEO, | ||
1497 | .amux = EM28XX_AMUX_LINE_IN, | ||
1498 | .gpio = default_analog, | ||
1499 | } }, | ||
1500 | }, | ||
1501 | [EM2882_BOARD_KWORLD_ATSC_315U] = { | ||
1502 | .name = "KWorld ATSC 315U HDTV TV Box", | ||
1503 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1504 | .tuner_type = TUNER_THOMSON_DTT761X, | ||
1505 | .tuner_gpio = em2882_kworld_315u_tuner_gpio, | ||
1506 | .tda9887_conf = TDA9887_PRESENT, | ||
1507 | .decoder = EM28XX_SAA711X, | ||
1508 | .has_dvb = 1, | ||
1509 | .dvb_gpio = em2882_kworld_315u_digital, | ||
1510 | .ir_codes = RC_MAP_KWORLD_315U, | ||
1511 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1512 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, | ||
1513 | /* Analog mode - still not ready */ | ||
1514 | /*.input = { { | ||
1515 | .type = EM28XX_VMUX_TELEVISION, | ||
1516 | .vmux = SAA7115_COMPOSITE2, | ||
1517 | .amux = EM28XX_AMUX_VIDEO, | ||
1518 | .gpio = em2882_kworld_315u_analog, | ||
1519 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1520 | }, { | ||
1521 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1522 | .vmux = SAA7115_COMPOSITE0, | ||
1523 | .amux = EM28XX_AMUX_LINE_IN, | ||
1524 | .gpio = em2882_kworld_315u_analog1, | ||
1525 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1526 | }, { | ||
1527 | .type = EM28XX_VMUX_SVIDEO, | ||
1528 | .vmux = SAA7115_SVIDEO3, | ||
1529 | .amux = EM28XX_AMUX_LINE_IN, | ||
1530 | .gpio = em2882_kworld_315u_analog1, | ||
1531 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1532 | } }, */ | ||
1533 | }, | ||
1534 | [EM2880_BOARD_EMPIRE_DUAL_TV] = { | ||
1535 | .name = "Empire dual TV", | ||
1536 | .tuner_type = TUNER_XC2028, | ||
1537 | .tuner_gpio = default_tuner_gpio, | ||
1538 | .has_dvb = 1, | ||
1539 | .dvb_gpio = default_digital, | ||
1540 | .mts_firmware = 1, | ||
1541 | .decoder = EM28XX_TVP5150, | ||
1542 | .input = { { | ||
1543 | .type = EM28XX_VMUX_TELEVISION, | ||
1544 | .vmux = TVP5150_COMPOSITE0, | ||
1545 | .amux = EM28XX_AMUX_VIDEO, | ||
1546 | .gpio = default_analog, | ||
1547 | }, { | ||
1548 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1549 | .vmux = TVP5150_COMPOSITE1, | ||
1550 | .amux = EM28XX_AMUX_LINE_IN, | ||
1551 | .gpio = default_analog, | ||
1552 | }, { | ||
1553 | .type = EM28XX_VMUX_SVIDEO, | ||
1554 | .vmux = TVP5150_SVIDEO, | ||
1555 | .amux = EM28XX_AMUX_LINE_IN, | ||
1556 | .gpio = default_analog, | ||
1557 | } }, | ||
1558 | }, | ||
1559 | [EM2881_BOARD_DNT_DA2_HYBRID] = { | ||
1560 | .name = "DNT DA2 Hybrid", | ||
1561 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1562 | .tuner_type = TUNER_XC2028, | ||
1563 | .tuner_gpio = default_tuner_gpio, | ||
1564 | .decoder = EM28XX_TVP5150, | ||
1565 | .input = { { | ||
1566 | .type = EM28XX_VMUX_TELEVISION, | ||
1567 | .vmux = TVP5150_COMPOSITE0, | ||
1568 | .amux = EM28XX_AMUX_VIDEO, | ||
1569 | .gpio = default_analog, | ||
1570 | }, { | ||
1571 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1572 | .vmux = TVP5150_COMPOSITE1, | ||
1573 | .amux = EM28XX_AMUX_LINE_IN, | ||
1574 | .gpio = default_analog, | ||
1575 | }, { | ||
1576 | .type = EM28XX_VMUX_SVIDEO, | ||
1577 | .vmux = TVP5150_SVIDEO, | ||
1578 | .amux = EM28XX_AMUX_LINE_IN, | ||
1579 | .gpio = default_analog, | ||
1580 | } }, | ||
1581 | }, | ||
1582 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { | ||
1583 | .name = "Pinnacle Hybrid Pro", | ||
1584 | .tuner_type = TUNER_XC2028, | ||
1585 | .tuner_gpio = default_tuner_gpio, | ||
1586 | .decoder = EM28XX_TVP5150, | ||
1587 | .has_dvb = 1, | ||
1588 | .dvb_gpio = pinnacle_hybrid_pro_digital, | ||
1589 | .input = { { | ||
1590 | .type = EM28XX_VMUX_TELEVISION, | ||
1591 | .vmux = TVP5150_COMPOSITE0, | ||
1592 | .amux = EM28XX_AMUX_VIDEO, | ||
1593 | .gpio = pinnacle_hybrid_pro_analog, | ||
1594 | }, { | ||
1595 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1596 | .vmux = TVP5150_COMPOSITE1, | ||
1597 | .amux = EM28XX_AMUX_LINE_IN, | ||
1598 | .gpio = pinnacle_hybrid_pro_analog, | ||
1599 | }, { | ||
1600 | .type = EM28XX_VMUX_SVIDEO, | ||
1601 | .vmux = TVP5150_SVIDEO, | ||
1602 | .amux = EM28XX_AMUX_LINE_IN, | ||
1603 | .gpio = pinnacle_hybrid_pro_analog, | ||
1604 | } }, | ||
1605 | }, | ||
1606 | [EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = { | ||
1607 | .name = "Pinnacle Hybrid Pro (330e)", | ||
1608 | .tuner_type = TUNER_XC2028, | ||
1609 | .tuner_gpio = default_tuner_gpio, | ||
1610 | .mts_firmware = 1, | ||
1611 | .has_dvb = 1, | ||
1612 | .dvb_gpio = hauppauge_wintv_hvr_900R2_digital, | ||
1613 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1614 | .decoder = EM28XX_TVP5150, | ||
1615 | .input = { { | ||
1616 | .type = EM28XX_VMUX_TELEVISION, | ||
1617 | .vmux = TVP5150_COMPOSITE0, | ||
1618 | .amux = EM28XX_AMUX_VIDEO, | ||
1619 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1620 | }, { | ||
1621 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1622 | .vmux = TVP5150_COMPOSITE1, | ||
1623 | .amux = EM28XX_AMUX_LINE_IN, | ||
1624 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1625 | }, { | ||
1626 | .type = EM28XX_VMUX_SVIDEO, | ||
1627 | .vmux = TVP5150_SVIDEO, | ||
1628 | .amux = EM28XX_AMUX_LINE_IN, | ||
1629 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1630 | } }, | ||
1631 | }, | ||
1632 | [EM2882_BOARD_KWORLD_VS_DVBT] = { | ||
1633 | .name = "Kworld VS-DVB-T 323UR", | ||
1634 | .tuner_type = TUNER_XC2028, | ||
1635 | .tuner_gpio = default_tuner_gpio, | ||
1636 | .decoder = EM28XX_TVP5150, | ||
1637 | .mts_firmware = 1, | ||
1638 | .has_dvb = 1, | ||
1639 | .dvb_gpio = kworld_330u_digital, | ||
1640 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ | ||
1641 | .ir_codes = RC_MAP_KWORLD_315U, | ||
1642 | .input = { { | ||
1643 | .type = EM28XX_VMUX_TELEVISION, | ||
1644 | .vmux = TVP5150_COMPOSITE0, | ||
1645 | .amux = EM28XX_AMUX_VIDEO, | ||
1646 | }, { | ||
1647 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1648 | .vmux = TVP5150_COMPOSITE1, | ||
1649 | .amux = EM28XX_AMUX_LINE_IN, | ||
1650 | }, { | ||
1651 | .type = EM28XX_VMUX_SVIDEO, | ||
1652 | .vmux = TVP5150_SVIDEO, | ||
1653 | .amux = EM28XX_AMUX_LINE_IN, | ||
1654 | } }, | ||
1655 | }, | ||
1656 | [EM2882_BOARD_TERRATEC_HYBRID_XS] = { | ||
1657 | .name = "Terratec Cinnergy Hybrid T USB XS (em2882)", | ||
1658 | .tuner_type = TUNER_XC2028, | ||
1659 | .tuner_gpio = default_tuner_gpio, | ||
1660 | .mts_firmware = 1, | ||
1661 | .decoder = EM28XX_TVP5150, | ||
1662 | .has_dvb = 1, | ||
1663 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1664 | .ir_codes = RC_MAP_TERRATEC_CINERGY_XS, | ||
1665 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1666 | .input = { { | ||
1667 | .type = EM28XX_VMUX_TELEVISION, | ||
1668 | .vmux = TVP5150_COMPOSITE0, | ||
1669 | .amux = EM28XX_AMUX_VIDEO, | ||
1670 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1671 | }, { | ||
1672 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1673 | .vmux = TVP5150_COMPOSITE1, | ||
1674 | .amux = EM28XX_AMUX_LINE_IN, | ||
1675 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1676 | }, { | ||
1677 | .type = EM28XX_VMUX_SVIDEO, | ||
1678 | .vmux = TVP5150_SVIDEO, | ||
1679 | .amux = EM28XX_AMUX_LINE_IN, | ||
1680 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1681 | } }, | ||
1682 | }, | ||
1683 | [EM2882_BOARD_DIKOM_DK300] = { | ||
1684 | .name = "Dikom DK300", | ||
1685 | .tuner_type = TUNER_XC2028, | ||
1686 | .tuner_gpio = default_tuner_gpio, | ||
1687 | .decoder = EM28XX_TVP5150, | ||
1688 | .mts_firmware = 1, | ||
1689 | .has_dvb = 1, | ||
1690 | .dvb_gpio = dikom_dk300_digital, | ||
1691 | .input = { { | ||
1692 | .type = EM28XX_VMUX_TELEVISION, | ||
1693 | .vmux = TVP5150_COMPOSITE0, | ||
1694 | .amux = EM28XX_AMUX_VIDEO, | ||
1695 | .gpio = default_analog, | ||
1696 | } }, | ||
1697 | }, | ||
1698 | [EM2883_BOARD_KWORLD_HYBRID_330U] = { | ||
1699 | .name = "Kworld PlusTV HD Hybrid 330", | ||
1700 | .tuner_type = TUNER_XC2028, | ||
1701 | .tuner_gpio = default_tuner_gpio, | ||
1702 | .decoder = EM28XX_TVP5150, | ||
1703 | .mts_firmware = 1, | ||
1704 | .has_dvb = 1, | ||
1705 | .dvb_gpio = kworld_330u_digital, | ||
1706 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1707 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1708 | EM28XX_I2C_EEPROM_ON_BOARD | | ||
1709 | EM28XX_I2C_EEPROM_KEY_VALID, | ||
1710 | .input = { { | ||
1711 | .type = EM28XX_VMUX_TELEVISION, | ||
1712 | .vmux = TVP5150_COMPOSITE0, | ||
1713 | .amux = EM28XX_AMUX_VIDEO, | ||
1714 | .gpio = kworld_330u_analog, | ||
1715 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1716 | }, { | ||
1717 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1718 | .vmux = TVP5150_COMPOSITE1, | ||
1719 | .amux = EM28XX_AMUX_LINE_IN, | ||
1720 | .gpio = kworld_330u_analog, | ||
1721 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1722 | }, { | ||
1723 | .type = EM28XX_VMUX_SVIDEO, | ||
1724 | .vmux = TVP5150_SVIDEO, | ||
1725 | .amux = EM28XX_AMUX_LINE_IN, | ||
1726 | .gpio = kworld_330u_analog, | ||
1727 | } }, | ||
1728 | }, | ||
1729 | [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { | ||
1730 | .name = "Compro VideoMate ForYou/Stereo", | ||
1731 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1732 | .tvaudio_addr = 0xb0, | ||
1733 | .tda9887_conf = TDA9887_PRESENT, | ||
1734 | .decoder = EM28XX_TVP5150, | ||
1735 | .adecoder = EM28XX_TVAUDIO, | ||
1736 | .mute_gpio = compro_mute_gpio, | ||
1737 | .input = { { | ||
1738 | .type = EM28XX_VMUX_TELEVISION, | ||
1739 | .vmux = TVP5150_COMPOSITE0, | ||
1740 | .amux = EM28XX_AMUX_VIDEO, | ||
1741 | .gpio = compro_unmute_tv_gpio, | ||
1742 | }, { | ||
1743 | .type = EM28XX_VMUX_SVIDEO, | ||
1744 | .vmux = TVP5150_SVIDEO, | ||
1745 | .amux = EM28XX_AMUX_LINE_IN, | ||
1746 | .gpio = compro_unmute_svid_gpio, | ||
1747 | } }, | ||
1748 | }, | ||
1749 | [EM2860_BOARD_KAIOMY_TVNPC_U2] = { | ||
1750 | .name = "Kaiomy TVnPC U2", | ||
1751 | .vchannels = 3, | ||
1752 | .tuner_type = TUNER_XC2028, | ||
1753 | .tuner_addr = 0x61, | ||
1754 | .mts_firmware = 1, | ||
1755 | .decoder = EM28XX_TVP5150, | ||
1756 | .tuner_gpio = default_tuner_gpio, | ||
1757 | .ir_codes = RC_MAP_KAIOMY, | ||
1758 | .input = { { | ||
1759 | .type = EM28XX_VMUX_TELEVISION, | ||
1760 | .vmux = TVP5150_COMPOSITE0, | ||
1761 | .amux = EM28XX_AMUX_VIDEO, | ||
1762 | |||
1763 | }, { | ||
1764 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1765 | .vmux = TVP5150_COMPOSITE1, | ||
1766 | .amux = EM28XX_AMUX_LINE_IN, | ||
1767 | }, { | ||
1768 | .type = EM28XX_VMUX_SVIDEO, | ||
1769 | .vmux = TVP5150_SVIDEO, | ||
1770 | .amux = EM28XX_AMUX_LINE_IN, | ||
1771 | } }, | ||
1772 | .radio = { | ||
1773 | .type = EM28XX_RADIO, | ||
1774 | .amux = EM28XX_AMUX_LINE_IN, | ||
1775 | } | ||
1776 | }, | ||
1777 | [EM2860_BOARD_EASYCAP] = { | ||
1778 | .name = "Easy Cap Capture DC-60", | ||
1779 | .vchannels = 2, | ||
1780 | .tuner_type = TUNER_ABSENT, | ||
1781 | .decoder = EM28XX_SAA711X, | ||
1782 | .input = { { | ||
1783 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1784 | .vmux = SAA7115_COMPOSITE0, | ||
1785 | .amux = EM28XX_AMUX_LINE_IN, | ||
1786 | }, { | ||
1787 | .type = EM28XX_VMUX_SVIDEO, | ||
1788 | .vmux = SAA7115_SVIDEO3, | ||
1789 | .amux = EM28XX_AMUX_LINE_IN, | ||
1790 | } }, | ||
1791 | }, | ||
1792 | [EM2820_BOARD_IODATA_GVMVP_SZ] = { | ||
1793 | .name = "IO-DATA GV-MVP/SZ", | ||
1794 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
1795 | .tuner_gpio = default_tuner_gpio, | ||
1796 | .tda9887_conf = TDA9887_PRESENT, | ||
1797 | .decoder = EM28XX_TVP5150, | ||
1798 | .input = { { | ||
1799 | .type = EM28XX_VMUX_TELEVISION, | ||
1800 | .vmux = TVP5150_COMPOSITE0, | ||
1801 | .amux = EM28XX_AMUX_VIDEO, | ||
1802 | }, { /* Composite has not been tested yet */ | ||
1803 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1804 | .vmux = TVP5150_COMPOSITE1, | ||
1805 | .amux = EM28XX_AMUX_VIDEO, | ||
1806 | }, { /* S-video has not been tested yet */ | ||
1807 | .type = EM28XX_VMUX_SVIDEO, | ||
1808 | .vmux = TVP5150_SVIDEO, | ||
1809 | .amux = EM28XX_AMUX_VIDEO, | ||
1810 | } }, | ||
1811 | }, | ||
1812 | [EM2860_BOARD_TERRATEC_GRABBY] = { | ||
1813 | .name = "Terratec Grabby", | ||
1814 | .vchannels = 2, | ||
1815 | .tuner_type = TUNER_ABSENT, | ||
1816 | .decoder = EM28XX_SAA711X, | ||
1817 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1818 | .input = { { | ||
1819 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1820 | .vmux = SAA7115_COMPOSITE0, | ||
1821 | .amux = EM28XX_AMUX_LINE_IN, | ||
1822 | }, { | ||
1823 | .type = EM28XX_VMUX_SVIDEO, | ||
1824 | .vmux = SAA7115_SVIDEO3, | ||
1825 | .amux = EM28XX_AMUX_LINE_IN, | ||
1826 | } }, | ||
1827 | }, | ||
1828 | [EM2860_BOARD_TERRATEC_AV350] = { | ||
1829 | .name = "Terratec AV350", | ||
1830 | .vchannels = 2, | ||
1831 | .tuner_type = TUNER_ABSENT, | ||
1832 | .decoder = EM28XX_TVP5150, | ||
1833 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1834 | .mute_gpio = terratec_av350_mute_gpio, | ||
1835 | .input = { { | ||
1836 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1837 | .vmux = TVP5150_COMPOSITE1, | ||
1838 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1839 | .gpio = terratec_av350_unmute_gpio, | ||
1840 | |||
1841 | }, { | ||
1842 | .type = EM28XX_VMUX_SVIDEO, | ||
1843 | .vmux = TVP5150_SVIDEO, | ||
1844 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1845 | .gpio = terratec_av350_unmute_gpio, | ||
1846 | } }, | ||
1847 | }, | ||
1848 | |||
1849 | [EM2860_BOARD_ELGATO_VIDEO_CAPTURE] = { | ||
1850 | .name = "Elgato Video Capture", | ||
1851 | .decoder = EM28XX_SAA711X, | ||
1852 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
1853 | .input = { { | ||
1854 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1855 | .vmux = SAA7115_COMPOSITE0, | ||
1856 | .amux = EM28XX_AMUX_LINE_IN, | ||
1857 | }, { | ||
1858 | .type = EM28XX_VMUX_SVIDEO, | ||
1859 | .vmux = SAA7115_SVIDEO3, | ||
1860 | .amux = EM28XX_AMUX_LINE_IN, | ||
1861 | } }, | ||
1862 | }, | ||
1863 | |||
1864 | [EM2882_BOARD_EVGA_INDTUBE] = { | ||
1865 | .name = "Evga inDtube", | ||
1866 | .tuner_type = TUNER_XC2028, | ||
1867 | .tuner_gpio = default_tuner_gpio, | ||
1868 | .decoder = EM28XX_TVP5150, | ||
1869 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ | ||
1870 | .mts_firmware = 1, | ||
1871 | .has_dvb = 1, | ||
1872 | .dvb_gpio = evga_indtube_digital, | ||
1873 | .ir_codes = RC_MAP_EVGA_INDTUBE, | ||
1874 | .input = { { | ||
1875 | .type = EM28XX_VMUX_TELEVISION, | ||
1876 | .vmux = TVP5150_COMPOSITE0, | ||
1877 | .amux = EM28XX_AMUX_VIDEO, | ||
1878 | .gpio = evga_indtube_analog, | ||
1879 | }, { | ||
1880 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1881 | .vmux = TVP5150_COMPOSITE1, | ||
1882 | .amux = EM28XX_AMUX_LINE_IN, | ||
1883 | .gpio = evga_indtube_analog, | ||
1884 | }, { | ||
1885 | .type = EM28XX_VMUX_SVIDEO, | ||
1886 | .vmux = TVP5150_SVIDEO, | ||
1887 | .amux = EM28XX_AMUX_LINE_IN, | ||
1888 | .gpio = evga_indtube_analog, | ||
1889 | } }, | ||
1890 | }, | ||
1891 | /* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 + | ||
1892 | Infineon TUA6034) */ | ||
1893 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { | ||
1894 | .name = "Reddo DVB-C USB TV Box", | ||
1895 | .tuner_type = TUNER_ABSENT, | ||
1896 | .tuner_gpio = reddo_dvb_c_usb_box, | ||
1897 | .has_dvb = 1, | ||
1898 | }, | ||
1899 | /* 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold | ||
1900 | * initially as the KWorld PlusTV 340U, then as the UB435-Q. | ||
1901 | * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 */ | ||
1902 | [EM2870_BOARD_KWORLD_A340] = { | ||
1903 | .name = "KWorld PlusTV 340U or UB435-Q (ATSC)", | ||
1904 | .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */ | ||
1905 | .has_dvb = 1, | ||
1906 | .dvb_gpio = kworld_a340_digital, | ||
1907 | .tuner_gpio = default_tuner_gpio, | ||
1908 | }, | ||
1909 | /* 2013:024f PCTV nanoStick T2 290e. | ||
1910 | * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */ | ||
1911 | [EM28174_BOARD_PCTV_290E] = { | ||
1912 | .name = "PCTV nanoStick T2 290e", | ||
1913 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1914 | EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ, | ||
1915 | .tuner_type = TUNER_ABSENT, | ||
1916 | .tuner_gpio = pctv_290e, | ||
1917 | .has_dvb = 1, | ||
1918 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1919 | }, | ||
1920 | /* 2013:024f PCTV DVB-S2 Stick 460e | ||
1921 | * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 */ | ||
1922 | [EM28174_BOARD_PCTV_460E] = { | ||
1923 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1924 | EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, | ||
1925 | .name = "PCTV DVB-S2 Stick (460e)", | ||
1926 | .tuner_type = TUNER_ABSENT, | ||
1927 | .tuner_gpio = pctv_460e, | ||
1928 | .has_dvb = 1, | ||
1929 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1930 | }, | ||
1931 | /* eb1a:5006 Honestech VIDBOX NW03 | ||
1932 | * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner */ | ||
1933 | [EM2860_BOARD_HT_VIDBOX_NW03] = { | ||
1934 | .name = "Honestech Vidbox NW03", | ||
1935 | .tuner_type = TUNER_ABSENT, | ||
1936 | .decoder = EM28XX_SAA711X, | ||
1937 | .input = { { | ||
1938 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1939 | .vmux = SAA7115_COMPOSITE0, | ||
1940 | .amux = EM28XX_AMUX_LINE_IN, | ||
1941 | }, { | ||
1942 | .type = EM28XX_VMUX_SVIDEO, | ||
1943 | .vmux = SAA7115_SVIDEO3, /* S-VIDEO needs confirming */ | ||
1944 | .amux = EM28XX_AMUX_LINE_IN, | ||
1945 | } }, | ||
1946 | }, | ||
1947 | /* 1b80:e425 MaxMedia UB425-TC | ||
1948 | * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 */ | ||
1949 | [EM2874_BOARD_MAXMEDIA_UB425_TC] = { | ||
1950 | .name = "MaxMedia UB425-TC", | ||
1951 | .tuner_type = TUNER_ABSENT, | ||
1952 | .tuner_gpio = maxmedia_ub425_tc, | ||
1953 | .has_dvb = 1, | ||
1954 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1955 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1956 | EM28XX_I2C_FREQ_400_KHZ, | ||
1957 | }, | ||
1958 | /* 2304:0242 PCTV QuatroStick (510e) | ||
1959 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ | ||
1960 | [EM2884_BOARD_PCTV_510E] = { | ||
1961 | .name = "PCTV QuatroStick (510e)", | ||
1962 | .tuner_type = TUNER_ABSENT, | ||
1963 | .tuner_gpio = pctv_510e, | ||
1964 | .has_dvb = 1, | ||
1965 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1966 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1967 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1968 | EM28XX_I2C_FREQ_400_KHZ, | ||
1969 | }, | ||
1970 | /* 2013:0251 PCTV QuatroStick nano (520e) | ||
1971 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ | ||
1972 | [EM2884_BOARD_PCTV_520E] = { | ||
1973 | .name = "PCTV QuatroStick nano (520e)", | ||
1974 | .tuner_type = TUNER_ABSENT, | ||
1975 | .tuner_gpio = pctv_520e, | ||
1976 | .has_dvb = 1, | ||
1977 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1978 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1979 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1980 | EM28XX_I2C_FREQ_400_KHZ, | ||
1981 | }, | ||
1982 | }; | ||
1983 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | ||
1984 | |||
1985 | /* table of devices that work with this driver */ | ||
1986 | struct usb_device_id em28xx_id_table[] = { | ||
1987 | { USB_DEVICE(0xeb1a, 0x2750), | ||
1988 | .driver_info = EM2750_BOARD_UNKNOWN }, | ||
1989 | { USB_DEVICE(0xeb1a, 0x2751), | ||
1990 | .driver_info = EM2750_BOARD_UNKNOWN }, | ||
1991 | { USB_DEVICE(0xeb1a, 0x2800), | ||
1992 | .driver_info = EM2800_BOARD_UNKNOWN }, | ||
1993 | { USB_DEVICE(0xeb1a, 0x2710), | ||
1994 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
1995 | { USB_DEVICE(0xeb1a, 0x2820), | ||
1996 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
1997 | { USB_DEVICE(0xeb1a, 0x2821), | ||
1998 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
1999 | { USB_DEVICE(0xeb1a, 0x2860), | ||
2000 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2001 | { USB_DEVICE(0xeb1a, 0x2861), | ||
2002 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2003 | { USB_DEVICE(0xeb1a, 0x2862), | ||
2004 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2005 | { USB_DEVICE(0xeb1a, 0x2863), | ||
2006 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2007 | { USB_DEVICE(0xeb1a, 0x2870), | ||
2008 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2009 | { USB_DEVICE(0xeb1a, 0x2881), | ||
2010 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2011 | { USB_DEVICE(0xeb1a, 0x2883), | ||
2012 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2013 | { USB_DEVICE(0xeb1a, 0x2868), | ||
2014 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2015 | { USB_DEVICE(0xeb1a, 0x2875), | ||
2016 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2017 | { USB_DEVICE(0xeb1a, 0xe300), | ||
2018 | .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, | ||
2019 | { USB_DEVICE(0xeb1a, 0xe303), | ||
2020 | .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 }, | ||
2021 | { USB_DEVICE(0xeb1a, 0xe305), | ||
2022 | .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, | ||
2023 | { USB_DEVICE(0xeb1a, 0xe310), | ||
2024 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, | ||
2025 | { USB_DEVICE(0xeb1a, 0xa313), | ||
2026 | .driver_info = EM2882_BOARD_KWORLD_ATSC_315U }, | ||
2027 | { USB_DEVICE(0xeb1a, 0xa316), | ||
2028 | .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, | ||
2029 | { USB_DEVICE(0xeb1a, 0xe320), | ||
2030 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II }, | ||
2031 | { USB_DEVICE(0xeb1a, 0xe323), | ||
2032 | .driver_info = EM2882_BOARD_KWORLD_VS_DVBT }, | ||
2033 | { USB_DEVICE(0xeb1a, 0xe350), | ||
2034 | .driver_info = EM2870_BOARD_KWORLD_350U }, | ||
2035 | { USB_DEVICE(0xeb1a, 0xe355), | ||
2036 | .driver_info = EM2870_BOARD_KWORLD_355U }, | ||
2037 | { USB_DEVICE(0xeb1a, 0x2801), | ||
2038 | .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, | ||
2039 | { USB_DEVICE(0xeb1a, 0xe357), | ||
2040 | .driver_info = EM2870_BOARD_KWORLD_355U }, | ||
2041 | { USB_DEVICE(0xeb1a, 0xe359), | ||
2042 | .driver_info = EM2870_BOARD_KWORLD_355U }, | ||
2043 | { USB_DEVICE(0x1b80, 0xe302), | ||
2044 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */ | ||
2045 | { USB_DEVICE(0x1b80, 0xe304), | ||
2046 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kworld DVD Maker 2 */ | ||
2047 | { USB_DEVICE(0x0ccd, 0x0036), | ||
2048 | .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, | ||
2049 | { USB_DEVICE(0x0ccd, 0x004c), | ||
2050 | .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR }, | ||
2051 | { USB_DEVICE(0x0ccd, 0x004f), | ||
2052 | .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS }, | ||
2053 | { USB_DEVICE(0x0ccd, 0x005e), | ||
2054 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, | ||
2055 | { USB_DEVICE(0x0ccd, 0x0042), | ||
2056 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, | ||
2057 | { USB_DEVICE(0x0ccd, 0x0043), | ||
2058 | .driver_info = EM2870_BOARD_TERRATEC_XS }, | ||
2059 | { USB_DEVICE(0x0ccd, 0x008e), /* Cinergy HTC USB XS Rev. 1 */ | ||
2060 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2061 | { USB_DEVICE(0x0ccd, 0x00ac), /* Cinergy HTC USB XS Rev. 2 */ | ||
2062 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2063 | { USB_DEVICE(0x0ccd, 0x10a2), /* H5 Rev. 1 */ | ||
2064 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2065 | { USB_DEVICE(0x0ccd, 0x10ad), /* H5 Rev. 2 */ | ||
2066 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2067 | { USB_DEVICE(0x0ccd, 0x0084), | ||
2068 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, | ||
2069 | { USB_DEVICE(0x0ccd, 0x0096), | ||
2070 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | ||
2071 | { USB_DEVICE(0x0ccd, 0x10AF), | ||
2072 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | ||
2073 | { USB_DEVICE(0x0ccd, 0x00b2), | ||
2074 | .driver_info = EM2884_BOARD_CINERGY_HTC_STICK }, | ||
2075 | { USB_DEVICE(0x0fd9, 0x0033), | ||
2076 | .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, | ||
2077 | { USB_DEVICE(0x185b, 0x2870), | ||
2078 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, | ||
2079 | { USB_DEVICE(0x185b, 0x2041), | ||
2080 | .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU }, | ||
2081 | { USB_DEVICE(0x2040, 0x4200), | ||
2082 | .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, | ||
2083 | { USB_DEVICE(0x2040, 0x4201), | ||
2084 | .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, | ||
2085 | { USB_DEVICE(0x2040, 0x6500), | ||
2086 | .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, | ||
2087 | { USB_DEVICE(0x2040, 0x6502), | ||
2088 | .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 }, | ||
2089 | { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */ | ||
2090 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | ||
2091 | { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */ | ||
2092 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | ||
2093 | { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ | ||
2094 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | ||
2095 | { USB_DEVICE(0x2040, 0x651f), | ||
2096 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, | ||
2097 | { USB_DEVICE(0x0438, 0xb002), | ||
2098 | .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, | ||
2099 | { USB_DEVICE(0x2001, 0xf112), | ||
2100 | .driver_info = EM2820_BOARD_DLINK_USB_TV }, | ||
2101 | { USB_DEVICE(0x2304, 0x0207), | ||
2102 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, | ||
2103 | { USB_DEVICE(0x2304, 0x0208), | ||
2104 | .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, | ||
2105 | { USB_DEVICE(0x2304, 0x021a), | ||
2106 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, | ||
2107 | { USB_DEVICE(0x2304, 0x0226), | ||
2108 | .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E }, | ||
2109 | { USB_DEVICE(0x2304, 0x0227), | ||
2110 | .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, | ||
2111 | { USB_DEVICE(0x0413, 0x6023), | ||
2112 | .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII }, | ||
2113 | { USB_DEVICE(0x093b, 0xa003), | ||
2114 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, | ||
2115 | { USB_DEVICE(0x093b, 0xa005), | ||
2116 | .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U }, | ||
2117 | { USB_DEVICE(0x04bb, 0x0515), | ||
2118 | .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ }, | ||
2119 | { USB_DEVICE(0xeb1a, 0x50a6), | ||
2120 | .driver_info = EM2860_BOARD_GADMEI_UTV330 }, | ||
2121 | { USB_DEVICE(0x1b80, 0xa340), | ||
2122 | .driver_info = EM2870_BOARD_KWORLD_A340 }, | ||
2123 | { USB_DEVICE(0x2013, 0x024f), | ||
2124 | .driver_info = EM28174_BOARD_PCTV_290E }, | ||
2125 | { USB_DEVICE(0x2013, 0x024c), | ||
2126 | .driver_info = EM28174_BOARD_PCTV_460E }, | ||
2127 | { USB_DEVICE(0x2040, 0x1605), | ||
2128 | .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, | ||
2129 | { USB_DEVICE(0xeb1a, 0x5006), | ||
2130 | .driver_info = EM2860_BOARD_HT_VIDBOX_NW03 }, | ||
2131 | { USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */ | ||
2132 | .driver_info = EM2860_BOARD_EASYCAP }, | ||
2133 | { USB_DEVICE(0x1b80, 0xe425), | ||
2134 | .driver_info = EM2874_BOARD_MAXMEDIA_UB425_TC }, | ||
2135 | { USB_DEVICE(0x2304, 0x0242), | ||
2136 | .driver_info = EM2884_BOARD_PCTV_510E }, | ||
2137 | { USB_DEVICE(0x2013, 0x0251), | ||
2138 | .driver_info = EM2884_BOARD_PCTV_520E }, | ||
2139 | { }, | ||
2140 | }; | ||
2141 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | ||
2142 | |||
2143 | /* | ||
2144 | * EEPROM hash table for devices with generic USB IDs | ||
2145 | */ | ||
2146 | static struct em28xx_hash_table em28xx_eeprom_hash[] = { | ||
2147 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ | ||
2148 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | ||
2149 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, | ||
2150 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | ||
2151 | {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, | ||
2152 | {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, | ||
2153 | {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, | ||
2154 | {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT}, | ||
2155 | {0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028}, | ||
2156 | }; | ||
2157 | |||
2158 | /* I2C devicelist hash table for devices with generic USB IDs */ | ||
2159 | static struct em28xx_hash_table em28xx_i2c_hash[] = { | ||
2160 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, | ||
2161 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, | ||
2162 | {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, | ||
2163 | {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT}, | ||
2164 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, | ||
2165 | {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, | ||
2166 | {0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT}, | ||
2167 | }; | ||
2168 | |||
2169 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ | ||
2170 | static unsigned short saa711x_addrs[] = { | ||
2171 | 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */ | ||
2172 | 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ | ||
2173 | I2C_CLIENT_END }; | ||
2174 | |||
2175 | static unsigned short tvp5150_addrs[] = { | ||
2176 | 0xb8 >> 1, | ||
2177 | 0xba >> 1, | ||
2178 | I2C_CLIENT_END | ||
2179 | }; | ||
2180 | |||
2181 | static unsigned short msp3400_addrs[] = { | ||
2182 | 0x80 >> 1, | ||
2183 | 0x88 >> 1, | ||
2184 | I2C_CLIENT_END | ||
2185 | }; | ||
2186 | |||
2187 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg) | ||
2188 | { | ||
2189 | int rc = 0; | ||
2190 | struct em28xx *dev = ptr; | ||
2191 | |||
2192 | if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000) | ||
2193 | return 0; | ||
2194 | |||
2195 | if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET) | ||
2196 | return 0; | ||
2197 | |||
2198 | rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2199 | |||
2200 | return rc; | ||
2201 | } | ||
2202 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); | ||
2203 | |||
2204 | static inline void em28xx_set_model(struct em28xx *dev) | ||
2205 | { | ||
2206 | memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board)); | ||
2207 | |||
2208 | /* Those are the default values for the majority of boards | ||
2209 | Use those values if not specified otherwise at boards entry | ||
2210 | */ | ||
2211 | if (!dev->board.xclk) | ||
2212 | dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE | | ||
2213 | EM28XX_XCLK_FREQUENCY_12MHZ; | ||
2214 | |||
2215 | if (!dev->board.i2c_speed) | ||
2216 | dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | ||
2217 | EM28XX_I2C_FREQ_100_KHZ; | ||
2218 | } | ||
2219 | |||
2220 | |||
2221 | /* FIXME: Should be replaced by a proper mt9m111 driver */ | ||
2222 | static int em28xx_initialize_mt9m111(struct em28xx *dev) | ||
2223 | { | ||
2224 | int i; | ||
2225 | unsigned char regs[][3] = { | ||
2226 | { 0x0d, 0x00, 0x01, }, /* reset and use defaults */ | ||
2227 | { 0x0d, 0x00, 0x00, }, | ||
2228 | { 0x0a, 0x00, 0x21, }, | ||
2229 | { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */ | ||
2230 | }; | ||
2231 | |||
2232 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
2233 | i2c_master_send(&dev->i2c_client, ®s[i][0], 3); | ||
2234 | |||
2235 | return 0; | ||
2236 | } | ||
2237 | |||
2238 | |||
2239 | /* FIXME: Should be replaced by a proper mt9m001 driver */ | ||
2240 | static int em28xx_initialize_mt9m001(struct em28xx *dev) | ||
2241 | { | ||
2242 | int i; | ||
2243 | unsigned char regs[][3] = { | ||
2244 | { 0x0d, 0x00, 0x01, }, | ||
2245 | { 0x0d, 0x00, 0x00, }, | ||
2246 | { 0x04, 0x05, 0x00, }, /* hres = 1280 */ | ||
2247 | { 0x03, 0x04, 0x00, }, /* vres = 1024 */ | ||
2248 | { 0x20, 0x11, 0x00, }, | ||
2249 | { 0x06, 0x00, 0x10, }, | ||
2250 | { 0x2b, 0x00, 0x24, }, | ||
2251 | { 0x2e, 0x00, 0x24, }, | ||
2252 | { 0x35, 0x00, 0x24, }, | ||
2253 | { 0x2d, 0x00, 0x20, }, | ||
2254 | { 0x2c, 0x00, 0x20, }, | ||
2255 | { 0x09, 0x0a, 0xd4, }, | ||
2256 | { 0x35, 0x00, 0x57, }, | ||
2257 | }; | ||
2258 | |||
2259 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
2260 | i2c_master_send(&dev->i2c_client, ®s[i][0], 3); | ||
2261 | |||
2262 | return 0; | ||
2263 | } | ||
2264 | |||
2265 | /* HINT method: webcam I2C chips | ||
2266 | * | ||
2267 | * This method works for webcams with Micron sensors | ||
2268 | */ | ||
2269 | static int em28xx_hint_sensor(struct em28xx *dev) | ||
2270 | { | ||
2271 | int rc; | ||
2272 | char *sensor_name; | ||
2273 | unsigned char cmd; | ||
2274 | __be16 version_be; | ||
2275 | u16 version; | ||
2276 | |||
2277 | /* Micron sensor detection */ | ||
2278 | dev->i2c_client.addr = 0xba >> 1; | ||
2279 | cmd = 0; | ||
2280 | i2c_master_send(&dev->i2c_client, &cmd, 1); | ||
2281 | rc = i2c_master_recv(&dev->i2c_client, (char *)&version_be, 2); | ||
2282 | if (rc != 2) | ||
2283 | return -EINVAL; | ||
2284 | |||
2285 | version = be16_to_cpu(version_be); | ||
2286 | switch (version) { | ||
2287 | case 0x8232: /* mt9v011 640x480 1.3 Mpix sensor */ | ||
2288 | case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */ | ||
2289 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | ||
2290 | em28xx_set_model(dev); | ||
2291 | |||
2292 | sensor_name = "mt9v011"; | ||
2293 | dev->em28xx_sensor = EM28XX_MT9V011; | ||
2294 | dev->sensor_xres = 640; | ||
2295 | dev->sensor_yres = 480; | ||
2296 | /* | ||
2297 | * FIXME: mt9v011 uses I2S speed as xtal clk - at least with | ||
2298 | * the Silvercrest cam I have here for testing - for higher | ||
2299 | * resolutions, a high clock cause horizontal artifacts, so we | ||
2300 | * need to use a lower xclk frequency. | ||
2301 | * Yet, it would be possible to adjust xclk depending on the | ||
2302 | * desired resolution, since this affects directly the | ||
2303 | * frame rate. | ||
2304 | */ | ||
2305 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; | ||
2306 | dev->sensor_xtal = 4300000; | ||
2307 | |||
2308 | /* probably means GRGB 16 bit bayer */ | ||
2309 | dev->vinmode = 0x0d; | ||
2310 | dev->vinctl = 0x00; | ||
2311 | |||
2312 | break; | ||
2313 | |||
2314 | case 0x143a: /* MT9M111 as found in the ECS G200 */ | ||
2315 | dev->model = EM2750_BOARD_UNKNOWN; | ||
2316 | em28xx_set_model(dev); | ||
2317 | |||
2318 | sensor_name = "mt9m111"; | ||
2319 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; | ||
2320 | dev->em28xx_sensor = EM28XX_MT9M111; | ||
2321 | em28xx_initialize_mt9m111(dev); | ||
2322 | dev->sensor_xres = 640; | ||
2323 | dev->sensor_yres = 512; | ||
2324 | |||
2325 | dev->vinmode = 0x0a; | ||
2326 | dev->vinctl = 0x00; | ||
2327 | |||
2328 | break; | ||
2329 | |||
2330 | case 0x8431: | ||
2331 | dev->model = EM2750_BOARD_UNKNOWN; | ||
2332 | em28xx_set_model(dev); | ||
2333 | |||
2334 | sensor_name = "mt9m001"; | ||
2335 | dev->em28xx_sensor = EM28XX_MT9M001; | ||
2336 | em28xx_initialize_mt9m001(dev); | ||
2337 | dev->sensor_xres = 1280; | ||
2338 | dev->sensor_yres = 1024; | ||
2339 | |||
2340 | /* probably means BGGR 16 bit bayer */ | ||
2341 | dev->vinmode = 0x0c; | ||
2342 | dev->vinctl = 0x00; | ||
2343 | |||
2344 | break; | ||
2345 | default: | ||
2346 | printk("Unknown Micron Sensor 0x%04x\n", version); | ||
2347 | return -EINVAL; | ||
2348 | } | ||
2349 | |||
2350 | /* Setup webcam defaults */ | ||
2351 | em28xx_pre_card_setup(dev); | ||
2352 | |||
2353 | em28xx_errdev("Sensor is %s, using model %s entry.\n", | ||
2354 | sensor_name, em28xx_boards[dev->model].name); | ||
2355 | |||
2356 | return 0; | ||
2357 | } | ||
2358 | |||
2359 | /* Since em28xx_pre_card_setup() requires a proper dev->model, | ||
2360 | * this won't work for boards with generic PCI IDs | ||
2361 | */ | ||
2362 | static void em28xx_pre_card_setup(struct em28xx *dev) | ||
2363 | { | ||
2364 | /* Set the initial XCLK and I2C clock values based on the board | ||
2365 | definition */ | ||
2366 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f); | ||
2367 | if (!dev->board.is_em2800) | ||
2368 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); | ||
2369 | msleep(50); | ||
2370 | |||
2371 | /* request some modules */ | ||
2372 | switch (dev->model) { | ||
2373 | case EM2861_BOARD_PLEXTOR_PX_TV100U: | ||
2374 | /* Sets the msp34xx I2S speed */ | ||
2375 | dev->i2s_speed = 2048000; | ||
2376 | break; | ||
2377 | case EM2861_BOARD_KWORLD_PVRTV_300U: | ||
2378 | case EM2880_BOARD_KWORLD_DVB_305U: | ||
2379 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d); | ||
2380 | msleep(10); | ||
2381 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d); | ||
2382 | msleep(10); | ||
2383 | break; | ||
2384 | case EM2870_BOARD_COMPRO_VIDEOMATE: | ||
2385 | /* TODO: someone can do some cleanup here... | ||
2386 | not everything's needed */ | ||
2387 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | ||
2388 | msleep(10); | ||
2389 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x01); | ||
2390 | msleep(10); | ||
2391 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2392 | mdelay(70); | ||
2393 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc); | ||
2394 | mdelay(70); | ||
2395 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc); | ||
2396 | mdelay(70); | ||
2397 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc); | ||
2398 | mdelay(70); | ||
2399 | break; | ||
2400 | case EM2870_BOARD_TERRATEC_XS_MT2060: | ||
2401 | /* this device needs some gpio writes to get the DVB-T | ||
2402 | demod work */ | ||
2403 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2404 | mdelay(70); | ||
2405 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde); | ||
2406 | mdelay(70); | ||
2407 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2408 | mdelay(70); | ||
2409 | break; | ||
2410 | case EM2870_BOARD_PINNACLE_PCTV_DVB: | ||
2411 | /* this device needs some gpio writes to get the | ||
2412 | DVB-T demod work */ | ||
2413 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2414 | mdelay(70); | ||
2415 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde); | ||
2416 | mdelay(70); | ||
2417 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2418 | mdelay(70); | ||
2419 | break; | ||
2420 | case EM2820_BOARD_GADMEI_UTV310: | ||
2421 | case EM2820_BOARD_MSI_VOX_USB_2: | ||
2422 | /* enables audio for that devices */ | ||
2423 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2424 | break; | ||
2425 | |||
2426 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
2427 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
2428 | msleep(10); | ||
2429 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2430 | msleep(10); | ||
2431 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | ||
2432 | msleep(10); | ||
2433 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x08); | ||
2434 | msleep(10); | ||
2435 | break; | ||
2436 | |||
2437 | case EM2860_BOARD_KAIOMY_TVNPC_U2: | ||
2438 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); | ||
2439 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
2440 | em28xx_write_regs(dev, 0x0d, "\x42", 1); | ||
2441 | em28xx_write_regs(dev, 0x08, "\xfd", 1); | ||
2442 | msleep(10); | ||
2443 | em28xx_write_regs(dev, 0x08, "\xff", 1); | ||
2444 | msleep(10); | ||
2445 | em28xx_write_regs(dev, 0x08, "\x7f", 1); | ||
2446 | msleep(10); | ||
2447 | em28xx_write_regs(dev, 0x08, "\x6b", 1); | ||
2448 | |||
2449 | break; | ||
2450 | case EM2860_BOARD_EASYCAP: | ||
2451 | em28xx_write_regs(dev, 0x08, "\xf8", 1); | ||
2452 | break; | ||
2453 | |||
2454 | case EM2820_BOARD_IODATA_GVMVP_SZ: | ||
2455 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
2456 | msleep(70); | ||
2457 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); | ||
2458 | msleep(10); | ||
2459 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2460 | msleep(70); | ||
2461 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2462 | msleep(70); | ||
2463 | break; | ||
2464 | } | ||
2465 | |||
2466 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2467 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
2468 | |||
2469 | /* Unlock device */ | ||
2470 | em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
2471 | } | ||
2472 | |||
2473 | static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | ||
2474 | { | ||
2475 | memset(ctl, 0, sizeof(*ctl)); | ||
2476 | |||
2477 | ctl->fname = XC2028_DEFAULT_FIRMWARE; | ||
2478 | ctl->max_len = 64; | ||
2479 | ctl->mts = em28xx_boards[dev->model].mts_firmware; | ||
2480 | |||
2481 | switch (dev->model) { | ||
2482 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
2483 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
2484 | case EM2882_BOARD_TERRATEC_HYBRID_XS: | ||
2485 | ctl->demod = XC3028_FE_ZARLINK456; | ||
2486 | break; | ||
2487 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
2488 | case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: | ||
2489 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
2490 | ctl->demod = XC3028_FE_ZARLINK456; | ||
2491 | break; | ||
2492 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | ||
2493 | case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: | ||
2494 | ctl->demod = XC3028_FE_DEFAULT; | ||
2495 | break; | ||
2496 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | ||
2497 | ctl->demod = XC3028_FE_DEFAULT; | ||
2498 | ctl->fname = XC3028L_DEFAULT_FIRMWARE; | ||
2499 | break; | ||
2500 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
2501 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
2502 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | ||
2503 | /* FIXME: Better to specify the needed IF */ | ||
2504 | ctl->demod = XC3028_FE_DEFAULT; | ||
2505 | break; | ||
2506 | case EM2883_BOARD_KWORLD_HYBRID_330U: | ||
2507 | case EM2882_BOARD_DIKOM_DK300: | ||
2508 | case EM2882_BOARD_KWORLD_VS_DVBT: | ||
2509 | ctl->demod = XC3028_FE_CHINA; | ||
2510 | ctl->fname = XC2028_DEFAULT_FIRMWARE; | ||
2511 | break; | ||
2512 | case EM2882_BOARD_EVGA_INDTUBE: | ||
2513 | ctl->demod = XC3028_FE_CHINA; | ||
2514 | ctl->fname = XC3028L_DEFAULT_FIRMWARE; | ||
2515 | break; | ||
2516 | default: | ||
2517 | ctl->demod = XC3028_FE_OREN538; | ||
2518 | } | ||
2519 | } | ||
2520 | |||
2521 | static void em28xx_tuner_setup(struct em28xx *dev) | ||
2522 | { | ||
2523 | struct tuner_setup tun_setup; | ||
2524 | struct v4l2_frequency f; | ||
2525 | |||
2526 | if (dev->tuner_type == TUNER_ABSENT) | ||
2527 | return; | ||
2528 | |||
2529 | memset(&tun_setup, 0, sizeof(tun_setup)); | ||
2530 | |||
2531 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | ||
2532 | tun_setup.tuner_callback = em28xx_tuner_callback; | ||
2533 | |||
2534 | if (dev->board.radio.type) { | ||
2535 | tun_setup.type = dev->board.radio.type; | ||
2536 | tun_setup.addr = dev->board.radio_addr; | ||
2537 | |||
2538 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup); | ||
2539 | } | ||
2540 | |||
2541 | if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) { | ||
2542 | tun_setup.type = dev->tuner_type; | ||
2543 | tun_setup.addr = dev->tuner_addr; | ||
2544 | |||
2545 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup); | ||
2546 | } | ||
2547 | |||
2548 | if (dev->tda9887_conf) { | ||
2549 | struct v4l2_priv_tun_config tda9887_cfg; | ||
2550 | |||
2551 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
2552 | tda9887_cfg.priv = &dev->tda9887_conf; | ||
2553 | |||
2554 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg); | ||
2555 | } | ||
2556 | |||
2557 | if (dev->tuner_type == TUNER_XC2028) { | ||
2558 | struct v4l2_priv_tun_config xc2028_cfg; | ||
2559 | struct xc2028_ctrl ctl; | ||
2560 | |||
2561 | memset(&xc2028_cfg, 0, sizeof(xc2028_cfg)); | ||
2562 | memset(&ctl, 0, sizeof(ctl)); | ||
2563 | |||
2564 | em28xx_setup_xc3028(dev, &ctl); | ||
2565 | |||
2566 | xc2028_cfg.tuner = TUNER_XC2028; | ||
2567 | xc2028_cfg.priv = &ctl; | ||
2568 | |||
2569 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg); | ||
2570 | } | ||
2571 | |||
2572 | /* configure tuner */ | ||
2573 | f.tuner = 0; | ||
2574 | f.type = V4L2_TUNER_ANALOG_TV; | ||
2575 | f.frequency = 9076; /* just a magic number */ | ||
2576 | dev->ctl_freq = f.frequency; | ||
2577 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | ||
2578 | } | ||
2579 | |||
2580 | static int em28xx_hint_board(struct em28xx *dev) | ||
2581 | { | ||
2582 | int i; | ||
2583 | |||
2584 | /* HINT method: EEPROM | ||
2585 | * | ||
2586 | * This method works only for boards with eeprom. | ||
2587 | * Uses a hash of all eeprom bytes. The hash should be | ||
2588 | * unique for a vendor/tuner pair. | ||
2589 | * There are a high chance that tuners for different | ||
2590 | * video standards produce different hashes. | ||
2591 | */ | ||
2592 | for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) { | ||
2593 | if (dev->hash == em28xx_eeprom_hash[i].hash) { | ||
2594 | dev->model = em28xx_eeprom_hash[i].model; | ||
2595 | dev->tuner_type = em28xx_eeprom_hash[i].tuner; | ||
2596 | |||
2597 | em28xx_errdev("Your board has no unique USB ID.\n"); | ||
2598 | em28xx_errdev("A hint were successfully done, " | ||
2599 | "based on eeprom hash.\n"); | ||
2600 | em28xx_errdev("This method is not 100%% failproof.\n"); | ||
2601 | em28xx_errdev("If the board were missdetected, " | ||
2602 | "please email this log to:\n"); | ||
2603 | em28xx_errdev("\tV4L Mailing List " | ||
2604 | " <linux-media@vger.kernel.org>\n"); | ||
2605 | em28xx_errdev("Board detected as %s\n", | ||
2606 | em28xx_boards[dev->model].name); | ||
2607 | |||
2608 | return 0; | ||
2609 | } | ||
2610 | } | ||
2611 | |||
2612 | /* HINT method: I2C attached devices | ||
2613 | * | ||
2614 | * This method works for all boards. | ||
2615 | * Uses a hash of i2c scanned devices. | ||
2616 | * Devices with the same i2c attached chips will | ||
2617 | * be considered equal. | ||
2618 | * This method is less precise than the eeprom one. | ||
2619 | */ | ||
2620 | |||
2621 | /* user did not request i2c scanning => do it now */ | ||
2622 | if (!dev->i2c_hash) | ||
2623 | em28xx_do_i2c_scan(dev); | ||
2624 | |||
2625 | for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) { | ||
2626 | if (dev->i2c_hash == em28xx_i2c_hash[i].hash) { | ||
2627 | dev->model = em28xx_i2c_hash[i].model; | ||
2628 | dev->tuner_type = em28xx_i2c_hash[i].tuner; | ||
2629 | em28xx_errdev("Your board has no unique USB ID.\n"); | ||
2630 | em28xx_errdev("A hint were successfully done, " | ||
2631 | "based on i2c devicelist hash.\n"); | ||
2632 | em28xx_errdev("This method is not 100%% failproof.\n"); | ||
2633 | em28xx_errdev("If the board were missdetected, " | ||
2634 | "please email this log to:\n"); | ||
2635 | em28xx_errdev("\tV4L Mailing List " | ||
2636 | " <linux-media@vger.kernel.org>\n"); | ||
2637 | em28xx_errdev("Board detected as %s\n", | ||
2638 | em28xx_boards[dev->model].name); | ||
2639 | |||
2640 | return 0; | ||
2641 | } | ||
2642 | } | ||
2643 | |||
2644 | em28xx_errdev("Your board has no unique USB ID and thus need a " | ||
2645 | "hint to be detected.\n"); | ||
2646 | em28xx_errdev("You may try to use card=<n> insmod option to " | ||
2647 | "workaround that.\n"); | ||
2648 | em28xx_errdev("Please send an email with this log to:\n"); | ||
2649 | em28xx_errdev("\tV4L Mailing List <linux-media@vger.kernel.org>\n"); | ||
2650 | em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash); | ||
2651 | em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); | ||
2652 | |||
2653 | em28xx_errdev("Here is a list of valid choices for the card=<n>" | ||
2654 | " insmod option:\n"); | ||
2655 | for (i = 0; i < em28xx_bcount; i++) { | ||
2656 | em28xx_errdev(" card=%d -> %s\n", | ||
2657 | i, em28xx_boards[i].name); | ||
2658 | } | ||
2659 | return -1; | ||
2660 | } | ||
2661 | |||
2662 | static void em28xx_card_setup(struct em28xx *dev) | ||
2663 | { | ||
2664 | /* | ||
2665 | * If the device can be a webcam, seek for a sensor. | ||
2666 | * If sensor is not found, then it isn't a webcam. | ||
2667 | */ | ||
2668 | if (dev->board.is_webcam) { | ||
2669 | if (em28xx_hint_sensor(dev) < 0) | ||
2670 | dev->board.is_webcam = 0; | ||
2671 | else | ||
2672 | dev->progressive = 1; | ||
2673 | } | ||
2674 | |||
2675 | if (!dev->board.is_webcam) { | ||
2676 | switch (dev->model) { | ||
2677 | case EM2820_BOARD_UNKNOWN: | ||
2678 | case EM2800_BOARD_UNKNOWN: | ||
2679 | /* | ||
2680 | * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD. | ||
2681 | * | ||
2682 | * This occurs because they share identical USB vendor and | ||
2683 | * product IDs. | ||
2684 | * | ||
2685 | * What we do here is look up the EEPROM hash of the K-WORLD | ||
2686 | * and if it is found then we decide that we do not have | ||
2687 | * a DIGIVOX and reset the device to the K-WORLD instead. | ||
2688 | * | ||
2689 | * This solution is only valid if they do not share eeprom | ||
2690 | * hash identities which has not been determined as yet. | ||
2691 | */ | ||
2692 | if (em28xx_hint_board(dev) < 0) | ||
2693 | em28xx_errdev("Board not discovered\n"); | ||
2694 | else { | ||
2695 | em28xx_set_model(dev); | ||
2696 | em28xx_pre_card_setup(dev); | ||
2697 | } | ||
2698 | break; | ||
2699 | default: | ||
2700 | em28xx_set_model(dev); | ||
2701 | } | ||
2702 | } | ||
2703 | |||
2704 | em28xx_info("Identified as %s (card=%d)\n", | ||
2705 | dev->board.name, dev->model); | ||
2706 | |||
2707 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; | ||
2708 | if (em28xx_boards[dev->model].tuner_addr) | ||
2709 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; | ||
2710 | |||
2711 | if (em28xx_boards[dev->model].tda9887_conf) | ||
2712 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | ||
2713 | |||
2714 | /* request some modules */ | ||
2715 | switch (dev->model) { | ||
2716 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: | ||
2717 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
2718 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | ||
2719 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
2720 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
2721 | { | ||
2722 | struct tveeprom tv; | ||
2723 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
2724 | request_module("tveeprom"); | ||
2725 | #endif | ||
2726 | /* Call first TVeeprom */ | ||
2727 | |||
2728 | dev->i2c_client.addr = 0xa0 >> 1; | ||
2729 | tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); | ||
2730 | |||
2731 | dev->tuner_type = tv.tuner_type; | ||
2732 | |||
2733 | if (tv.audio_processor == V4L2_IDENT_MSPX4XX) { | ||
2734 | dev->i2s_speed = 2048000; | ||
2735 | dev->board.has_msp34xx = 1; | ||
2736 | } | ||
2737 | break; | ||
2738 | } | ||
2739 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
2740 | em28xx_write_reg(dev, 0x0d, 0x42); | ||
2741 | msleep(10); | ||
2742 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2743 | msleep(10); | ||
2744 | break; | ||
2745 | case EM2820_BOARD_KWORLD_PVRTV2800RF: | ||
2746 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ | ||
2747 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); | ||
2748 | break; | ||
2749 | case EM2820_BOARD_UNKNOWN: | ||
2750 | case EM2800_BOARD_UNKNOWN: | ||
2751 | /* | ||
2752 | * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD. | ||
2753 | * | ||
2754 | * This occurs because they share identical USB vendor and | ||
2755 | * product IDs. | ||
2756 | * | ||
2757 | * What we do here is look up the EEPROM hash of the K-WORLD | ||
2758 | * and if it is found then we decide that we do not have | ||
2759 | * a DIGIVOX and reset the device to the K-WORLD instead. | ||
2760 | * | ||
2761 | * This solution is only valid if they do not share eeprom | ||
2762 | * hash identities which has not been determined as yet. | ||
2763 | */ | ||
2764 | case EM2880_BOARD_MSI_DIGIVOX_AD: | ||
2765 | if (!em28xx_hint_board(dev)) | ||
2766 | em28xx_set_model(dev); | ||
2767 | |||
2768 | /* In cases where we had to use a board hint, the call to | ||
2769 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | ||
2770 | so make the call now so the analog GPIOs are set properly | ||
2771 | before probing the i2c bus. */ | ||
2772 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2773 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
2774 | break; | ||
2775 | |||
2776 | /* | ||
2777 | * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR. | ||
2778 | * | ||
2779 | * This occurs because they share identical USB vendor and | ||
2780 | * product IDs. | ||
2781 | * | ||
2782 | * What we do here is look up the EEPROM hash of the Dikom | ||
2783 | * and if it is found then we decide that we do not have | ||
2784 | * a Kworld and reset the device to the Dikom instead. | ||
2785 | * | ||
2786 | * This solution is only valid if they do not share eeprom | ||
2787 | * hash identities which has not been determined as yet. | ||
2788 | */ | ||
2789 | case EM2882_BOARD_KWORLD_VS_DVBT: | ||
2790 | if (!em28xx_hint_board(dev)) | ||
2791 | em28xx_set_model(dev); | ||
2792 | |||
2793 | /* In cases where we had to use a board hint, the call to | ||
2794 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | ||
2795 | so make the call now so the analog GPIOs are set properly | ||
2796 | before probing the i2c bus. */ | ||
2797 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2798 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
2799 | break; | ||
2800 | } | ||
2801 | |||
2802 | if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { | ||
2803 | em28xx_errdev("\n\n"); | ||
2804 | em28xx_errdev("The support for this board weren't " | ||
2805 | "valid yet.\n"); | ||
2806 | em28xx_errdev("Please send a report of having this working\n"); | ||
2807 | em28xx_errdev("not to V4L mailing list (and/or to other " | ||
2808 | "addresses)\n\n"); | ||
2809 | } | ||
2810 | |||
2811 | /* Allow override tuner type by a module parameter */ | ||
2812 | if (tuner >= 0) | ||
2813 | dev->tuner_type = tuner; | ||
2814 | |||
2815 | /* request some modules */ | ||
2816 | if (dev->board.has_msp34xx) | ||
2817 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2818 | "msp3400", 0, msp3400_addrs); | ||
2819 | |||
2820 | if (dev->board.decoder == EM28XX_SAA711X) | ||
2821 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2822 | "saa7115_auto", 0, saa711x_addrs); | ||
2823 | |||
2824 | if (dev->board.decoder == EM28XX_TVP5150) | ||
2825 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2826 | "tvp5150", 0, tvp5150_addrs); | ||
2827 | |||
2828 | if (dev->em28xx_sensor == EM28XX_MT9V011) { | ||
2829 | struct mt9v011_platform_data pdata; | ||
2830 | struct i2c_board_info mt9v011_info = { | ||
2831 | .type = "mt9v011", | ||
2832 | .addr = 0xba >> 1, | ||
2833 | .platform_data = &pdata, | ||
2834 | }; | ||
2835 | |||
2836 | pdata.xtal = dev->sensor_xtal; | ||
2837 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap, | ||
2838 | &mt9v011_info, NULL); | ||
2839 | } | ||
2840 | |||
2841 | |||
2842 | if (dev->board.adecoder == EM28XX_TVAUDIO) | ||
2843 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2844 | "tvaudio", dev->board.tvaudio_addr, NULL); | ||
2845 | |||
2846 | if (dev->board.tuner_type != TUNER_ABSENT) { | ||
2847 | int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); | ||
2848 | |||
2849 | if (dev->board.radio.type) | ||
2850 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2851 | "tuner", dev->board.radio_addr, NULL); | ||
2852 | |||
2853 | if (has_demod) | ||
2854 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | ||
2855 | &dev->i2c_adap, "tuner", | ||
2856 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | ||
2857 | if (dev->tuner_addr == 0) { | ||
2858 | enum v4l2_i2c_tuner_type type = | ||
2859 | has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; | ||
2860 | struct v4l2_subdev *sd; | ||
2861 | |||
2862 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | ||
2863 | &dev->i2c_adap, "tuner", | ||
2864 | 0, v4l2_i2c_tuner_addrs(type)); | ||
2865 | |||
2866 | if (sd) | ||
2867 | dev->tuner_addr = v4l2_i2c_subdev_addr(sd); | ||
2868 | } else { | ||
2869 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2870 | "tuner", dev->tuner_addr, NULL); | ||
2871 | } | ||
2872 | } | ||
2873 | |||
2874 | em28xx_tuner_setup(dev); | ||
2875 | } | ||
2876 | |||
2877 | |||
2878 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
2879 | static void request_module_async(struct work_struct *work) | ||
2880 | { | ||
2881 | struct em28xx *dev = container_of(work, | ||
2882 | struct em28xx, request_module_wk); | ||
2883 | |||
2884 | if (dev->has_audio_class) | ||
2885 | request_module("snd-usb-audio"); | ||
2886 | else if (dev->has_alsa_audio) | ||
2887 | request_module("em28xx-alsa"); | ||
2888 | |||
2889 | if (dev->board.has_dvb) | ||
2890 | request_module("em28xx-dvb"); | ||
2891 | if (dev->board.ir_codes && !disable_ir) | ||
2892 | request_module("em28xx-rc"); | ||
2893 | } | ||
2894 | |||
2895 | static void request_modules(struct em28xx *dev) | ||
2896 | { | ||
2897 | INIT_WORK(&dev->request_module_wk, request_module_async); | ||
2898 | schedule_work(&dev->request_module_wk); | ||
2899 | } | ||
2900 | |||
2901 | static void flush_request_modules(struct em28xx *dev) | ||
2902 | { | ||
2903 | flush_work_sync(&dev->request_module_wk); | ||
2904 | } | ||
2905 | #else | ||
2906 | #define request_modules(dev) | ||
2907 | #define flush_request_modules(dev) | ||
2908 | #endif /* CONFIG_MODULES */ | ||
2909 | |||
2910 | /* | ||
2911 | * em28xx_release_resources() | ||
2912 | * unregisters the v4l2,i2c and usb devices | ||
2913 | * called when the device gets disconnected or at module unload | ||
2914 | */ | ||
2915 | void em28xx_release_resources(struct em28xx *dev) | ||
2916 | { | ||
2917 | /*FIXME: I2C IR should be disconnected */ | ||
2918 | |||
2919 | em28xx_release_analog_resources(dev); | ||
2920 | |||
2921 | em28xx_i2c_unregister(dev); | ||
2922 | |||
2923 | v4l2_device_unregister(&dev->v4l2_dev); | ||
2924 | |||
2925 | usb_put_dev(dev->udev); | ||
2926 | |||
2927 | /* Mark device as unused */ | ||
2928 | clear_bit(dev->devno, &em28xx_devused); | ||
2929 | }; | ||
2930 | |||
2931 | /* | ||
2932 | * em28xx_init_dev() | ||
2933 | * allocates and inits the device structs, registers i2c bus and v4l device | ||
2934 | */ | ||
2935 | static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | ||
2936 | struct usb_interface *interface, | ||
2937 | int minor) | ||
2938 | { | ||
2939 | int retval; | ||
2940 | |||
2941 | dev->udev = udev; | ||
2942 | mutex_init(&dev->ctrl_urb_lock); | ||
2943 | spin_lock_init(&dev->slock); | ||
2944 | |||
2945 | dev->em28xx_write_regs = em28xx_write_regs; | ||
2946 | dev->em28xx_read_reg = em28xx_read_reg; | ||
2947 | dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len; | ||
2948 | dev->em28xx_write_regs_req = em28xx_write_regs_req; | ||
2949 | dev->em28xx_read_reg_req = em28xx_read_reg_req; | ||
2950 | dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800; | ||
2951 | |||
2952 | em28xx_set_model(dev); | ||
2953 | |||
2954 | /* Set the default GPO/GPIO for legacy devices */ | ||
2955 | dev->reg_gpo_num = EM2880_R04_GPO; | ||
2956 | dev->reg_gpio_num = EM28XX_R08_GPIO; | ||
2957 | |||
2958 | dev->wait_after_write = 5; | ||
2959 | |||
2960 | /* Based on the Chip ID, set the device configuration */ | ||
2961 | retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); | ||
2962 | if (retval > 0) { | ||
2963 | dev->chip_id = retval; | ||
2964 | |||
2965 | switch (dev->chip_id) { | ||
2966 | case CHIP_ID_EM2800: | ||
2967 | em28xx_info("chip ID is em2800\n"); | ||
2968 | break; | ||
2969 | case CHIP_ID_EM2710: | ||
2970 | em28xx_info("chip ID is em2710\n"); | ||
2971 | break; | ||
2972 | case CHIP_ID_EM2750: | ||
2973 | em28xx_info("chip ID is em2750\n"); | ||
2974 | break; | ||
2975 | case CHIP_ID_EM2820: | ||
2976 | em28xx_info("chip ID is em2820 (or em2710)\n"); | ||
2977 | break; | ||
2978 | case CHIP_ID_EM2840: | ||
2979 | em28xx_info("chip ID is em2840\n"); | ||
2980 | break; | ||
2981 | case CHIP_ID_EM2860: | ||
2982 | em28xx_info("chip ID is em2860\n"); | ||
2983 | break; | ||
2984 | case CHIP_ID_EM2870: | ||
2985 | em28xx_info("chip ID is em2870\n"); | ||
2986 | dev->wait_after_write = 0; | ||
2987 | break; | ||
2988 | case CHIP_ID_EM2874: | ||
2989 | em28xx_info("chip ID is em2874\n"); | ||
2990 | dev->reg_gpio_num = EM2874_R80_GPIO; | ||
2991 | dev->wait_after_write = 0; | ||
2992 | break; | ||
2993 | case CHIP_ID_EM28174: | ||
2994 | em28xx_info("chip ID is em28174\n"); | ||
2995 | dev->reg_gpio_num = EM2874_R80_GPIO; | ||
2996 | dev->wait_after_write = 0; | ||
2997 | break; | ||
2998 | case CHIP_ID_EM2883: | ||
2999 | em28xx_info("chip ID is em2882/em2883\n"); | ||
3000 | dev->wait_after_write = 0; | ||
3001 | break; | ||
3002 | case CHIP_ID_EM2884: | ||
3003 | em28xx_info("chip ID is em2884\n"); | ||
3004 | dev->reg_gpio_num = EM2874_R80_GPIO; | ||
3005 | dev->wait_after_write = 0; | ||
3006 | break; | ||
3007 | default: | ||
3008 | em28xx_info("em28xx chip ID = %d\n", dev->chip_id); | ||
3009 | } | ||
3010 | } | ||
3011 | |||
3012 | if (dev->is_audio_only) { | ||
3013 | retval = em28xx_audio_setup(dev); | ||
3014 | if (retval) | ||
3015 | return -ENODEV; | ||
3016 | em28xx_init_extension(dev); | ||
3017 | |||
3018 | return 0; | ||
3019 | } | ||
3020 | |||
3021 | /* Prepopulate cached GPO register content */ | ||
3022 | retval = em28xx_read_reg(dev, dev->reg_gpo_num); | ||
3023 | if (retval >= 0) | ||
3024 | dev->reg_gpo = retval; | ||
3025 | |||
3026 | em28xx_pre_card_setup(dev); | ||
3027 | |||
3028 | if (!dev->board.is_em2800) { | ||
3029 | /* Resets I2C speed */ | ||
3030 | retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); | ||
3031 | if (retval < 0) { | ||
3032 | em28xx_errdev("%s: em28xx_write_reg failed!" | ||
3033 | " retval [%d]\n", | ||
3034 | __func__, retval); | ||
3035 | return retval; | ||
3036 | } | ||
3037 | } | ||
3038 | |||
3039 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); | ||
3040 | if (retval < 0) { | ||
3041 | em28xx_errdev("Call to v4l2_device_register() failed!\n"); | ||
3042 | return retval; | ||
3043 | } | ||
3044 | |||
3045 | /* register i2c bus */ | ||
3046 | retval = em28xx_i2c_register(dev); | ||
3047 | if (retval < 0) { | ||
3048 | em28xx_errdev("%s: em28xx_i2c_register - error [%d]!\n", | ||
3049 | __func__, retval); | ||
3050 | goto unregister_dev; | ||
3051 | } | ||
3052 | |||
3053 | /* | ||
3054 | * Default format, used for tvp5150 or saa711x output formats | ||
3055 | */ | ||
3056 | dev->vinmode = 0x10; | ||
3057 | dev->vinctl = EM28XX_VINCTRL_INTERLACED | | ||
3058 | EM28XX_VINCTRL_CCIR656_ENABLE; | ||
3059 | |||
3060 | /* Do board specific init and eeprom reading */ | ||
3061 | em28xx_card_setup(dev); | ||
3062 | |||
3063 | /* Configure audio */ | ||
3064 | retval = em28xx_audio_setup(dev); | ||
3065 | if (retval < 0) { | ||
3066 | em28xx_errdev("%s: Error while setting audio - error [%d]!\n", | ||
3067 | __func__, retval); | ||
3068 | goto fail; | ||
3069 | } | ||
3070 | |||
3071 | /* wake i2c devices */ | ||
3072 | em28xx_wake_i2c(dev); | ||
3073 | |||
3074 | /* init video dma queues */ | ||
3075 | INIT_LIST_HEAD(&dev->vidq.active); | ||
3076 | INIT_LIST_HEAD(&dev->vbiq.active); | ||
3077 | |||
3078 | if (dev->board.has_msp34xx) { | ||
3079 | /* Send a reset to other chips via gpio */ | ||
3080 | retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); | ||
3081 | if (retval < 0) { | ||
3082 | em28xx_errdev("%s: em28xx_write_reg - " | ||
3083 | "msp34xx(1) failed! error [%d]\n", | ||
3084 | __func__, retval); | ||
3085 | goto fail; | ||
3086 | } | ||
3087 | msleep(3); | ||
3088 | |||
3089 | retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
3090 | if (retval < 0) { | ||
3091 | em28xx_errdev("%s: em28xx_write_reg - " | ||
3092 | "msp34xx(2) failed! error [%d]\n", | ||
3093 | __func__, retval); | ||
3094 | goto fail; | ||
3095 | } | ||
3096 | msleep(3); | ||
3097 | } | ||
3098 | |||
3099 | retval = em28xx_register_analog_devices(dev); | ||
3100 | if (retval < 0) { | ||
3101 | goto fail; | ||
3102 | } | ||
3103 | |||
3104 | /* Save some power by putting tuner to sleep */ | ||
3105 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); | ||
3106 | |||
3107 | return 0; | ||
3108 | |||
3109 | fail: | ||
3110 | em28xx_i2c_unregister(dev); | ||
3111 | |||
3112 | unregister_dev: | ||
3113 | v4l2_device_unregister(&dev->v4l2_dev); | ||
3114 | |||
3115 | return retval; | ||
3116 | } | ||
3117 | |||
3118 | /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ | ||
3119 | #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) | ||
3120 | |||
3121 | /* | ||
3122 | * em28xx_usb_probe() | ||
3123 | * checks for supported devices | ||
3124 | */ | ||
3125 | static int em28xx_usb_probe(struct usb_interface *interface, | ||
3126 | const struct usb_device_id *id) | ||
3127 | { | ||
3128 | struct usb_device *udev; | ||
3129 | struct em28xx *dev = NULL; | ||
3130 | int retval; | ||
3131 | bool has_audio = false, has_video = false, has_dvb = false; | ||
3132 | int i, nr; | ||
3133 | const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; | ||
3134 | char *speed; | ||
3135 | |||
3136 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
3137 | |||
3138 | /* Check to see next free device and mark as used */ | ||
3139 | do { | ||
3140 | nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); | ||
3141 | if (nr >= EM28XX_MAXBOARDS) { | ||
3142 | /* No free device slots */ | ||
3143 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", | ||
3144 | EM28XX_MAXBOARDS); | ||
3145 | retval = -ENOMEM; | ||
3146 | goto err_no_slot; | ||
3147 | } | ||
3148 | } while (test_and_set_bit(nr, &em28xx_devused)); | ||
3149 | |||
3150 | /* Don't register audio interfaces */ | ||
3151 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
3152 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): " | ||
3153 | "interface %i, class %i\n", | ||
3154 | le16_to_cpu(udev->descriptor.idVendor), | ||
3155 | le16_to_cpu(udev->descriptor.idProduct), | ||
3156 | ifnum, | ||
3157 | interface->altsetting[0].desc.bInterfaceClass); | ||
3158 | |||
3159 | retval = -ENODEV; | ||
3160 | goto err; | ||
3161 | } | ||
3162 | |||
3163 | /* allocate memory for our device state and initialize it */ | ||
3164 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
3165 | if (dev == NULL) { | ||
3166 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | ||
3167 | retval = -ENOMEM; | ||
3168 | goto err; | ||
3169 | } | ||
3170 | |||
3171 | /* compute alternate max packet sizes */ | ||
3172 | dev->alt_max_pkt_size = kmalloc(sizeof(dev->alt_max_pkt_size[0]) * | ||
3173 | interface->num_altsetting, GFP_KERNEL); | ||
3174 | if (dev->alt_max_pkt_size == NULL) { | ||
3175 | em28xx_errdev("out of memory!\n"); | ||
3176 | kfree(dev); | ||
3177 | retval = -ENOMEM; | ||
3178 | goto err; | ||
3179 | } | ||
3180 | |||
3181 | /* Get endpoints */ | ||
3182 | for (i = 0; i < interface->num_altsetting; i++) { | ||
3183 | int ep; | ||
3184 | |||
3185 | for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) { | ||
3186 | const struct usb_endpoint_descriptor *e; | ||
3187 | int sizedescr, size; | ||
3188 | |||
3189 | e = &interface->altsetting[i].endpoint[ep].desc; | ||
3190 | |||
3191 | sizedescr = le16_to_cpu(e->wMaxPacketSize); | ||
3192 | size = sizedescr & 0x7ff; | ||
3193 | |||
3194 | if (udev->speed == USB_SPEED_HIGH) | ||
3195 | size = size * hb_mult(sizedescr); | ||
3196 | |||
3197 | if (usb_endpoint_xfer_isoc(e) && | ||
3198 | usb_endpoint_dir_in(e)) { | ||
3199 | switch (e->bEndpointAddress) { | ||
3200 | case EM28XX_EP_AUDIO: | ||
3201 | has_audio = true; | ||
3202 | break; | ||
3203 | case EM28XX_EP_ANALOG: | ||
3204 | has_video = true; | ||
3205 | dev->alt_max_pkt_size[i] = size; | ||
3206 | break; | ||
3207 | case EM28XX_EP_DIGITAL: | ||
3208 | has_dvb = true; | ||
3209 | if (size > dev->dvb_max_pkt_size) { | ||
3210 | dev->dvb_max_pkt_size = size; | ||
3211 | dev->dvb_alt = i; | ||
3212 | } | ||
3213 | break; | ||
3214 | } | ||
3215 | } | ||
3216 | } | ||
3217 | } | ||
3218 | |||
3219 | if (!(has_audio || has_video || has_dvb)) { | ||
3220 | retval = -ENODEV; | ||
3221 | goto err_free; | ||
3222 | } | ||
3223 | |||
3224 | switch (udev->speed) { | ||
3225 | case USB_SPEED_LOW: | ||
3226 | speed = "1.5"; | ||
3227 | break; | ||
3228 | case USB_SPEED_UNKNOWN: | ||
3229 | case USB_SPEED_FULL: | ||
3230 | speed = "12"; | ||
3231 | break; | ||
3232 | case USB_SPEED_HIGH: | ||
3233 | speed = "480"; | ||
3234 | break; | ||
3235 | default: | ||
3236 | speed = "unknown"; | ||
3237 | } | ||
3238 | |||
3239 | printk(KERN_INFO DRIVER_NAME | ||
3240 | ": New device %s %s @ %s Mbps " | ||
3241 | "(%04x:%04x, interface %d, class %d)\n", | ||
3242 | udev->manufacturer ? udev->manufacturer : "", | ||
3243 | udev->product ? udev->product : "", | ||
3244 | speed, | ||
3245 | le16_to_cpu(udev->descriptor.idVendor), | ||
3246 | le16_to_cpu(udev->descriptor.idProduct), | ||
3247 | ifnum, | ||
3248 | interface->altsetting->desc.bInterfaceNumber); | ||
3249 | |||
3250 | if (has_audio) | ||
3251 | printk(KERN_INFO DRIVER_NAME | ||
3252 | ": Audio Vendor Class interface %i found\n", | ||
3253 | ifnum); | ||
3254 | if (has_video) | ||
3255 | printk(KERN_INFO DRIVER_NAME | ||
3256 | ": Video interface %i found\n", | ||
3257 | ifnum); | ||
3258 | if (has_dvb) | ||
3259 | printk(KERN_INFO DRIVER_NAME | ||
3260 | ": DVB interface %i found\n", | ||
3261 | ifnum); | ||
3262 | |||
3263 | /* | ||
3264 | * Make sure we have 480 Mbps of bandwidth, otherwise things like | ||
3265 | * video stream wouldn't likely work, since 12 Mbps is generally | ||
3266 | * not enough even for most Digital TV streams. | ||
3267 | */ | ||
3268 | if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { | ||
3269 | printk(DRIVER_NAME ": Device initialization failed.\n"); | ||
3270 | printk(DRIVER_NAME ": Device must be connected to a high-speed" | ||
3271 | " USB 2.0 port.\n"); | ||
3272 | retval = -ENODEV; | ||
3273 | goto err_free; | ||
3274 | } | ||
3275 | |||
3276 | snprintf(dev->name, sizeof(dev->name), "em28xx #%d", nr); | ||
3277 | dev->devno = nr; | ||
3278 | dev->model = id->driver_info; | ||
3279 | dev->alt = -1; | ||
3280 | dev->is_audio_only = has_audio && !(has_video || has_dvb); | ||
3281 | dev->has_alsa_audio = has_audio; | ||
3282 | dev->audio_ifnum = ifnum; | ||
3283 | |||
3284 | /* Checks if audio is provided by some interface */ | ||
3285 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { | ||
3286 | struct usb_interface *uif = udev->config->interface[i]; | ||
3287 | if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
3288 | dev->has_audio_class = 1; | ||
3289 | break; | ||
3290 | } | ||
3291 | } | ||
3292 | |||
3293 | dev->num_alt = interface->num_altsetting; | ||
3294 | |||
3295 | if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) | ||
3296 | dev->model = card[nr]; | ||
3297 | |||
3298 | /* save our data pointer in this interface device */ | ||
3299 | usb_set_intfdata(interface, dev); | ||
3300 | |||
3301 | /* allocate device struct */ | ||
3302 | mutex_init(&dev->lock); | ||
3303 | mutex_lock(&dev->lock); | ||
3304 | retval = em28xx_init_dev(dev, udev, interface, nr); | ||
3305 | if (retval) { | ||
3306 | goto unlock_and_free; | ||
3307 | } | ||
3308 | |||
3309 | if (has_dvb) { | ||
3310 | /* pre-allocate DVB isoc transfer buffers */ | ||
3311 | retval = em28xx_alloc_isoc(dev, EM28XX_DIGITAL_MODE, | ||
3312 | EM28XX_DVB_MAX_PACKETS, | ||
3313 | EM28XX_DVB_NUM_BUFS, | ||
3314 | dev->dvb_max_pkt_size); | ||
3315 | if (retval) { | ||
3316 | goto unlock_and_free; | ||
3317 | } | ||
3318 | } | ||
3319 | |||
3320 | request_modules(dev); | ||
3321 | |||
3322 | /* Should be the last thing to do, to avoid newer udev's to | ||
3323 | open the device before fully initializing it | ||
3324 | */ | ||
3325 | mutex_unlock(&dev->lock); | ||
3326 | |||
3327 | /* | ||
3328 | * These extensions can be modules. If the modules are already | ||
3329 | * loaded then we can initialise the device now, otherwise we | ||
3330 | * will initialise it when the modules load instead. | ||
3331 | */ | ||
3332 | em28xx_init_extension(dev); | ||
3333 | |||
3334 | return 0; | ||
3335 | |||
3336 | unlock_and_free: | ||
3337 | mutex_unlock(&dev->lock); | ||
3338 | |||
3339 | err_free: | ||
3340 | kfree(dev->alt_max_pkt_size); | ||
3341 | kfree(dev); | ||
3342 | |||
3343 | err: | ||
3344 | clear_bit(nr, &em28xx_devused); | ||
3345 | |||
3346 | err_no_slot: | ||
3347 | usb_put_dev(udev); | ||
3348 | return retval; | ||
3349 | } | ||
3350 | |||
3351 | /* | ||
3352 | * em28xx_usb_disconnect() | ||
3353 | * called when the device gets disconnected | ||
3354 | * video device will be unregistered on v4l2_close in case it is still open | ||
3355 | */ | ||
3356 | static void em28xx_usb_disconnect(struct usb_interface *interface) | ||
3357 | { | ||
3358 | struct em28xx *dev; | ||
3359 | |||
3360 | dev = usb_get_intfdata(interface); | ||
3361 | usb_set_intfdata(interface, NULL); | ||
3362 | |||
3363 | if (!dev) | ||
3364 | return; | ||
3365 | |||
3366 | if (dev->is_audio_only) { | ||
3367 | mutex_lock(&dev->lock); | ||
3368 | em28xx_close_extension(dev); | ||
3369 | mutex_unlock(&dev->lock); | ||
3370 | return; | ||
3371 | } | ||
3372 | |||
3373 | em28xx_info("disconnecting %s\n", dev->vdev->name); | ||
3374 | |||
3375 | flush_request_modules(dev); | ||
3376 | |||
3377 | /* wait until all current v4l2 io is finished then deallocate | ||
3378 | resources */ | ||
3379 | mutex_lock(&dev->lock); | ||
3380 | |||
3381 | v4l2_device_disconnect(&dev->v4l2_dev); | ||
3382 | |||
3383 | if (dev->users) { | ||
3384 | em28xx_warn | ||
3385 | ("device %s is open! Deregistration and memory " | ||
3386 | "deallocation are deferred on close.\n", | ||
3387 | video_device_node_name(dev->vdev)); | ||
3388 | |||
3389 | dev->state |= DEV_MISCONFIGURED; | ||
3390 | em28xx_uninit_isoc(dev, dev->mode); | ||
3391 | dev->state |= DEV_DISCONNECTED; | ||
3392 | } else { | ||
3393 | dev->state |= DEV_DISCONNECTED; | ||
3394 | em28xx_release_resources(dev); | ||
3395 | } | ||
3396 | |||
3397 | /* free DVB isoc buffers */ | ||
3398 | em28xx_uninit_isoc(dev, EM28XX_DIGITAL_MODE); | ||
3399 | |||
3400 | mutex_unlock(&dev->lock); | ||
3401 | |||
3402 | em28xx_close_extension(dev); | ||
3403 | |||
3404 | if (!dev->users) { | ||
3405 | kfree(dev->alt_max_pkt_size); | ||
3406 | kfree(dev); | ||
3407 | } | ||
3408 | } | ||
3409 | |||
3410 | static struct usb_driver em28xx_usb_driver = { | ||
3411 | .name = "em28xx", | ||
3412 | .probe = em28xx_usb_probe, | ||
3413 | .disconnect = em28xx_usb_disconnect, | ||
3414 | .id_table = em28xx_id_table, | ||
3415 | }; | ||
3416 | |||
3417 | module_usb_driver(em28xx_usb_driver); | ||