• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * device driver for Conexant 2388x based TV cards
4  * card-specific stuff.
5  *
6  * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/pci.h>
26 #include <linux/delay.h>
27 
28 #include "cx88.h"
29 #include "tea5767.h"
30 
31 static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
32 static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
33 static unsigned int card[]  = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
34 
35 module_param_array(tuner, int, NULL, 0444);
36 module_param_array(radio, int, NULL, 0444);
37 module_param_array(card,  int, NULL, 0444);
38 
39 MODULE_PARM_DESC(tuner,"tuner type");
40 MODULE_PARM_DESC(radio,"radio tuner type");
41 MODULE_PARM_DESC(card,"card type");
42 
43 static unsigned int latency = UNSET;
44 module_param(latency,int,0444);
45 MODULE_PARM_DESC(latency,"pci latency timer");
46 
47 #define info_printk(core, fmt, arg...) \
48 	printk(KERN_INFO "%s: " fmt, core->name , ## arg)
49 
50 #define warn_printk(core, fmt, arg...) \
51 	printk(KERN_WARNING "%s: " fmt, core->name , ## arg)
52 
53 #define err_printk(core, fmt, arg...) \
54 	printk(KERN_ERR "%s: " fmt, core->name , ## arg)
55 
56 
57 /* ------------------------------------------------------------------ */
58 /* board config info                                                  */
59 
60 /* If radio_type !=UNSET, radio_addr should be specified
61  */
62 
63 static const struct cx88_board cx88_boards[] = {
64 	[CX88_BOARD_UNKNOWN] = {
65 		.name		= "UNKNOWN/GENERIC",
66 		.tuner_type     = UNSET,
67 		.radio_type     = UNSET,
68 		.tuner_addr	= ADDR_UNSET,
69 		.radio_addr	= ADDR_UNSET,
70 		.input          = {{
71 			.type   = CX88_VMUX_COMPOSITE1,
72 			.vmux   = 0,
73 		},{
74 			.type   = CX88_VMUX_COMPOSITE2,
75 			.vmux   = 1,
76 		},{
77 			.type   = CX88_VMUX_COMPOSITE3,
78 			.vmux   = 2,
79 		},{
80 			.type   = CX88_VMUX_COMPOSITE4,
81 			.vmux   = 3,
82 		}},
83 	},
84 	[CX88_BOARD_HAUPPAUGE] = {
85 		.name		= "Hauppauge WinTV 34xxx models",
86 		.tuner_type     = UNSET,
87 		.radio_type     = UNSET,
88 		.tuner_addr	= ADDR_UNSET,
89 		.radio_addr	= ADDR_UNSET,
90 		.tda9887_conf   = TDA9887_PRESENT,
91 		.input          = {{
92 			.type   = CX88_VMUX_TELEVISION,
93 			.vmux   = 0,
94 			.gpio0  = 0xff00,  // internal decoder
95 		},{
96 			.type   = CX88_VMUX_DEBUG,
97 			.vmux   = 0,
98 			.gpio0  = 0xff01,  // mono from tuner chip
99 		},{
100 			.type   = CX88_VMUX_COMPOSITE1,
101 			.vmux   = 1,
102 			.gpio0  = 0xff02,
103 		},{
104 			.type   = CX88_VMUX_SVIDEO,
105 			.vmux   = 2,
106 			.gpio0  = 0xff02,
107 		}},
108 		.radio = {
109 			.type   = CX88_RADIO,
110 			.gpio0  = 0xff01,
111 		},
112 	},
113 	[CX88_BOARD_GDI] = {
114 		.name		= "GDI Black Gold",
115 		.tuner_type     = UNSET,
116 		.radio_type     = UNSET,
117 		.tuner_addr	= ADDR_UNSET,
118 		.radio_addr	= ADDR_UNSET,
119 		.input          = {{
120 			.type   = CX88_VMUX_TELEVISION,
121 			.vmux   = 0,
122 		},{
123 			.type   = CX88_VMUX_SVIDEO,
124 			.vmux   = 2,
125 		}},
126 	},
127 	[CX88_BOARD_PIXELVIEW] = {
128 		.name           = "PixelView",
129 		.tuner_type     = TUNER_PHILIPS_PAL,
130 		.radio_type     = UNSET,
131 		.tuner_addr	= ADDR_UNSET,
132 		.radio_addr	= ADDR_UNSET,
133 		.input          = {{
134 			.type   = CX88_VMUX_TELEVISION,
135 			.vmux   = 0,
136 			.gpio0  = 0xff00,  // internal decoder
137 		},{
138 			.type   = CX88_VMUX_COMPOSITE1,
139 			.vmux   = 1,
140 		},{
141 			.type   = CX88_VMUX_SVIDEO,
142 			.vmux   = 2,
143 		}},
144 		.radio = {
145 			 .type  = CX88_RADIO,
146 			 .gpio0 = 0xff10,
147 		},
148 	},
149 	[CX88_BOARD_ATI_WONDER_PRO] = {
150 		.name           = "ATI TV Wonder Pro",
151 		.tuner_type     = TUNER_PHILIPS_4IN1,
152 		.radio_type     = UNSET,
153 		.tuner_addr	= ADDR_UNSET,
154 		.radio_addr	= ADDR_UNSET,
155 		.tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER,
156 		.input          = {{
157 			.type   = CX88_VMUX_TELEVISION,
158 			.vmux   = 0,
159 			.gpio0  = 0x03ff,
160 		},{
161 			.type   = CX88_VMUX_COMPOSITE1,
162 			.vmux   = 1,
163 			.gpio0  = 0x03fe,
164 		},{
165 			.type   = CX88_VMUX_SVIDEO,
166 			.vmux   = 2,
167 			.gpio0  = 0x03fe,
168 		}},
169 	},
170 	[CX88_BOARD_WINFAST2000XP_EXPERT] = {
171 		.name           = "Leadtek Winfast 2000XP Expert",
172 		.tuner_type     = TUNER_PHILIPS_4IN1,
173 		.radio_type     = UNSET,
174 		.tuner_addr	= ADDR_UNSET,
175 		.radio_addr	= ADDR_UNSET,
176 		.tda9887_conf   = TDA9887_PRESENT,
177 		.input          = {{
178 			.type   = CX88_VMUX_TELEVISION,
179 			.vmux   = 0,
180 			.gpio0	= 0x00F5e700,
181 			.gpio1  = 0x00003004,
182 			.gpio2  = 0x00F5e700,
183 			.gpio3  = 0x02000000,
184 		},{
185 			.type   = CX88_VMUX_COMPOSITE1,
186 			.vmux   = 1,
187 			.gpio0	= 0x00F5c700,
188 			.gpio1  = 0x00003004,
189 			.gpio2  = 0x00F5c700,
190 			.gpio3  = 0x02000000,
191 		},{
192 			.type   = CX88_VMUX_SVIDEO,
193 			.vmux   = 2,
194 			.gpio0	= 0x00F5c700,
195 			.gpio1  = 0x00003004,
196 			.gpio2  = 0x00F5c700,
197 			.gpio3  = 0x02000000,
198 		}},
199 		.radio = {
200 			.type   = CX88_RADIO,
201 			.gpio0	= 0x00F5d700,
202 			.gpio1  = 0x00003004,
203 			.gpio2  = 0x00F5d700,
204 			.gpio3  = 0x02000000,
205 		},
206 	},
207 	[CX88_BOARD_AVERTV_STUDIO_303] = {
208 		.name           = "AverTV Studio 303 (M126)",
209 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
210 		.radio_type     = UNSET,
211 		.tuner_addr	= ADDR_UNSET,
212 		.radio_addr	= ADDR_UNSET,
213 		.tda9887_conf   = TDA9887_PRESENT,
214 		.input          = {{
215 			.type   = CX88_VMUX_TELEVISION,
216 			.vmux   = 0,
217 			.gpio1  = 0xe09f,
218 		},{
219 			.type   = CX88_VMUX_COMPOSITE1,
220 			.vmux   = 1,
221 			.gpio1  = 0xe05f,
222 		},{
223 			.type   = CX88_VMUX_SVIDEO,
224 			.vmux   = 2,
225 			.gpio1  = 0xe05f,
226 		}},
227 		.radio = {
228 			.gpio1  = 0xe0df,
229 			.type   = CX88_RADIO,
230 		},
231 	},
232 	[CX88_BOARD_MSI_TVANYWHERE_MASTER] = {
233 		// added gpio values thanks to Michal
234 		// values for PAL from DScaler
235 		.name           = "MSI TV-@nywhere Master",
236 		.tuner_type     = TUNER_MT2032,
237 		.radio_type     = UNSET,
238 		.tuner_addr	= ADDR_UNSET,
239 		.radio_addr	= ADDR_UNSET,
240 		.tda9887_conf	= TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
241 		.input          = {{
242 			.type   = CX88_VMUX_TELEVISION,
243 			.vmux   = 0,
244 			.gpio0  = 0x000040bf,
245 			.gpio1  = 0x000080c0,
246 			.gpio2  = 0x0000ff40,
247 		},{
248 			.type   = CX88_VMUX_COMPOSITE1,
249 			.vmux   = 1,
250 			.gpio0  = 0x000040bf,
251 			.gpio1  = 0x000080c0,
252 			.gpio2  = 0x0000ff40,
253 		},{
254 			.type   = CX88_VMUX_SVIDEO,
255 			.vmux   = 2,
256 			.gpio0  = 0x000040bf,
257 			.gpio1  = 0x000080c0,
258 			.gpio2  = 0x0000ff40,
259 		}},
260 		.radio = {
261 			 .type   = CX88_RADIO,
262 			 .vmux   = 3,
263 			 .gpio0  = 0x000040bf,
264 			 .gpio1  = 0x000080c0,
265 			 .gpio2  = 0x0000ff20,
266 		},
267 	},
268 	[CX88_BOARD_WINFAST_DV2000] = {
269 		.name           = "Leadtek Winfast DV2000",
270 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
271 		.radio_type     = UNSET,
272 		.tuner_addr	= ADDR_UNSET,
273 		.radio_addr	= ADDR_UNSET,
274 		.tda9887_conf   = TDA9887_PRESENT,
275 		.input          = {{
276 			.type   = CX88_VMUX_TELEVISION,
277 			.vmux   = 0,
278 			.gpio0  = 0x0035e700,
279 			.gpio1  = 0x00003004,
280 			.gpio2  = 0x0035e700,
281 			.gpio3  = 0x02000000,
282 		},{
283 
284 			.type   = CX88_VMUX_COMPOSITE1,
285 			.vmux   = 1,
286 			.gpio0  = 0x0035c700,
287 			.gpio1  = 0x00003004,
288 			.gpio2  = 0x0035c700,
289 			.gpio3  = 0x02000000,
290 		},{
291 			.type   = CX88_VMUX_SVIDEO,
292 			.vmux   = 2,
293 			.gpio0  = 0x0035c700,
294 			.gpio1  = 0x0035c700,
295 			.gpio2  = 0x02000000,
296 			.gpio3  = 0x02000000,
297 		}},
298 		.radio = {
299 			.type   = CX88_RADIO,
300 			.gpio0  = 0x0035d700,
301 			.gpio1  = 0x00007004,
302 			.gpio2  = 0x0035d700,
303 			.gpio3  = 0x02000000,
304 		},
305 	},
306 	[CX88_BOARD_LEADTEK_PVR2000] = {
307 		// gpio values for PAL version from regspy by DScaler
308 		.name           = "Leadtek PVR 2000",
309 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
310 		.radio_type     = UNSET,
311 		.tuner_addr	= ADDR_UNSET,
312 		.radio_addr	= ADDR_UNSET,
313 		.tda9887_conf   = TDA9887_PRESENT,
314 		.input          = {{
315 			.type   = CX88_VMUX_TELEVISION,
316 			.vmux   = 0,
317 			.gpio0  = 0x0000bde2,
318 			.audioroute = 1,
319 		},{
320 			.type   = CX88_VMUX_COMPOSITE1,
321 			.vmux   = 1,
322 			.gpio0  = 0x0000bde6,
323 			.audioroute = 1,
324 		},{
325 			.type   = CX88_VMUX_SVIDEO,
326 			.vmux   = 2,
327 			.gpio0  = 0x0000bde6,
328 			.audioroute = 1,
329 		}},
330 		.radio = {
331 			.type   = CX88_RADIO,
332 			.gpio0  = 0x0000bd62,
333 			.audioroute = 1,
334 		},
335 		.mpeg           = CX88_MPEG_BLACKBIRD,
336 	},
337 	[CX88_BOARD_IODATA_GVVCP3PCI] = {
338 		.name		= "IODATA GV-VCP3/PCI",
339 		.tuner_type     = TUNER_ABSENT,
340 		.radio_type     = UNSET,
341 		.tuner_addr	= ADDR_UNSET,
342 		.radio_addr	= ADDR_UNSET,
343 		.input          = {{
344 			.type   = CX88_VMUX_COMPOSITE1,
345 			.vmux   = 0,
346 		},{
347 			.type   = CX88_VMUX_COMPOSITE2,
348 			.vmux   = 1,
349 		},{
350 			.type   = CX88_VMUX_SVIDEO,
351 			.vmux   = 2,
352 		}},
353 	},
354 	[CX88_BOARD_PROLINK_PLAYTVPVR] = {
355 		.name           = "Prolink PlayTV PVR",
356 		.tuner_type     = TUNER_PHILIPS_FM1236_MK3,
357 		.radio_type     = UNSET,
358 		.tuner_addr	= ADDR_UNSET,
359 		.radio_addr	= ADDR_UNSET,
360 		.tda9887_conf	= TDA9887_PRESENT,
361 		.input          = {{
362 			.type   = CX88_VMUX_TELEVISION,
363 			.vmux   = 0,
364 			.gpio0  = 0xbff0,
365 		},{
366 			.type   = CX88_VMUX_COMPOSITE1,
367 			.vmux   = 1,
368 			.gpio0  = 0xbff3,
369 		},{
370 			.type   = CX88_VMUX_SVIDEO,
371 			.vmux   = 2,
372 			.gpio0  = 0xbff3,
373 		}},
374 		.radio = {
375 			.type   = CX88_RADIO,
376 			.gpio0  = 0xbff0,
377 		},
378 	},
379 	[CX88_BOARD_ASUS_PVR_416] = {
380 		.name		= "ASUS PVR-416",
381 		.tuner_type     = TUNER_PHILIPS_FM1236_MK3,
382 		.radio_type     = UNSET,
383 		.tuner_addr	= ADDR_UNSET,
384 		.radio_addr	= ADDR_UNSET,
385 		.tda9887_conf   = TDA9887_PRESENT,
386 		.input          = {{
387 			.type   = CX88_VMUX_TELEVISION,
388 			.vmux   = 0,
389 			.gpio0  = 0x0000fde6,
390 		},{
391 			.type   = CX88_VMUX_SVIDEO,
392 			.vmux   = 2,
393 			.gpio0  = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
394 			.audioroute = 1,
395 		}},
396 		.radio = {
397 			.type   = CX88_RADIO,
398 			.gpio0  = 0x0000fde2,
399 		},
400 		.mpeg           = CX88_MPEG_BLACKBIRD,
401 	},
402 	[CX88_BOARD_MSI_TVANYWHERE] = {
403 		.name           = "MSI TV-@nywhere",
404 		.tuner_type     = TUNER_MT2032,
405 		.radio_type     = UNSET,
406 		.tuner_addr	= ADDR_UNSET,
407 		.radio_addr	= ADDR_UNSET,
408 		.tda9887_conf   = TDA9887_PRESENT,
409 		.input          = {{
410 			.type   = CX88_VMUX_TELEVISION,
411 			.vmux   = 0,
412 			.gpio0  = 0x00000fbf,
413 			.gpio2  = 0x0000fc08,
414 		},{
415 			.type   = CX88_VMUX_COMPOSITE1,
416 			.vmux   = 1,
417 			.gpio0  = 0x00000fbf,
418 			.gpio2  = 0x0000fc68,
419 		},{
420 			.type   = CX88_VMUX_SVIDEO,
421 			.vmux   = 2,
422 			.gpio0  = 0x00000fbf,
423 			.gpio2  = 0x0000fc68,
424 		}},
425 	},
426 	[CX88_BOARD_KWORLD_DVB_T] = {
427 		.name           = "KWorld/VStream XPert DVB-T",
428 		.tuner_type     = TUNER_ABSENT,
429 		.radio_type     = UNSET,
430 		.tuner_addr	= ADDR_UNSET,
431 		.radio_addr	= ADDR_UNSET,
432 		.input          = {{
433 			.type   = CX88_VMUX_COMPOSITE1,
434 			.vmux   = 1,
435 			.gpio0  = 0x0700,
436 			.gpio2  = 0x0101,
437 		},{
438 			.type   = CX88_VMUX_SVIDEO,
439 			.vmux   = 2,
440 			.gpio0  = 0x0700,
441 			.gpio2  = 0x0101,
442 		}},
443 		.mpeg           = CX88_MPEG_DVB,
444 	},
445 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
446 		.name           = "DViCO FusionHDTV DVB-T1",
447 		.tuner_type     = TUNER_ABSENT, /* No analog tuner */
448 		.radio_type     = UNSET,
449 		.tuner_addr	= ADDR_UNSET,
450 		.radio_addr	= ADDR_UNSET,
451 		.input          = {{
452 			.type   = CX88_VMUX_COMPOSITE1,
453 			.vmux   = 1,
454 			.gpio0  = 0x000027df,
455 		},{
456 			.type   = CX88_VMUX_SVIDEO,
457 			.vmux   = 2,
458 			.gpio0  = 0x000027df,
459 		}},
460 		.mpeg           = CX88_MPEG_DVB,
461 	},
462 	[CX88_BOARD_KWORLD_LTV883] = {
463 		.name           = "KWorld LTV883RF",
464 		.tuner_type     = TUNER_TNF_8831BGFF,
465 		.radio_type     = UNSET,
466 		.tuner_addr	= ADDR_UNSET,
467 		.radio_addr	= ADDR_UNSET,
468 		.input          = {{
469 			.type   = CX88_VMUX_TELEVISION,
470 			.vmux   = 0,
471 			.gpio0  = 0x07f8,
472 		},{
473 			.type   = CX88_VMUX_DEBUG,
474 			.vmux   = 0,
475 			.gpio0  = 0x07f9,  // mono from tuner chip
476 		},{
477 			.type   = CX88_VMUX_COMPOSITE1,
478 			.vmux   = 1,
479 			.gpio0  = 0x000007fa,
480 		},{
481 			.type   = CX88_VMUX_SVIDEO,
482 			.vmux   = 2,
483 			.gpio0  = 0x000007fa,
484 		}},
485 		.radio = {
486 			.type   = CX88_RADIO,
487 			.gpio0  = 0x000007f8,
488 		},
489 	},
490 	[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
491 		.name		= "DViCO FusionHDTV 3 Gold-Q",
492 		.tuner_type     = TUNER_MICROTUNE_4042FI5,
493 		.radio_type     = UNSET,
494 		.tuner_addr	= ADDR_UNSET,
495 		.radio_addr	= ADDR_UNSET,
496 		/*
497 		   GPIO[0] resets DT3302 DTV receiver
498 		    0 - reset asserted
499 		    1 - normal operation
500 		   GPIO[1] mutes analog audio output connector
501 		    0 - enable selected source
502 		    1 - mute
503 		   GPIO[2] selects source for analog audio output connector
504 		    0 - analog audio input connector on tab
505 		    1 - analog DAC output from CX23881 chip
506 		   GPIO[3] selects RF input connector on tuner module
507 		    0 - RF connector labeled CABLE
508 		    1 - RF connector labeled ANT
509 		   GPIO[4] selects high RF for QAM256 mode
510 		    0 - normal RF
511 		    1 - high RF
512 		*/
513 		.input          = {{
514 			.type   = CX88_VMUX_TELEVISION,
515 			.vmux   = 0,
516 			.gpio0	= 0x0f0d,
517 		},{
518 			.type   = CX88_VMUX_CABLE,
519 			.vmux   = 0,
520 			.gpio0	= 0x0f05,
521 		},{
522 			.type   = CX88_VMUX_COMPOSITE1,
523 			.vmux   = 1,
524 			.gpio0	= 0x0f00,
525 		},{
526 			.type   = CX88_VMUX_SVIDEO,
527 			.vmux   = 2,
528 			.gpio0	= 0x0f00,
529 		}},
530 		.mpeg           = CX88_MPEG_DVB,
531 	},
532 	[CX88_BOARD_HAUPPAUGE_DVB_T1] = {
533 		.name           = "Hauppauge Nova-T DVB-T",
534 		.tuner_type     = TUNER_ABSENT,
535 		.radio_type     = UNSET,
536 		.tuner_addr	= ADDR_UNSET,
537 		.radio_addr	= ADDR_UNSET,
538 		.input          = {{
539 			.type   = CX88_VMUX_DVB,
540 			.vmux   = 0,
541 		}},
542 		.mpeg           = CX88_MPEG_DVB,
543 	},
544 	[CX88_BOARD_CONEXANT_DVB_T1] = {
545 		.name           = "Conexant DVB-T reference design",
546 		.tuner_type     = TUNER_ABSENT,
547 		.radio_type     = UNSET,
548 		.tuner_addr	= ADDR_UNSET,
549 		.radio_addr	= ADDR_UNSET,
550 		.input          = {{
551 			.type   = CX88_VMUX_DVB,
552 			.vmux   = 0,
553 		}},
554 		.mpeg           = CX88_MPEG_DVB,
555 	},
556 	[CX88_BOARD_PROVIDEO_PV259] = {
557 		.name		= "Provideo PV259",
558 		.tuner_type     = TUNER_PHILIPS_FQ1216ME,
559 		.radio_type     = UNSET,
560 		.tuner_addr	= ADDR_UNSET,
561 		.radio_addr	= ADDR_UNSET,
562 		.input          = {{
563 			.type   = CX88_VMUX_TELEVISION,
564 			.vmux   = 0,
565 			.audioroute = 1,
566 		}},
567 		.mpeg           = CX88_MPEG_BLACKBIRD,
568 	},
569 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
570 		.name           = "DViCO FusionHDTV DVB-T Plus",
571 		.tuner_type     = TUNER_ABSENT, /* No analog tuner */
572 		.radio_type     = UNSET,
573 		.tuner_addr	= ADDR_UNSET,
574 		.radio_addr	= ADDR_UNSET,
575 		.input          = {{
576 			.type   = CX88_VMUX_COMPOSITE1,
577 			.vmux   = 1,
578 			.gpio0  = 0x000027df,
579 		},{
580 			.type   = CX88_VMUX_SVIDEO,
581 			.vmux   = 2,
582 			.gpio0  = 0x000027df,
583 		}},
584 		.mpeg           = CX88_MPEG_DVB,
585 	},
586 	[CX88_BOARD_DNTV_LIVE_DVB_T] = {
587 		.name		= "digitalnow DNTV Live! DVB-T",
588 		.tuner_type     = TUNER_ABSENT,
589 		.radio_type     = UNSET,
590 		.tuner_addr	= ADDR_UNSET,
591 		.radio_addr	= ADDR_UNSET,
592 		.input		= {{
593 			.type   = CX88_VMUX_COMPOSITE1,
594 			.vmux   = 1,
595 			.gpio0  = 0x00000700,
596 			.gpio2  = 0x00000101,
597 		},{
598 			.type   = CX88_VMUX_SVIDEO,
599 			.vmux   = 2,
600 			.gpio0  = 0x00000700,
601 			.gpio2  = 0x00000101,
602 		}},
603 		.mpeg           = CX88_MPEG_DVB,
604 	},
605 	[CX88_BOARD_PCHDTV_HD3000] = {
606 		.name           = "pcHDTV HD3000 HDTV",
607 		.tuner_type     = TUNER_THOMSON_DTT761X,
608 		.radio_type     = UNSET,
609 		.tuner_addr	= ADDR_UNSET,
610 		.radio_addr	= ADDR_UNSET,
611 		.tda9887_conf   = TDA9887_PRESENT,
612 		/* GPIO[2] = audio source for analog audio out connector
613 		 *  0 = analog audio input connector
614 		 *  1 = CX88 audio DACs
615 		 *
616 		 * GPIO[7] = input to CX88's audio/chroma ADC
617 		 *  0 = FM 10.7 MHz IF
618 		 *  1 = Sound 4.5 MHz IF
619 		 *
620 		 * GPIO[1,5,6] = Oren 51132 pins 27,35,28 respectively
621 		 *
622 		 * GPIO[16] = Remote control input
623 		 */
624 		.input          = {{
625 			.type   = CX88_VMUX_TELEVISION,
626 			.vmux   = 0,
627 			.gpio0  = 0x00008484,
628 		},{
629 			.type   = CX88_VMUX_COMPOSITE1,
630 			.vmux   = 1,
631 			.gpio0  = 0x00008400,
632 		},{
633 			.type   = CX88_VMUX_SVIDEO,
634 			.vmux   = 2,
635 			.gpio0  = 0x00008400,
636 		}},
637 		.radio = {
638 			.type   = CX88_RADIO,
639 			.gpio0  = 0x00008404,
640 		},
641 		.mpeg           = CX88_MPEG_DVB,
642 	},
643 	[CX88_BOARD_HAUPPAUGE_ROSLYN] = {
644 		// entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
645 		// GPIO values obtained from regspy, courtesy Sean Covel
646 		.name           = "Hauppauge WinTV 28xxx (Roslyn) models",
647 		.tuner_type     = UNSET,
648 		.radio_type     = UNSET,
649 		.tuner_addr	= ADDR_UNSET,
650 		.radio_addr	= ADDR_UNSET,
651 		.input          = {{
652 			.type   = CX88_VMUX_TELEVISION,
653 			.vmux   = 0,
654 			.gpio0  = 0xed1a,
655 			.gpio2  = 0x00ff,
656 		},{
657 			.type   = CX88_VMUX_DEBUG,
658 			.vmux   = 0,
659 			.gpio0  = 0xff01,
660 		},{
661 			.type   = CX88_VMUX_COMPOSITE1,
662 			.vmux   = 1,
663 			.gpio0  = 0xff02,
664 		},{
665 			.type   = CX88_VMUX_SVIDEO,
666 			.vmux   = 2,
667 			.gpio0  = 0xed92,
668 			.gpio2  = 0x00ff,
669 		}},
670 		.radio = {
671 			 .type   = CX88_RADIO,
672 			 .gpio0  = 0xed96,
673 			 .gpio2  = 0x00ff,
674 		 },
675 		.mpeg           = CX88_MPEG_BLACKBIRD,
676 	},
677 	[CX88_BOARD_DIGITALLOGIC_MEC] = {
678 		.name           = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
679 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
680 		.radio_type     = UNSET,
681 		.tuner_addr	= ADDR_UNSET,
682 		.radio_addr	= ADDR_UNSET,
683 		.tda9887_conf   = TDA9887_PRESENT,
684 		.input          = {{
685 			.type   = CX88_VMUX_TELEVISION,
686 			.vmux   = 0,
687 			.gpio0  = 0x00009d80,
688 			.audioroute = 1,
689 		},{
690 			.type   = CX88_VMUX_COMPOSITE1,
691 			.vmux   = 1,
692 			.gpio0  = 0x00009d76,
693 			.audioroute = 1,
694 		},{
695 			.type   = CX88_VMUX_SVIDEO,
696 			.vmux   = 2,
697 			.gpio0  = 0x00009d76,
698 			.audioroute = 1,
699 		}},
700 		.radio = {
701 			.type   = CX88_RADIO,
702 			.gpio0  = 0x00009d00,
703 			.audioroute = 1,
704 		},
705 		.mpeg           = CX88_MPEG_BLACKBIRD,
706 	},
707 	[CX88_BOARD_IODATA_GVBCTV7E] = {
708 		.name           = "IODATA GV/BCTV7E",
709 		.tuner_type     = TUNER_PHILIPS_FQ1286,
710 		.radio_type     = UNSET,
711 		.tuner_addr	= ADDR_UNSET,
712 		.radio_addr	= ADDR_UNSET,
713 		.tda9887_conf   = TDA9887_PRESENT,
714 		.input          = {{
715 			.type   = CX88_VMUX_TELEVISION,
716 			.vmux   = 1,
717 			.gpio1  = 0x0000e03f,
718 		},{
719 			.type   = CX88_VMUX_COMPOSITE1,
720 			.vmux   = 2,
721 			.gpio1  = 0x0000e07f,
722 		},{
723 			.type   = CX88_VMUX_SVIDEO,
724 			.vmux   = 3,
725 			.gpio1  = 0x0000e07f,
726 		}}
727 	},
728 	[CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = {
729 		.name           = "PixelView PlayTV Ultra Pro (Stereo)",
730 		/* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
731 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
732 		.radio_type     = UNSET,
733 		.tuner_addr	= ADDR_UNSET,
734 		.radio_addr	= ADDR_UNSET,
735 		.input          = {{
736 			.type   = CX88_VMUX_TELEVISION,
737 			.vmux   = 0,
738 			.gpio0  = 0xbf61,  /* internal decoder */
739 		},{
740 			.type   = CX88_VMUX_COMPOSITE1,
741 			.vmux   = 1,
742 			.gpio0	= 0xbf63,
743 		},{
744 			.type   = CX88_VMUX_SVIDEO,
745 			.vmux   = 2,
746 			.gpio0	= 0xbf63,
747 		}},
748 		.radio = {
749 			 .type  = CX88_RADIO,
750 			 .gpio0 = 0xbf60,
751 		 },
752 	},
753 	[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
754 		.name           = "DViCO FusionHDTV 3 Gold-T",
755 		.tuner_type     = TUNER_THOMSON_DTT761X,
756 		.radio_type     = UNSET,
757 		.tuner_addr	= ADDR_UNSET,
758 		.radio_addr	= ADDR_UNSET,
759 		.tda9887_conf   = TDA9887_PRESENT,
760 		.input          = {{
761 			.type   = CX88_VMUX_TELEVISION,
762 			.vmux   = 0,
763 			.gpio0  = 0x97ed,
764 		},{
765 			.type   = CX88_VMUX_COMPOSITE1,
766 			.vmux   = 1,
767 			.gpio0  = 0x97e9,
768 		},{
769 			.type   = CX88_VMUX_SVIDEO,
770 			.vmux   = 2,
771 			.gpio0  = 0x97e9,
772 		}},
773 		.mpeg           = CX88_MPEG_DVB,
774 	},
775 	[CX88_BOARD_ADSTECH_DVB_T_PCI] = {
776 		.name           = "ADS Tech Instant TV DVB-T PCI",
777 		.tuner_type     = TUNER_ABSENT,
778 		.radio_type     = UNSET,
779 		.tuner_addr	= ADDR_UNSET,
780 		.radio_addr	= ADDR_UNSET,
781 		.input          = {{
782 			.type   = CX88_VMUX_COMPOSITE1,
783 			.vmux   = 1,
784 			.gpio0  = 0x0700,
785 			.gpio2  = 0x0101,
786 		},{
787 			.type   = CX88_VMUX_SVIDEO,
788 			.vmux   = 2,
789 			.gpio0  = 0x0700,
790 			.gpio2  = 0x0101,
791 		}},
792 		.mpeg           = CX88_MPEG_DVB,
793 	},
794 	[CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
795 		.name           = "TerraTec Cinergy 1400 DVB-T",
796 		.tuner_type     = TUNER_ABSENT,
797 		.input          = {{
798 			.type   = CX88_VMUX_DVB,
799 			.vmux   = 0,
800 		},{
801 			.type   = CX88_VMUX_COMPOSITE1,
802 			.vmux   = 2,
803 		},{
804 			.type   = CX88_VMUX_SVIDEO,
805 			.vmux   = 2,
806 		}},
807 		.mpeg           = CX88_MPEG_DVB,
808 	},
809 	[CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = {
810 		.name           = "DViCO FusionHDTV 5 Gold",
811 		.tuner_type     = TUNER_LG_TDVS_H06XF, /* TDVS-H062F */
812 		.radio_type     = UNSET,
813 		.tuner_addr	= ADDR_UNSET,
814 		.radio_addr	= ADDR_UNSET,
815 		.tda9887_conf   = TDA9887_PRESENT,
816 		.input          = {{
817 			.type   = CX88_VMUX_TELEVISION,
818 			.vmux   = 0,
819 			.gpio0  = 0x87fd,
820 		},{
821 			.type   = CX88_VMUX_COMPOSITE1,
822 			.vmux   = 1,
823 			.gpio0  = 0x87f9,
824 		},{
825 			.type   = CX88_VMUX_SVIDEO,
826 			.vmux   = 2,
827 			.gpio0  = 0x87f9,
828 		}},
829 		.mpeg           = CX88_MPEG_DVB,
830 	},
831 	[CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
832 		.name           = "AverMedia UltraTV Media Center PCI 550",
833 		.tuner_type     = TUNER_PHILIPS_FM1236_MK3,
834 		.radio_type     = UNSET,
835 		.tuner_addr     = ADDR_UNSET,
836 		.radio_addr     = ADDR_UNSET,
837 		.tda9887_conf   = TDA9887_PRESENT,
838 		.input          = {{
839 			.type   = CX88_VMUX_COMPOSITE1,
840 			.vmux   = 0,
841 			.gpio0  = 0x0000cd73,
842 			.audioroute = 1,
843 		},{
844 			.type   = CX88_VMUX_SVIDEO,
845 			.vmux   = 1,
846 			.gpio0  = 0x0000cd73,
847 			.audioroute = 1,
848 		},{
849 			.type   = CX88_VMUX_TELEVISION,
850 			.vmux   = 3,
851 			.gpio0  = 0x0000cdb3,
852 			.audioroute = 1,
853 		}},
854 		.radio = {
855 			.type   = CX88_RADIO,
856 			.vmux   = 2,
857 			.gpio0  = 0x0000cdf3,
858 			.audioroute = 1,
859 		},
860 		.mpeg           = CX88_MPEG_BLACKBIRD,
861 	},
862 	[CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = {
863 		 /* Alexander Wold <awold@bigfoot.com> */
864 		 .name           = "Kworld V-Stream Xpert DVD",
865 		 .tuner_type     = UNSET,
866 		 .input          = {{
867 			 .type   = CX88_VMUX_COMPOSITE1,
868 			 .vmux   = 1,
869 			 .gpio0  = 0x03000000,
870 			 .gpio1  = 0x01000000,
871 			 .gpio2  = 0x02000000,
872 			 .gpio3  = 0x00100000,
873 		 },{
874 			 .type   = CX88_VMUX_SVIDEO,
875 			 .vmux   = 2,
876 			 .gpio0  = 0x03000000,
877 			 .gpio1  = 0x01000000,
878 			 .gpio2  = 0x02000000,
879 			 .gpio3  = 0x00100000,
880 		 }},
881 	},
882 	[CX88_BOARD_ATI_HDTVWONDER] = {
883 		.name           = "ATI HDTV Wonder",
884 		.tuner_type     = TUNER_PHILIPS_TUV1236D,
885 		.radio_type     = UNSET,
886 		.tuner_addr	= ADDR_UNSET,
887 		.radio_addr	= ADDR_UNSET,
888 		.input          = {{
889 			.type   = CX88_VMUX_TELEVISION,
890 			.vmux   = 0,
891 			.gpio0  = 0x00000ff7,
892 			.gpio1  = 0x000000ff,
893 			.gpio2  = 0x00000001,
894 			.gpio3  = 0x00000000,
895 		},{
896 			.type   = CX88_VMUX_COMPOSITE1,
897 			.vmux   = 1,
898 			.gpio0  = 0x00000ffe,
899 			.gpio1  = 0x000000ff,
900 			.gpio2  = 0x00000001,
901 			.gpio3  = 0x00000000,
902 		},{
903 			.type   = CX88_VMUX_SVIDEO,
904 			.vmux   = 2,
905 			.gpio0  = 0x00000ffe,
906 			.gpio1  = 0x000000ff,
907 			.gpio2  = 0x00000001,
908 			.gpio3  = 0x00000000,
909 		}},
910 		.mpeg           = CX88_MPEG_DVB,
911 	},
912 	[CX88_BOARD_WINFAST_DTV1000] = {
913 		.name           = "WinFast DTV1000-T",
914 		.tuner_type     = TUNER_ABSENT,
915 		.radio_type     = UNSET,
916 		.tuner_addr	= ADDR_UNSET,
917 		.radio_addr	= ADDR_UNSET,
918 		.input          = {{
919 			.type   = CX88_VMUX_DVB,
920 			.vmux   = 0,
921 		},{
922 			.type   = CX88_VMUX_COMPOSITE1,
923 			.vmux   = 1,
924 		},{
925 			.type   = CX88_VMUX_SVIDEO,
926 			.vmux   = 2,
927 		}},
928 		.mpeg           = CX88_MPEG_DVB,
929 	},
930 	[CX88_BOARD_AVERTV_303] = {
931 		.name           = "AVerTV 303 (M126)",
932 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
933 		.radio_type     = UNSET,
934 		.tuner_addr	= ADDR_UNSET,
935 		.radio_addr	= ADDR_UNSET,
936 		.tda9887_conf   = TDA9887_PRESENT,
937 		.input          = {{
938 			.type   = CX88_VMUX_TELEVISION,
939 			.vmux   = 0,
940 			.gpio0  = 0x00ff,
941 			.gpio1  = 0xe09f,
942 			.gpio2  = 0x0010,
943 			.gpio3  = 0x0000,
944 		},{
945 			.type   = CX88_VMUX_COMPOSITE1,
946 			.vmux   = 1,
947 			.gpio0  = 0x00ff,
948 			.gpio1  = 0xe05f,
949 			.gpio2  = 0x0010,
950 			.gpio3  = 0x0000,
951 		},{
952 			.type   = CX88_VMUX_SVIDEO,
953 			.vmux   = 2,
954 			.gpio0  = 0x00ff,
955 			.gpio1  = 0xe05f,
956 			.gpio2  = 0x0010,
957 			.gpio3  = 0x0000,
958 		}},
959 	},
960 	[CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = {
961 		.name		= "Hauppauge Nova-S-Plus DVB-S",
962 		.tuner_type	= TUNER_ABSENT,
963 		.radio_type	= UNSET,
964 		.tuner_addr	= ADDR_UNSET,
965 		.radio_addr	= ADDR_UNSET,
966 		.input		= {{
967 			.type	= CX88_VMUX_DVB,
968 			.vmux	= 0,
969 		},{
970 			.type	= CX88_VMUX_COMPOSITE1,
971 			.vmux	= 1,
972 		},{
973 			.type	= CX88_VMUX_SVIDEO,
974 			.vmux	= 2,
975 		}},
976 		.mpeg           = CX88_MPEG_DVB,
977 	},
978 	[CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = {
979 		.name		= "Hauppauge Nova-SE2 DVB-S",
980 		.tuner_type	= TUNER_ABSENT,
981 		.radio_type	= UNSET,
982 		.tuner_addr	= ADDR_UNSET,
983 		.radio_addr	= ADDR_UNSET,
984 		.input		= {{
985 			.type	= CX88_VMUX_DVB,
986 			.vmux	= 0,
987 		}},
988 		.mpeg           = CX88_MPEG_DVB,
989 	},
990 	[CX88_BOARD_KWORLD_DVBS_100] = {
991 		.name		= "KWorld DVB-S 100",
992 		.tuner_type	= TUNER_ABSENT,
993 		.radio_type	= UNSET,
994 		.tuner_addr	= ADDR_UNSET,
995 		.radio_addr	= ADDR_UNSET,
996 		.input		= {{
997 			.type	= CX88_VMUX_DVB,
998 			.vmux	= 0,
999 		},{
1000 			.type	= CX88_VMUX_COMPOSITE1,
1001 			.vmux	= 1,
1002 		},{
1003 			.type	= CX88_VMUX_SVIDEO,
1004 			.vmux	= 2,
1005 		}},
1006 		.mpeg           = CX88_MPEG_DVB,
1007 	},
1008 	[CX88_BOARD_HAUPPAUGE_HVR1100] = {
1009 		.name		= "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
1010 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1011 		.radio_type	= UNSET,
1012 		.tuner_addr	= ADDR_UNSET,
1013 		.radio_addr	= ADDR_UNSET,
1014 		.tda9887_conf   = TDA9887_PRESENT,
1015 		.input		= {{
1016 			.type   = CX88_VMUX_TELEVISION,
1017 			.vmux   = 0,
1018 		},{
1019 			.type	= CX88_VMUX_COMPOSITE1,
1020 			.vmux	= 1,
1021 		},{
1022 			.type	= CX88_VMUX_SVIDEO,
1023 			.vmux	= 2,
1024 		}},
1025 		/* fixme: Add radio support */
1026 		.mpeg           = CX88_MPEG_DVB,
1027 	},
1028 	[CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
1029 		.name		= "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
1030 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1031 		.radio_type	= UNSET,
1032 		.tuner_addr	= ADDR_UNSET,
1033 		.radio_addr	= ADDR_UNSET,
1034 		.tda9887_conf   = TDA9887_PRESENT,
1035 		.input		= {{
1036 			.type   = CX88_VMUX_TELEVISION,
1037 			.vmux   = 0,
1038 		},{
1039 			.type	= CX88_VMUX_COMPOSITE1,
1040 			.vmux	= 1,
1041 		}},
1042 		/* fixme: Add radio support */
1043 		.mpeg           = CX88_MPEG_DVB,
1044 	},
1045 	[CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
1046 		.name           = "digitalnow DNTV Live! DVB-T Pro",
1047 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1048 		.radio_type     = UNSET,
1049 		.tuner_addr	= ADDR_UNSET,
1050 		.radio_addr	= ADDR_UNSET,
1051 		.tda9887_conf   = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
1052 				  TDA9887_PORT2_ACTIVE,
1053 		.input          = {{
1054 			.type   = CX88_VMUX_TELEVISION,
1055 			.vmux   = 0,
1056 			.gpio0  = 0xf80808,
1057 		},{
1058 			.type   = CX88_VMUX_COMPOSITE1,
1059 			.vmux   = 1,
1060 			.gpio0	= 0xf80808,
1061 		},{
1062 			.type   = CX88_VMUX_SVIDEO,
1063 			.vmux   = 2,
1064 			.gpio0	= 0xf80808,
1065 		}},
1066 		.radio = {
1067 			 .type  = CX88_RADIO,
1068 			 .gpio0 = 0xf80808,
1069 		},
1070 		.mpeg           = CX88_MPEG_DVB,
1071 	},
1072 	[CX88_BOARD_KWORLD_DVB_T_CX22702] = {
1073 		/* Kworld V-stream Xpert DVB-T with Thomson tuner */
1074 		/* DTT 7579 Conexant CX22702-19 Conexant CX2388x  */
1075 		/* Manenti Marco <marco_manenti@colman.it> */
1076 		.name           = "KWorld/VStream XPert DVB-T with cx22702",
1077 		.tuner_type     = TUNER_ABSENT,
1078 		.radio_type     = UNSET,
1079 		.tuner_addr	= ADDR_UNSET,
1080 		.radio_addr	= ADDR_UNSET,
1081 		.input          = {{
1082 			.type   = CX88_VMUX_COMPOSITE1,
1083 			.vmux   = 1,
1084 			.gpio0  = 0x0700,
1085 			.gpio2  = 0x0101,
1086 		},{
1087 			.type   = CX88_VMUX_SVIDEO,
1088 			.vmux   = 2,
1089 			.gpio0  = 0x0700,
1090 			.gpio2  = 0x0101,
1091 		}},
1092 		.mpeg           = CX88_MPEG_DVB,
1093 	},
1094 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = {
1095 		.name           = "DViCO FusionHDTV DVB-T Dual Digital",
1096 		.tuner_type     = TUNER_ABSENT, /* No analog tuner */
1097 		.radio_type     = UNSET,
1098 		.tuner_addr	= ADDR_UNSET,
1099 		.radio_addr	= ADDR_UNSET,
1100 		.input          = {{
1101 			.type   = CX88_VMUX_COMPOSITE1,
1102 			.vmux   = 1,
1103 			.gpio0  = 0x000067df,
1104 		 },{
1105 			.type   = CX88_VMUX_SVIDEO,
1106 			.vmux   = 2,
1107 			.gpio0  = 0x000067df,
1108 		}},
1109 		.mpeg           = CX88_MPEG_DVB,
1110 	},
1111 	[CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
1112 		.name           = "KWorld HardwareMpegTV XPert",
1113 		.tuner_type     = TUNER_PHILIPS_TDA8290,
1114 		.radio_type     = UNSET,
1115 		.tuner_addr	= ADDR_UNSET,
1116 		.radio_addr	= ADDR_UNSET,
1117 		.input          = {{
1118 			.type   = CX88_VMUX_TELEVISION,
1119 			.vmux   = 0,
1120 			.gpio0  = 0x3de2,
1121 			.gpio2  = 0x00ff,
1122 		},{
1123 			.type   = CX88_VMUX_COMPOSITE1,
1124 			.vmux   = 1,
1125 			.gpio0  = 0x3de6,
1126 			.audioroute = 1,
1127 		},{
1128 			.type   = CX88_VMUX_SVIDEO,
1129 			.vmux   = 2,
1130 			.gpio0  = 0x3de6,
1131 			.audioroute = 1,
1132 		}},
1133 		.radio = {
1134 			.type   = CX88_RADIO,
1135 			.gpio0  = 0x3de6,
1136 			.gpio2  = 0x00ff,
1137 		},
1138 		.mpeg           = CX88_MPEG_BLACKBIRD,
1139 	},
1140 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = {
1141 		.name           = "DViCO FusionHDTV DVB-T Hybrid",
1142 		.tuner_type     = TUNER_THOMSON_FE6600,
1143 		.radio_type     = UNSET,
1144 		.tuner_addr	= ADDR_UNSET,
1145 		.radio_addr	= ADDR_UNSET,
1146 		.input          = {{
1147 			.type   = CX88_VMUX_TELEVISION,
1148 			.vmux   = 0,
1149 			.gpio0  = 0x0000a75f,
1150 		},{
1151 			.type   = CX88_VMUX_COMPOSITE1,
1152 			.vmux   = 1,
1153 			.gpio0  = 0x0000a75b,
1154 		},{
1155 			.type   = CX88_VMUX_SVIDEO,
1156 			.vmux   = 2,
1157 			.gpio0  = 0x0000a75b,
1158 		}},
1159 		.mpeg           = CX88_MPEG_DVB,
1160 	},
1161 	[CX88_BOARD_PCHDTV_HD5500] = {
1162 		.name           = "pcHDTV HD5500 HDTV",
1163 		.tuner_type     = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
1164 		.radio_type     = UNSET,
1165 		.tuner_addr	= ADDR_UNSET,
1166 		.radio_addr	= ADDR_UNSET,
1167 		.tda9887_conf   = TDA9887_PRESENT,
1168 		.input          = {{
1169 			.type   = CX88_VMUX_TELEVISION,
1170 			.vmux   = 0,
1171 			.gpio0  = 0x87fd,
1172 		},{
1173 			.type   = CX88_VMUX_COMPOSITE1,
1174 			.vmux   = 1,
1175 			.gpio0  = 0x87f9,
1176 		},{
1177 			.type   = CX88_VMUX_SVIDEO,
1178 			.vmux   = 2,
1179 			.gpio0  = 0x87f9,
1180 		}},
1181 		.mpeg           = CX88_MPEG_DVB,
1182 	},
1183 	[CX88_BOARD_KWORLD_MCE200_DELUXE] = {
1184 		/* FIXME: tested TV input only, disabled composite,
1185 		   svideo and radio until they can be tested also. */
1186 		.name           = "Kworld MCE 200 Deluxe",
1187 		.tuner_type     = TUNER_TENA_9533_DI,
1188 		.radio_type     = UNSET,
1189 		.tda9887_conf   = TDA9887_PRESENT,
1190 		.tuner_addr     = ADDR_UNSET,
1191 		.radio_addr     = ADDR_UNSET,
1192 		.input          = {{
1193 			.type   = CX88_VMUX_TELEVISION,
1194 			.vmux   = 0,
1195 			.gpio0  = 0x0000BDE6
1196 		}},
1197 		.mpeg           = CX88_MPEG_BLACKBIRD,
1198 	},
1199 	[CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = {
1200 		/* FIXME: SVideo, Composite and FM inputs are untested */
1201 		.name           = "PixelView PlayTV P7000",
1202 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
1203 		.radio_type     = UNSET,
1204 		.tuner_addr	= ADDR_UNSET,
1205 		.radio_addr	= ADDR_UNSET,
1206 		.tda9887_conf   = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
1207 				  TDA9887_PORT2_ACTIVE,
1208 		.input          = {{
1209 			.type   = CX88_VMUX_TELEVISION,
1210 			.vmux   = 0,
1211 			.gpio0  = 0x5da6,
1212 		}},
1213 		.mpeg           = CX88_MPEG_BLACKBIRD,
1214 	},
1215 	[CX88_BOARD_NPGTECH_REALTV_TOP10FM] = {
1216 		.name           = "NPG Tech Real TV FM Top 10",
1217 		.tuner_type     = TUNER_TNF_5335MF, /* Actually a TNF9535 */
1218 		.radio_type     = UNSET,
1219 		.tuner_addr	= ADDR_UNSET,
1220 		.radio_addr	= ADDR_UNSET,
1221 		.input          = {{
1222 			.type   = CX88_VMUX_TELEVISION,
1223 			.vmux   = 0,
1224 			.gpio0	= 0x0788,
1225 		},{
1226 			.type   = CX88_VMUX_COMPOSITE1,
1227 			.vmux   = 1,
1228 			.gpio0	= 0x078b,
1229 		},{
1230 			.type   = CX88_VMUX_SVIDEO,
1231 			.vmux   = 2,
1232 			.gpio0	= 0x078b,
1233 		}},
1234 		.radio = {
1235 			 .type  = CX88_RADIO,
1236 			 .gpio0 = 0x074a,
1237 		},
1238 	},
1239 	[CX88_BOARD_WINFAST_DTV2000H] = {
1240 		.name           = "WinFast DTV2000 H",
1241 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1242 		.radio_type     = UNSET,
1243 		.tuner_addr     = ADDR_UNSET,
1244 		.radio_addr     = ADDR_UNSET,
1245 		.tda9887_conf   = TDA9887_PRESENT,
1246 		.input          = {{
1247 			.type   = CX88_VMUX_TELEVISION,
1248 			.vmux   = 0,
1249 			.gpio0  = 0x00017304,
1250 			.gpio1  = 0x00008203,
1251 			.gpio2  = 0x00017304,
1252 			.gpio3  = 0x02000000,
1253 		}, {
1254 			.type   = CX88_VMUX_COMPOSITE1,
1255 			.vmux   = 1,
1256 			.gpio0  = 0x0001d701,
1257 			.gpio1  = 0x0000b207,
1258 			.gpio2  = 0x0001d701,
1259 			.gpio3  = 0x02000000,
1260 		}, {
1261 			.type   = CX88_VMUX_COMPOSITE2,
1262 			.vmux   = 2,
1263 			.gpio0  = 0x0001d503,
1264 			.gpio1  = 0x0000b207,
1265 			.gpio2  = 0x0001d503,
1266 			.gpio3  = 0x02000000,
1267 		}, {
1268 			.type   = CX88_VMUX_SVIDEO,
1269 			.vmux   = 3,
1270 			.gpio0  = 0x0001d701,
1271 			.gpio1  = 0x0000b207,
1272 			.gpio2  = 0x0001d701,
1273 			.gpio3  = 0x02000000,
1274 		}},
1275 		.radio = {
1276 			 .type  = CX88_RADIO,
1277 			 .gpio0 = 0x00015702,
1278 			 .gpio1 = 0x0000f207,
1279 			 .gpio2 = 0x00015702,
1280 			 .gpio3 = 0x02000000,
1281 		},
1282 		.mpeg           = CX88_MPEG_DVB,
1283 	},
1284 	[CX88_BOARD_GENIATECH_DVBS] = {
1285 		.name          = "Geniatech DVB-S",
1286 		.tuner_type    = TUNER_ABSENT,
1287 		.radio_type    = UNSET,
1288 		.tuner_addr    = ADDR_UNSET,
1289 		.radio_addr    = ADDR_UNSET,
1290 		.input  = {{
1291 			.type  = CX88_VMUX_DVB,
1292 			.vmux  = 0,
1293 		},{
1294 			.type  = CX88_VMUX_COMPOSITE1,
1295 			.vmux  = 1,
1296 		}},
1297 		.mpeg           = CX88_MPEG_DVB,
1298 	},
1299 	[CX88_BOARD_HAUPPAUGE_HVR3000] = {
1300 		.name           = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T",
1301 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1302 		.radio_type     = UNSET,
1303 		.tuner_addr     = ADDR_UNSET,
1304 		.radio_addr     = ADDR_UNSET,
1305 		.tda9887_conf   = TDA9887_PRESENT,
1306 		.audio_chip     = V4L2_IDENT_WM8775,
1307 		.input          = {{
1308 			.type   = CX88_VMUX_TELEVISION,
1309 			.vmux   = 0,
1310 			.gpio0  = 0x84bf,
1311 			/* 1: TV Audio / FM Mono */
1312 			.audioroute = 1,
1313 		},{
1314 			.type   = CX88_VMUX_COMPOSITE1,
1315 			.vmux   = 1,
1316 			.gpio0  = 0x84bf,
1317 			/* 2: Line-In */
1318 			.audioroute = 2,
1319 		},{
1320 			.type   = CX88_VMUX_SVIDEO,
1321 			.vmux   = 2,
1322 			.gpio0  = 0x84bf,
1323 			/* 2: Line-In */
1324 			.audioroute = 2,
1325 		}},
1326 		.radio = {
1327 			.type   = CX88_RADIO,
1328 			.gpio0	= 0x84bf,
1329 			/* 4: FM Stereo (untested) */
1330 			.audioroute = 8,
1331 		},
1332 		.mpeg           = CX88_MPEG_DVB,
1333 		.num_frontends	= 2,
1334 	},
1335 	[CX88_BOARD_NORWOOD_MICRO] = {
1336 		.name           = "Norwood Micro TV Tuner",
1337 		.tuner_type     = TUNER_TNF_5335MF,
1338 		.radio_type     = UNSET,
1339 		.tuner_addr     = ADDR_UNSET,
1340 		.radio_addr     = ADDR_UNSET,
1341 		.input          = {{
1342 			.type   = CX88_VMUX_TELEVISION,
1343 			.vmux   = 0,
1344 			.gpio0  = 0x0709,
1345 		},{
1346 			.type   = CX88_VMUX_COMPOSITE1,
1347 			.vmux   = 1,
1348 			.gpio0  = 0x070b,
1349 		},{
1350 			.type   = CX88_VMUX_SVIDEO,
1351 			.vmux   = 2,
1352 			.gpio0  = 0x070b,
1353 		}},
1354 	},
1355 	[CX88_BOARD_TE_DTV_250_OEM_SWANN] = {
1356 		.name           = "Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM",
1357 		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
1358 		.radio_type     = UNSET,
1359 		.tuner_addr     = ADDR_UNSET,
1360 		.radio_addr     = ADDR_UNSET,
1361 		.input          = {{
1362 			.type   = CX88_VMUX_TELEVISION,
1363 			.vmux   = 0,
1364 			.gpio0  = 0x003fffff,
1365 			.gpio1  = 0x00e00000,
1366 			.gpio2  = 0x003fffff,
1367 			.gpio3  = 0x02000000,
1368 		},{
1369 			.type   = CX88_VMUX_COMPOSITE1,
1370 			.vmux   = 1,
1371 			.gpio0  = 0x003fffff,
1372 			.gpio1  = 0x00e00000,
1373 			.gpio2  = 0x003fffff,
1374 			.gpio3  = 0x02000000,
1375 		},{
1376 			.type   = CX88_VMUX_SVIDEO,
1377 			.vmux   = 2,
1378 			.gpio0  = 0x003fffff,
1379 			.gpio1  = 0x00e00000,
1380 			.gpio2  = 0x003fffff,
1381 			.gpio3  = 0x02000000,
1382 		}},
1383 	},
1384 	[CX88_BOARD_HAUPPAUGE_HVR1300] = {
1385 		.name		= "Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder",
1386 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1387 		.radio_type	= UNSET,
1388 		.tuner_addr	= ADDR_UNSET,
1389 		.radio_addr	= ADDR_UNSET,
1390 		.tda9887_conf   = TDA9887_PRESENT,
1391 		.audio_chip     = V4L2_IDENT_WM8775,
1392 		/*
1393 		 * gpio0 as reported by Mike Crash <mike AT mikecrash.com>
1394 		 */
1395 		.input		= {{
1396 			.type   = CX88_VMUX_TELEVISION,
1397 			.vmux   = 0,
1398 			.gpio0	= 0xef88,
1399 			/* 1: TV Audio / FM Mono */
1400 			.audioroute = 1,
1401 		},{
1402 			.type	= CX88_VMUX_COMPOSITE1,
1403 			.vmux	= 1,
1404 			.gpio0	= 0xef88,
1405 			/* 2: Line-In */
1406 			.audioroute = 2,
1407 		},{
1408 			.type	= CX88_VMUX_SVIDEO,
1409 			.vmux	= 2,
1410 			.gpio0	= 0xef88,
1411 			/* 2: Line-In */
1412 			.audioroute = 2,
1413 		}},
1414 		.mpeg           = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
1415 		.radio = {
1416 			.type   = CX88_RADIO,
1417 			.gpio0	= 0xef88,
1418 			/* 4: FM Stereo (untested) */
1419 			.audioroute = 8,
1420 		},
1421 	},
1422 	[CX88_BOARD_ADSTECH_PTV_390] = {
1423 		.name           = "ADS Tech Instant Video PCI",
1424 		.tuner_type     = TUNER_ABSENT,
1425 		.radio_type     = UNSET,
1426 		.tuner_addr     = ADDR_UNSET,
1427 		.radio_addr     = ADDR_UNSET,
1428 		.input          = {{
1429 			.type   = CX88_VMUX_DEBUG,
1430 			.vmux   = 3,
1431 			.gpio0  = 0x04ff,
1432 		},{
1433 			.type   = CX88_VMUX_COMPOSITE1,
1434 			.vmux   = 1,
1435 			.gpio0  = 0x07fa,
1436 		},{
1437 			.type   = CX88_VMUX_SVIDEO,
1438 			.vmux   = 2,
1439 			.gpio0  = 0x07fa,
1440 		}},
1441 	},
1442 	[CX88_BOARD_PINNACLE_PCTV_HD_800i] = {
1443 		.name           = "Pinnacle PCTV HD 800i",
1444 		.tuner_type     = TUNER_XC5000,
1445 		.radio_type     = UNSET,
1446 		.tuner_addr	= ADDR_UNSET,
1447 		.radio_addr	= ADDR_UNSET,
1448 		.input          = {{
1449 			.type   = CX88_VMUX_TELEVISION,
1450 			.vmux   = 0,
1451 			.gpio0  = 0x04fb,
1452 			.gpio1  = 0x10ff,
1453 		},{
1454 			.type   = CX88_VMUX_COMPOSITE1,
1455 			.vmux   = 1,
1456 			.gpio0  = 0x04fb,
1457 			.gpio1  = 0x10ef,
1458 			.audioroute = 1,
1459 		},{
1460 			.type   = CX88_VMUX_SVIDEO,
1461 			.vmux   = 2,
1462 			.gpio0  = 0x04fb,
1463 			.gpio1  = 0x10ef,
1464 			.audioroute = 1,
1465 		}},
1466 		.mpeg           = CX88_MPEG_DVB,
1467 	},
1468 	[CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO] = {
1469 		.name           = "DViCO FusionHDTV 5 PCI nano",
1470 		/* xc3008 tuner, digital only for now */
1471 		.tuner_type     = TUNER_ABSENT,
1472 		.radio_type     = UNSET,
1473 		.tuner_addr	= ADDR_UNSET,
1474 		.radio_addr	= ADDR_UNSET,
1475 		.input          = {{
1476 			.type   = CX88_VMUX_TELEVISION,
1477 			.vmux   = 0,
1478 			.gpio0  = 0x000027df, /* Unconfirmed */
1479 		}, {
1480 			.type   = CX88_VMUX_COMPOSITE1,
1481 			.vmux   = 1,
1482 			.gpio0  = 0x000027df, /* Unconfirmed */
1483 			.audioroute = 1,
1484 		}, {
1485 			.type   = CX88_VMUX_SVIDEO,
1486 			.vmux   = 2,
1487 			.gpio0  = 0x000027df, /* Unconfirmed */
1488 			.audioroute = 1,
1489 		} },
1490 		.mpeg           = CX88_MPEG_DVB,
1491 	},
1492 	[CX88_BOARD_PINNACLE_HYBRID_PCTV] = {
1493 		.name           = "Pinnacle Hybrid PCTV",
1494 		.tuner_type     = TUNER_XC2028,
1495 		.tuner_addr     = 0x61,
1496 		.radio_type     = TUNER_XC2028,
1497 		.radio_addr     = 0x61,
1498 		.input          = { {
1499 			.type   = CX88_VMUX_TELEVISION,
1500 			.vmux   = 0,
1501 			.gpio0  = 0x004ff,
1502 			.gpio1  = 0x010ff,
1503 			.gpio2  = 0x00001,
1504 		}, {
1505 			.type   = CX88_VMUX_COMPOSITE1,
1506 			.vmux   = 1,
1507 			.gpio0  = 0x004fb,
1508 			.gpio1  = 0x010ef,
1509 			.audioroute = 1,
1510 		}, {
1511 			.type   = CX88_VMUX_SVIDEO,
1512 			.vmux   = 2,
1513 			.gpio0  = 0x004fb,
1514 			.gpio1  = 0x010ef,
1515 			.audioroute = 1,
1516 		} },
1517 		.radio = {
1518 			.type   = CX88_RADIO,
1519 			.gpio0  = 0x004ff,
1520 			.gpio1  = 0x010ff,
1521 			.gpio2  = 0x0ff,
1522 		},
1523 		.mpeg           = CX88_MPEG_DVB,
1524 	},
1525 	[CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = {
1526 		.name           = "Winfast TV2000 XP Global",
1527 		.tuner_type     = TUNER_XC2028,
1528 		.tuner_addr     = 0x61,
1529 		.input          = { {
1530 			.type   = CX88_VMUX_TELEVISION,
1531 			.vmux   = 0,
1532 			.gpio0  = 0x0400, /* pin 2:mute = 0 (off?) */
1533 			.gpio1  = 0x0000,
1534 			.gpio2  = 0x0800, /* pin 19:audio = 0 (tv) */
1535 
1536 		}, {
1537 			.type   = CX88_VMUX_COMPOSITE1,
1538 			.vmux   = 1,
1539 			.gpio0  = 0x0400, /* probably?  or 0x0404 to turn mute on */
1540 			.gpio1  = 0x0000,
1541 			.gpio2  = 0x0808, /* pin 19:audio = 1 (line) */
1542 
1543 		}, {
1544 			.type   = CX88_VMUX_SVIDEO,
1545 			.vmux   = 2,
1546 		} },
1547 		.radio = {
1548 			.type   = CX88_RADIO,
1549 			.gpio0  = 0x004ff,
1550 			.gpio1  = 0x010ff,
1551 			.gpio2  = 0x0ff,
1552 		},
1553 	},
1554 	[CX88_BOARD_POWERCOLOR_REAL_ANGEL] = {
1555 		.name           = "PowerColor RA330",	/* Long names may confuse LIRC. */
1556 		.tuner_type     = TUNER_XC2028,
1557 		.tuner_addr     = 0x61,
1558 		.input          = { {
1559 			.type   = CX88_VMUX_DEBUG,
1560 			.vmux   = 3,		/* Due to the way the cx88 driver is written,	*/
1561 			.gpio0 = 0x00ff,	/* there is no way to deactivate audio pass-	*/
1562 			.gpio1 = 0xf39d,	/* through without this entry. Furthermore, if	*/
1563 			.gpio3 = 0x0000,	/* the TV mux entry is first, you get audio	*/
1564 		}, {				/* from the tuner on boot for a little while.	*/
1565 			.type   = CX88_VMUX_TELEVISION,
1566 			.vmux   = 0,
1567 			.gpio0 = 0x00ff,
1568 			.gpio1 = 0xf35d,
1569 			.gpio3 = 0x0000,
1570 		}, {
1571 			.type   = CX88_VMUX_COMPOSITE1,
1572 			.vmux   = 1,
1573 			.gpio0 = 0x00ff,
1574 			.gpio1 = 0xf37d,
1575 			.gpio3 = 0x0000,
1576 		}, {
1577 			.type   = CX88_VMUX_SVIDEO,
1578 			.vmux   = 2,
1579 			.gpio0  = 0x000ff,
1580 			.gpio1  = 0x0f37d,
1581 			.gpio3  = 0x00000,
1582 		} },
1583 		.radio = {
1584 			.type   = CX88_RADIO,
1585 			.gpio0  = 0x000ff,
1586 			.gpio1  = 0x0f35d,
1587 			.gpio3  = 0x00000,
1588 		},
1589 	},
1590 	[CX88_BOARD_GENIATECH_X8000_MT] = {
1591 		/* Also PowerColor Real Angel 330 and Geniatech X800 OEM */
1592 		.name           = "Geniatech X8000-MT DVBT",
1593 		.tuner_type     = TUNER_XC2028,
1594 		.tuner_addr     = 0x61,
1595 		.input          = { {
1596 			.type   = CX88_VMUX_TELEVISION,
1597 			.vmux   = 0,
1598 			.gpio0  = 0x00000000,
1599 			.gpio1  = 0x00e3e341,
1600 			.gpio2  = 0x00000000,
1601 			.gpio3  = 0x00000000,
1602 		}, {
1603 			.type   = CX88_VMUX_COMPOSITE1,
1604 			.vmux   = 1,
1605 			.gpio0  = 0x00000000,
1606 			.gpio1  = 0x00e3e361,
1607 			.gpio2  = 0x00000000,
1608 			.gpio3  = 0x00000000,
1609 		}, {
1610 			.type   = CX88_VMUX_SVIDEO,
1611 			.vmux   = 2,
1612 			.gpio0  = 0x00000000,
1613 			.gpio1  = 0x00e3e361,
1614 			.gpio2  = 0x00000000,
1615 			.gpio3  = 0x00000000,
1616 		} },
1617 		.radio = {
1618 			.type   = CX88_RADIO,
1619 			.gpio0  = 0x00000000,
1620 			.gpio1  = 0x00e3e341,
1621 			.gpio2  = 0x00000000,
1622 			.gpio3  = 0x00000000,
1623 		},
1624 		.mpeg           = CX88_MPEG_DVB,
1625 	},
1626 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO] = {
1627 		.name           = "DViCO FusionHDTV DVB-T PRO",
1628 		.tuner_type     = TUNER_XC2028,
1629 		.tuner_addr     = 0x61,
1630 		.radio_type     = UNSET,
1631 		.radio_addr     = ADDR_UNSET,
1632 		.input          = { {
1633 			.type   = CX88_VMUX_COMPOSITE1,
1634 			.vmux   = 1,
1635 			.gpio0  = 0x000067df,
1636 		}, {
1637 			.type   = CX88_VMUX_SVIDEO,
1638 			.vmux   = 2,
1639 			.gpio0  = 0x000067df,
1640 		} },
1641 		.mpeg           = CX88_MPEG_DVB,
1642 	},
1643 	[CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD] = {
1644 		.name           = "DViCO FusionHDTV 7 Gold",
1645 		.tuner_type     = TUNER_XC5000,
1646 		.radio_type     = UNSET,
1647 		.tuner_addr	= ADDR_UNSET,
1648 		.radio_addr	= ADDR_UNSET,
1649 		.input          = {{
1650 			.type   = CX88_VMUX_TELEVISION,
1651 			.vmux   = 0,
1652 			.gpio0  = 0x10df,
1653 		},{
1654 			.type   = CX88_VMUX_COMPOSITE1,
1655 			.vmux   = 1,
1656 			.gpio0  = 0x16d9,
1657 		},{
1658 			.type   = CX88_VMUX_SVIDEO,
1659 			.vmux   = 2,
1660 			.gpio0  = 0x16d9,
1661 		}},
1662 		.mpeg           = CX88_MPEG_DVB,
1663 	},
1664 	[CX88_BOARD_PROLINK_PV_8000GT] = {
1665 		.name           = "Prolink Pixelview MPEG 8000GT",
1666 		.tuner_type     = TUNER_XC2028,
1667 		.tuner_addr     = 0x61,
1668 		.input          = { {
1669 			.type   = CX88_VMUX_TELEVISION,
1670 			.vmux   = 0,
1671 			.gpio0 = 0x0ff,
1672 			.gpio2 = 0x0cfb,
1673 		}, {
1674 			.type   = CX88_VMUX_COMPOSITE1,
1675 			.vmux   = 1,
1676 			.gpio2 = 0x0cfb,
1677 		}, {
1678 			.type   = CX88_VMUX_SVIDEO,
1679 			.vmux   = 2,
1680 			.gpio2 = 0x0cfb,
1681 		} },
1682 		.radio = {
1683 			.type   = CX88_RADIO,
1684 			.gpio2 = 0x0cfb,
1685 		},
1686 	},
1687 	[CX88_BOARD_PROLINK_PV_GLOBAL_XTREME] = {
1688 		.name           = "Prolink Pixelview Global Extreme",
1689 		.tuner_type     = TUNER_XC2028,
1690 		.tuner_addr     = 0x61,
1691 		.input          = { {
1692 			.type   = CX88_VMUX_TELEVISION,
1693 			.vmux   = 0,
1694 			.gpio0 = 0x04fb,
1695 			.gpio1 = 0x04080,
1696 			.gpio2 = 0x0cf7,
1697 		}, {
1698 			.type   = CX88_VMUX_COMPOSITE1,
1699 			.vmux   = 1,
1700 			.gpio0 = 0x04fb,
1701 			.gpio1 = 0x04080,
1702 			.gpio2 = 0x0cfb,
1703 		}, {
1704 			.type   = CX88_VMUX_SVIDEO,
1705 			.vmux   = 2,
1706 			.gpio0 = 0x04fb,
1707 			.gpio1 = 0x04080,
1708 			.gpio2 = 0x0cfb,
1709 		} },
1710 		.radio = {
1711 			.type   = CX88_RADIO,
1712 			.gpio0 = 0x04ff,
1713 			.gpio1 = 0x04080,
1714 			.gpio2 = 0x0cf7,
1715 		},
1716 	},
1717 	/* Both radio, analog and ATSC work with this board.
1718 	   However, for analog to work, s5h1409 gate should be open,
1719 	   otherwise, tuner-xc3028 won't be detected.
1720 	   A proper fix require using the newer i2c methods to add
1721 	   tuner-xc3028 without doing an i2c probe.
1722 	 */
1723 	[CX88_BOARD_KWORLD_ATSC_120] = {
1724 		.name           = "Kworld PlusTV HD PCI 120 (ATSC 120)",
1725 		.tuner_type     = TUNER_XC2028,
1726 		.radio_type     = UNSET,
1727 		.tuner_addr	= ADDR_UNSET,
1728 		.radio_addr	= ADDR_UNSET,
1729 		.input          = { {
1730 			.type   = CX88_VMUX_TELEVISION,
1731 			.vmux   = 0,
1732 			.gpio0  = 0x000000ff,
1733 			.gpio1  = 0x0000f35d,
1734 			.gpio2  = 0x00000000,
1735 		}, {
1736 			.type   = CX88_VMUX_COMPOSITE1,
1737 			.vmux   = 1,
1738 			.gpio0  = 0x000000ff,
1739 			.gpio1  = 0x0000f37e,
1740 			.gpio2  = 0x00000000,
1741 		}, {
1742 			.type   = CX88_VMUX_SVIDEO,
1743 			.vmux   = 2,
1744 			.gpio0  = 0x000000ff,
1745 			.gpio1  = 0x0000f37e,
1746 			.gpio2  = 0x00000000,
1747 		} },
1748 		.radio = {
1749 			.type   = CX88_RADIO,
1750 			.gpio0  = 0x000000ff,
1751 			.gpio1  = 0x0000f35d,
1752 			.gpio2  = 0x00000000,
1753 		},
1754 		.mpeg           = CX88_MPEG_DVB,
1755 	},
1756 	[CX88_BOARD_HAUPPAUGE_HVR4000] = {
1757 		.name           = "Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid",
1758 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1759 		.radio_type     = UNSET,
1760 		.tuner_addr     = ADDR_UNSET,
1761 		.radio_addr     = ADDR_UNSET,
1762 		.tda9887_conf   = TDA9887_PRESENT,
1763 		.audio_chip     = V4L2_IDENT_WM8775,
1764 		/*
1765 		 * GPIO0 (WINTV2000)
1766 		 *
1767 		 * Analogue     SAT     DVB-T
1768 		 * Antenna      0xc4bf  0xc4bb
1769 		 * Composite    0xc4bf  0xc4bb
1770 		 * S-Video      0xc4bf  0xc4bb
1771 		 * Composite1   0xc4ff  0xc4fb
1772 		 * S-Video1     0xc4ff  0xc4fb
1773 		 *
1774 		 * BIT  VALUE   FUNCTION GP{x}_IO
1775 		 * 0    1       I:?
1776 		 * 1    1       I:?
1777 		 * 2    1       O:MPEG PORT 0=DVB-T 1=DVB-S
1778 		 * 3    1       I:?
1779 		 * 4    1       I:?
1780 		 * 5    1       I:?
1781 		 * 6    0       O:INPUT SELECTOR 0=INTERNAL 1=EXPANSION
1782 		 * 7    1       O:DVB-T DEMOD RESET LOW
1783 		 *
1784 		 * BIT  VALUE   FUNCTION GP{x}_OE
1785 		 * 8    0       I
1786 		 * 9    0       I
1787 		 * a    1       O
1788 		 * b    0       I
1789 		 * c    0       I
1790 		 * d    0       I
1791 		 * e    1       O
1792 		 * f    1       O
1793 		 *
1794 		 * WM8775 ADC
1795 		 *
1796 		 * 1: TV Audio / FM Mono
1797 		 * 2: Line-In
1798 		 * 3: Line-In Expansion
1799 		 * 4: FM Stereo
1800 		 */
1801 		.input          = {{
1802 			.type   = CX88_VMUX_TELEVISION,
1803 			.vmux   = 0,
1804 			.gpio0  = 0xc4bf,
1805 			/* 1: TV Audio / FM Mono */
1806 			.audioroute = 1,
1807 		}, {
1808 			.type   = CX88_VMUX_COMPOSITE1,
1809 			.vmux   = 1,
1810 			.gpio0  = 0xc4bf,
1811 			/* 2: Line-In */
1812 			.audioroute = 2,
1813 		}, {
1814 			.type   = CX88_VMUX_SVIDEO,
1815 			.vmux   = 2,
1816 			.gpio0  = 0xc4bf,
1817 			/* 2: Line-In */
1818 			.audioroute = 2,
1819 		} },
1820 		.radio = {
1821 			.type   = CX88_RADIO,
1822 			.gpio0	= 0xc4bf,
1823 			/* 4: FM Stereo */
1824 			.audioroute = 8,
1825 		},
1826 		.mpeg           = CX88_MPEG_DVB,
1827 		.num_frontends	= 2,
1828 	},
1829 	[CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
1830 		.name           = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
1831 		.tuner_type     = UNSET,
1832 		.radio_type     = UNSET,
1833 		.tuner_addr     = ADDR_UNSET,
1834 		.radio_addr     = ADDR_UNSET,
1835 		.input          = {{
1836 			.type   = CX88_VMUX_DVB,
1837 			.vmux   = 0,
1838 		} },
1839 		.mpeg           = CX88_MPEG_DVB,
1840 	},
1841 	[CX88_BOARD_TEVII_S420] = {
1842 		.name           = "TeVii S420 DVB-S",
1843 		.tuner_type     = UNSET,
1844 		.radio_type     = UNSET,
1845 		.tuner_addr     = ADDR_UNSET,
1846 		.radio_addr     = ADDR_UNSET,
1847 		.input          = {{
1848 			.type   = CX88_VMUX_DVB,
1849 			.vmux   = 0,
1850 		} },
1851 		.mpeg           = CX88_MPEG_DVB,
1852 	},
1853 	[CX88_BOARD_TEVII_S460] = {
1854 		.name           = "TeVii S460 DVB-S/S2",
1855 		.tuner_type     = UNSET,
1856 		.radio_type     = UNSET,
1857 		.tuner_addr     = ADDR_UNSET,
1858 		.radio_addr     = ADDR_UNSET,
1859 		.input          = {{
1860 			.type   = CX88_VMUX_DVB,
1861 			.vmux   = 0,
1862 		} },
1863 		.mpeg           = CX88_MPEG_DVB,
1864 	},
1865 	[CX88_BOARD_OMICOM_SS4_PCI] = {
1866 		.name           = "Omicom SS4 DVB-S/S2 PCI",
1867 		.tuner_type     = UNSET,
1868 		.radio_type     = UNSET,
1869 		.tuner_addr     = ADDR_UNSET,
1870 		.radio_addr     = ADDR_UNSET,
1871 		.input          = {{
1872 			.type   = CX88_VMUX_DVB,
1873 			.vmux   = 0,
1874 		} },
1875 		.mpeg           = CX88_MPEG_DVB,
1876 	},
1877 	[CX88_BOARD_TBS_8910] = {
1878 		.name           = "TBS 8910 DVB-S",
1879 		.tuner_type     = UNSET,
1880 		.radio_type     = UNSET,
1881 		.tuner_addr     = ADDR_UNSET,
1882 		.radio_addr     = ADDR_UNSET,
1883 		.input          = {{
1884 			.type   = CX88_VMUX_DVB,
1885 			.vmux   = 0,
1886 		} },
1887 		.mpeg           = CX88_MPEG_DVB,
1888 	},
1889 	[CX88_BOARD_TBS_8920] = {
1890 		.name           = "TBS 8920 DVB-S/S2",
1891 		.tuner_type     = TUNER_ABSENT,
1892 		.radio_type     = UNSET,
1893 		.tuner_addr     = ADDR_UNSET,
1894 		.radio_addr     = ADDR_UNSET,
1895 		.input          = {{
1896 			.type   = CX88_VMUX_DVB,
1897 			.vmux   = 1,
1898 		} },
1899 		.mpeg           = CX88_MPEG_DVB,
1900 	},
1901 	[CX88_BOARD_PROF_6200] = {
1902 		.name           = "Prof 6200 DVB-S",
1903 		.tuner_type     = UNSET,
1904 		.radio_type     = UNSET,
1905 		.tuner_addr     = ADDR_UNSET,
1906 		.radio_addr     = ADDR_UNSET,
1907 		.input          = {{
1908 			.type   = CX88_VMUX_DVB,
1909 			.vmux   = 0,
1910 		} },
1911 		.mpeg           = CX88_MPEG_DVB,
1912 	},
1913 	[CX88_BOARD_PROF_7300] = {
1914 		.name           = "PROF 7300 DVB-S/S2",
1915 		.tuner_type     = UNSET,
1916 		.radio_type     = UNSET,
1917 		.tuner_addr     = ADDR_UNSET,
1918 		.radio_addr     = ADDR_UNSET,
1919 		.input          = {{
1920 			.type   = CX88_VMUX_DVB,
1921 			.vmux   = 0,
1922 		} },
1923 		.mpeg           = CX88_MPEG_DVB,
1924 	},
1925 	[CX88_BOARD_SATTRADE_ST4200] = {
1926 		.name           = "SATTRADE ST4200 DVB-S/S2",
1927 		.tuner_type     = UNSET,
1928 		.radio_type     = UNSET,
1929 		.tuner_addr     = ADDR_UNSET,
1930 		.radio_addr     = ADDR_UNSET,
1931 		.input          = {{
1932 			.type   = CX88_VMUX_DVB,
1933 			.vmux   = 0,
1934 		} },
1935 		.mpeg           = CX88_MPEG_DVB,
1936 	},
1937 };
1938 
1939 /* ------------------------------------------------------------------ */
1940 /* PCI subsystem IDs                                                  */
1941 
1942 static const struct cx88_subid cx88_subids[] = {
1943 	{
1944 		.subvendor = 0x0070,
1945 		.subdevice = 0x3400,
1946 		.card      = CX88_BOARD_HAUPPAUGE,
1947 	},{
1948 		.subvendor = 0x0070,
1949 		.subdevice = 0x3401,
1950 		.card      = CX88_BOARD_HAUPPAUGE,
1951 	},{
1952 		.subvendor = 0x14c7,
1953 		.subdevice = 0x0106,
1954 		.card      = CX88_BOARD_GDI,
1955 	},{
1956 		.subvendor = 0x14c7,
1957 		.subdevice = 0x0107, /* with mpeg encoder */
1958 		.card      = CX88_BOARD_GDI,
1959 	},{
1960 		.subvendor = PCI_VENDOR_ID_ATI,
1961 		.subdevice = 0x00f8,
1962 		.card      = CX88_BOARD_ATI_WONDER_PRO,
1963 	}, {
1964 		.subvendor = PCI_VENDOR_ID_ATI,
1965 		.subdevice = 0x00f9,
1966 		.card      = CX88_BOARD_ATI_WONDER_PRO,
1967 	}, {
1968 		.subvendor = 0x107d,
1969 		.subdevice = 0x6611,
1970 		.card      = CX88_BOARD_WINFAST2000XP_EXPERT,
1971 	},{
1972 		.subvendor = 0x107d,
1973 		.subdevice = 0x6613,	/* NTSC */
1974 		.card      = CX88_BOARD_WINFAST2000XP_EXPERT,
1975 	},{
1976 		.subvendor = 0x107d,
1977 		.subdevice = 0x6620,
1978 		.card      = CX88_BOARD_WINFAST_DV2000,
1979 	},{
1980 		.subvendor = 0x107d,
1981 		.subdevice = 0x663b,
1982 		.card      = CX88_BOARD_LEADTEK_PVR2000,
1983 	},{
1984 		.subvendor = 0x107d,
1985 		.subdevice = 0x663c,
1986 		.card      = CX88_BOARD_LEADTEK_PVR2000,
1987 	},{
1988 		.subvendor = 0x1461,
1989 		.subdevice = 0x000b,
1990 		.card      = CX88_BOARD_AVERTV_STUDIO_303,
1991 	},{
1992 		.subvendor = 0x1462,
1993 		.subdevice = 0x8606,
1994 		.card      = CX88_BOARD_MSI_TVANYWHERE_MASTER,
1995 	},{
1996 		.subvendor = 0x10fc,
1997 		.subdevice = 0xd003,
1998 		.card      = CX88_BOARD_IODATA_GVVCP3PCI,
1999 	},{
2000 		.subvendor = 0x1043,
2001 		.subdevice = 0x4823,  /* with mpeg encoder */
2002 		.card      = CX88_BOARD_ASUS_PVR_416,
2003 	},{
2004 		.subvendor = 0x17de,
2005 		.subdevice = 0x08a6,
2006 		.card      = CX88_BOARD_KWORLD_DVB_T,
2007 	},{
2008 		.subvendor = 0x18ac,
2009 		.subdevice = 0xd810,
2010 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
2011 	},{
2012 		.subvendor = 0x18ac,
2013 		.subdevice = 0xd820,
2014 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
2015 	},{
2016 		.subvendor = 0x18ac,
2017 		.subdevice = 0xdb00,
2018 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
2019 	},{
2020 		.subvendor = 0x0070,
2021 		.subdevice = 0x9002,
2022 		.card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
2023 	},{
2024 		.subvendor = 0x14f1,
2025 		.subdevice = 0x0187,
2026 		.card      = CX88_BOARD_CONEXANT_DVB_T1,
2027 	},{
2028 		.subvendor = 0x1540,
2029 		.subdevice = 0x2580,
2030 		.card      = CX88_BOARD_PROVIDEO_PV259,
2031 	},{
2032 		.subvendor = 0x18ac,
2033 		.subdevice = 0xdb10,
2034 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
2035 	},{
2036 		.subvendor = 0x1554,
2037 		.subdevice = 0x4811,
2038 		.card      = CX88_BOARD_PIXELVIEW,
2039 	},{
2040 		.subvendor = 0x7063,
2041 		.subdevice = 0x3000, /* HD-3000 card */
2042 		.card      = CX88_BOARD_PCHDTV_HD3000,
2043 	},{
2044 		.subvendor = 0x17de,
2045 		.subdevice = 0xa8a6,
2046 		.card      = CX88_BOARD_DNTV_LIVE_DVB_T,
2047 	},{
2048 		.subvendor = 0x0070,
2049 		.subdevice = 0x2801,
2050 		.card      = CX88_BOARD_HAUPPAUGE_ROSLYN,
2051 	},{
2052 		.subvendor = 0x14f1,
2053 		.subdevice = 0x0342,
2054 		.card      = CX88_BOARD_DIGITALLOGIC_MEC,
2055 	},{
2056 		.subvendor = 0x10fc,
2057 		.subdevice = 0xd035,
2058 		.card      = CX88_BOARD_IODATA_GVBCTV7E,
2059 	},{
2060 		.subvendor = 0x1421,
2061 		.subdevice = 0x0334,
2062 		.card      = CX88_BOARD_ADSTECH_DVB_T_PCI,
2063 	},{
2064 		.subvendor = 0x153b,
2065 		.subdevice = 0x1166,
2066 		.card      = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
2067 	},{
2068 		.subvendor = 0x18ac,
2069 		.subdevice = 0xd500,
2070 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
2071 	},{
2072 		.subvendor = 0x1461,
2073 		.subdevice = 0x8011,
2074 		.card      = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
2075 	},{
2076 		.subvendor = PCI_VENDOR_ID_ATI,
2077 		.subdevice = 0xa101,
2078 		.card      = CX88_BOARD_ATI_HDTVWONDER,
2079 	},{
2080 		.subvendor = 0x107d,
2081 		.subdevice = 0x665f,
2082 		.card      = CX88_BOARD_WINFAST_DTV1000,
2083 	},{
2084 		.subvendor = 0x1461,
2085 		.subdevice = 0x000a,
2086 		.card      = CX88_BOARD_AVERTV_303,
2087 	},{
2088 		.subvendor = 0x0070,
2089 		.subdevice = 0x9200,
2090 		.card      = CX88_BOARD_HAUPPAUGE_NOVASE2_S1,
2091 	},{
2092 		.subvendor = 0x0070,
2093 		.subdevice = 0x9201,
2094 		.card      = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
2095 	},{
2096 		.subvendor = 0x0070,
2097 		.subdevice = 0x9202,
2098 		.card      = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
2099 	},{
2100 		.subvendor = 0x17de,
2101 		.subdevice = 0x08b2,
2102 		.card      = CX88_BOARD_KWORLD_DVBS_100,
2103 	},{
2104 		.subvendor = 0x0070,
2105 		.subdevice = 0x9400,
2106 		.card      = CX88_BOARD_HAUPPAUGE_HVR1100,
2107 	},{
2108 		.subvendor = 0x0070,
2109 		.subdevice = 0x9402,
2110 		.card      = CX88_BOARD_HAUPPAUGE_HVR1100,
2111 	},{
2112 		.subvendor = 0x0070,
2113 		.subdevice = 0x9800,
2114 		.card      = CX88_BOARD_HAUPPAUGE_HVR1100LP,
2115 	},{
2116 		.subvendor = 0x0070,
2117 		.subdevice = 0x9802,
2118 		.card      = CX88_BOARD_HAUPPAUGE_HVR1100LP,
2119 	},{
2120 		.subvendor = 0x0070,
2121 		.subdevice = 0x9001,
2122 		.card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
2123 	},{
2124 		.subvendor = 0x1822,
2125 		.subdevice = 0x0025,
2126 		.card      = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
2127 	},{
2128 		.subvendor = 0x17de,
2129 		.subdevice = 0x08a1,
2130 		.card      = CX88_BOARD_KWORLD_DVB_T_CX22702,
2131 	},{
2132 		.subvendor = 0x18ac,
2133 		.subdevice = 0xdb50,
2134 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
2135 	},{
2136 		.subvendor = 0x18ac,
2137 		.subdevice = 0xdb54,
2138 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
2139 		/* Re-branded DViCO: DigitalNow DVB-T Dual */
2140 	},{
2141 		.subvendor = 0x18ac,
2142 		.subdevice = 0xdb11,
2143 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
2144 		/* Re-branded DViCO: UltraView DVB-T Plus */
2145 	}, {
2146 		.subvendor = 0x18ac,
2147 		.subdevice = 0xdb30,
2148 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO,
2149 	}, {
2150 		.subvendor = 0x17de,
2151 		.subdevice = 0x0840,
2152 		.card      = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
2153 	},{
2154 		.subvendor = 0x1421,
2155 		.subdevice = 0x0305,
2156 		.card      = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
2157 	},{
2158 		.subvendor = 0x18ac,
2159 		.subdevice = 0xdb40,
2160 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
2161 	},{
2162 		.subvendor = 0x18ac,
2163 		.subdevice = 0xdb44,
2164 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
2165 	},{
2166 		.subvendor = 0x7063,
2167 		.subdevice = 0x5500,
2168 		.card      = CX88_BOARD_PCHDTV_HD5500,
2169 	},{
2170 		.subvendor = 0x17de,
2171 		.subdevice = 0x0841,
2172 		.card      = CX88_BOARD_KWORLD_MCE200_DELUXE,
2173 	},{
2174 		.subvendor = 0x1822,
2175 		.subdevice = 0x0019,
2176 		.card      = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
2177 	},{
2178 		.subvendor = 0x1554,
2179 		.subdevice = 0x4813,
2180 		.card      = CX88_BOARD_PIXELVIEW_PLAYTV_P7000,
2181 	},{
2182 		.subvendor = 0x14f1,
2183 		.subdevice = 0x0842,
2184 		.card      = CX88_BOARD_NPGTECH_REALTV_TOP10FM,
2185 	},{
2186 		.subvendor = 0x107d,
2187 		.subdevice = 0x665e,
2188 		.card      = CX88_BOARD_WINFAST_DTV2000H,
2189 	},{
2190 		.subvendor = 0x18ac,
2191 		.subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */
2192 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
2193 	},{
2194 		.subvendor = 0x14f1,
2195 		.subdevice = 0x0084,
2196 		.card      = CX88_BOARD_GENIATECH_DVBS,
2197 	},{
2198 		.subvendor = 0x0070,
2199 		.subdevice = 0x1404,
2200 		.card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2201 	},{
2202 		.subvendor = 0x1461,
2203 		.subdevice = 0xc111, /* AverMedia M150-D */
2204 		/* This board is known to work with the ASUS PVR416 config */
2205 		.card      = CX88_BOARD_ASUS_PVR_416,
2206 	},{
2207 		.subvendor = 0xc180,
2208 		.subdevice = 0xc980,
2209 		.card      = CX88_BOARD_TE_DTV_250_OEM_SWANN,
2210 	},{
2211 		.subvendor = 0x0070,
2212 		.subdevice = 0x9600,
2213 		.card      = CX88_BOARD_HAUPPAUGE_HVR1300,
2214 	},{
2215 		.subvendor = 0x0070,
2216 		.subdevice = 0x9601,
2217 		.card      = CX88_BOARD_HAUPPAUGE_HVR1300,
2218 	},{
2219 		.subvendor = 0x0070,
2220 		.subdevice = 0x9602,
2221 		.card      = CX88_BOARD_HAUPPAUGE_HVR1300,
2222 	},{
2223 		.subvendor = 0x107d,
2224 		.subdevice = 0x6632,
2225 		.card      = CX88_BOARD_LEADTEK_PVR2000,
2226 	},{
2227 		.subvendor = 0x12ab,
2228 		.subdevice = 0x2300, /* Club3D Zap TV2100 */
2229 		.card      = CX88_BOARD_KWORLD_DVB_T_CX22702,
2230 	},{
2231 		.subvendor = 0x0070,
2232 		.subdevice = 0x9000,
2233 		.card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
2234 	},{
2235 		.subvendor = 0x0070,
2236 		.subdevice = 0x1400,
2237 		.card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2238 	},{
2239 		.subvendor = 0x0070,
2240 		.subdevice = 0x1401,
2241 		.card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2242 	},{
2243 		.subvendor = 0x0070,
2244 		.subdevice = 0x1402,
2245 		.card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2246 	},{
2247 		.subvendor = 0x1421,
2248 		.subdevice = 0x0341, /* ADS Tech InstantTV DVB-S */
2249 		.card      = CX88_BOARD_KWORLD_DVBS_100,
2250 	},{
2251 		.subvendor = 0x1421,
2252 		.subdevice = 0x0390,
2253 		.card      = CX88_BOARD_ADSTECH_PTV_390,
2254 	},{
2255 		.subvendor = 0x11bd,
2256 		.subdevice = 0x0051,
2257 		.card      = CX88_BOARD_PINNACLE_PCTV_HD_800i,
2258 	}, {
2259 		.subvendor = 0x18ac,
2260 		.subdevice = 0xd530,
2261 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO,
2262 	}, {
2263 		.subvendor = 0x12ab,
2264 		.subdevice = 0x1788,
2265 		.card      = CX88_BOARD_PINNACLE_HYBRID_PCTV,
2266 	}, {
2267 		.subvendor = 0x14f1,
2268 		.subdevice = 0xea3d,
2269 		.card      = CX88_BOARD_POWERCOLOR_REAL_ANGEL,
2270 	}, {
2271 		.subvendor = 0x107d,
2272 		.subdevice = 0x6f18,
2273 		.card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
2274 	}, {
2275 		.subvendor = 0x14f1,
2276 		.subdevice = 0x8852,
2277 		.card      = CX88_BOARD_GENIATECH_X8000_MT,
2278 	}, {
2279 		.subvendor = 0x18ac,
2280 		.subdevice = 0xd610,
2281 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD,
2282 	}, {
2283 		.subvendor = 0x1554,
2284 		.subdevice = 0x4935,
2285 		.card      = CX88_BOARD_PROLINK_PV_8000GT,
2286 	}, {
2287 		.subvendor = 0x1554,
2288 		.subdevice = 0x4976,
2289 		.card      = CX88_BOARD_PROLINK_PV_GLOBAL_XTREME,
2290 	}, {
2291 		.subvendor = 0x17de,
2292 		.subdevice = 0x08c1,
2293 		.card      = CX88_BOARD_KWORLD_ATSC_120,
2294 	}, {
2295 		.subvendor = 0x0070,
2296 		.subdevice = 0x6900,
2297 		.card      = CX88_BOARD_HAUPPAUGE_HVR4000,
2298 	}, {
2299 		.subvendor = 0x0070,
2300 		.subdevice = 0x6904,
2301 		.card      = CX88_BOARD_HAUPPAUGE_HVR4000,
2302 	}, {
2303 		.subvendor = 0x0070,
2304 		.subdevice = 0x6902,
2305 		.card      = CX88_BOARD_HAUPPAUGE_HVR4000,
2306 	}, {
2307 		.subvendor = 0x0070,
2308 		.subdevice = 0x6905,
2309 		.card      = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
2310 	}, {
2311 		.subvendor = 0x0070,
2312 		.subdevice = 0x6906,
2313 		.card      = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
2314 	}, {
2315 		.subvendor = 0xd420,
2316 		.subdevice = 0x9022,
2317 		.card      = CX88_BOARD_TEVII_S420,
2318 	}, {
2319 		.subvendor = 0xd460,
2320 		.subdevice = 0x9022,
2321 		.card      = CX88_BOARD_TEVII_S460,
2322 	}, {
2323 		.subvendor = 0xA044,
2324 		.subdevice = 0x2011,
2325 		.card      = CX88_BOARD_OMICOM_SS4_PCI,
2326 	}, {
2327 		.subvendor = 0x8910,
2328 		.subdevice = 0x8888,
2329 		.card      = CX88_BOARD_TBS_8910,
2330 	}, {
2331 		.subvendor = 0x8920,
2332 		.subdevice = 0x8888,
2333 		.card      = CX88_BOARD_TBS_8920,
2334 	}, {
2335 		.subvendor = 0xb022,
2336 		.subdevice = 0x3022,
2337 		.card      = CX88_BOARD_PROF_6200,
2338 	}, {
2339 		.subvendor = 0xB033,
2340 		.subdevice = 0x3033,
2341 		.card      = CX88_BOARD_PROF_7300,
2342 	}, {
2343 		.subvendor = 0xb200,
2344 		.subdevice = 0x4200,
2345 		.card      = CX88_BOARD_SATTRADE_ST4200,
2346 	},
2347 };
2348 
2349 /* ----------------------------------------------------------------------- */
2350 /* some leadtek specific stuff                                             */
2351 
leadtek_eeprom(struct cx88_core * core,u8 * eeprom_data)2352 static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
2353 {
2354 	/* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on
2355 	 * any others.
2356 	 *
2357 	 * Byte 0 is 1 on the NTSC board.
2358 	 */
2359 
2360 	if (eeprom_data[4] != 0x7d ||
2361 	    eeprom_data[5] != 0x10 ||
2362 	    eeprom_data[7] != 0x66) {
2363 		warn_printk(core, "Leadtek eeprom invalid.\n");
2364 		return;
2365 	}
2366 
2367 	core->board.tuner_type = (eeprom_data[6] == 0x13) ?
2368 		TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3;
2369 
2370 	info_printk(core, "Leadtek Winfast 2000XP Expert config: "
2371 		    "tuner=%d, eeprom[0]=0x%02x\n",
2372 		    core->board.tuner_type, eeprom_data[0]);
2373 }
2374 
hauppauge_eeprom(struct cx88_core * core,u8 * eeprom_data)2375 static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2376 {
2377 	struct tveeprom tv;
2378 
2379 	tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
2380 	core->board.tuner_type = tv.tuner_type;
2381 	core->tuner_formats = tv.tuner_formats;
2382 	core->board.radio.type = tv.has_radio ? CX88_RADIO : 0;
2383 
2384 	/* Make sure we support the board model */
2385 	switch (tv.model)
2386 	{
2387 	case 14009: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in) */
2388 	case 14019: /* WinTV-HVR3000 (Retail, IR Blaster, b/panel video, 3.5mm audio in) */
2389 	case 14029: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge) */
2390 	case 14109: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - low profile) */
2391 	case 14129: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge - LP) */
2392 	case 14559: /* WinTV-HVR3000 (OEM, no IR, b/panel video, 3.5mm audio in) */
2393 	case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */
2394 	case 14659: /* WinTV-HVR3000 (OEM, no IR, b/panel video, RCA audio in - Low profile) */
2395 	case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */
2396 	case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
2397 	case 34519: /* WinTV-PCI-FM */
2398 	case 69009:
2399 		/* WinTV-HVR4000 (DVBS/S2/T, Video and IR, back panel inputs) */
2400 	case 69100: /* WinTV-HVR4000LITE (DVBS/S2, IR) */
2401 	case 69500: /* WinTV-HVR4000LITE (DVBS/S2, No IR) */
2402 	case 69559:
2403 		/* WinTV-HVR4000 (DVBS/S2/T, Video no IR, back panel inputs) */
2404 	case 69569: /* WinTV-HVR4000 (DVBS/S2/T, Video no IR) */
2405 	case 90002: /* Nova-T-PCI (9002) */
2406 	case 92001: /* Nova-S-Plus (Video and IR) */
2407 	case 92002: /* Nova-S-Plus (Video and IR) */
2408 	case 90003: /* Nova-T-PCI (9002 No RF out) */
2409 	case 90500: /* Nova-T-PCI (oem) */
2410 	case 90501: /* Nova-T-PCI (oem/IR) */
2411 	case 92000: /* Nova-SE2 (OEM, No Video or IR) */
2412 	case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
2413 	case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
2414 	case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
2415 	case 96019: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX/TX) */
2416 	case 96559: /* WinTV-HVR1300 (PAL Video, MPEG Video no IR) */
2417 	case 96569: /* WinTV-HVR1300 () */
2418 	case 96659: /* WinTV-HVR1300 () */
2419 	case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
2420 		/* known */
2421 		break;
2422 	default:
2423 		warn_printk(core, "warning: unknown hauppauge model #%d\n",
2424 			    tv.model);
2425 		break;
2426 	}
2427 
2428 	info_printk(core, "hauppauge eeprom: model=%d\n", tv.model);
2429 }
2430 
2431 /* ----------------------------------------------------------------------- */
2432 /* some GDI (was: Modular Technology) specific stuff                       */
2433 
2434 static struct {
2435 	int  id;
2436 	int  fm;
2437 	char *name;
2438 } gdi_tuner[] = {
2439 	[ 0x01 ] = { .id   = TUNER_ABSENT,
2440 		     .name = "NTSC_M" },
2441 	[ 0x02 ] = { .id   = TUNER_ABSENT,
2442 		     .name = "PAL_B" },
2443 	[ 0x03 ] = { .id   = TUNER_ABSENT,
2444 		     .name = "PAL_I" },
2445 	[ 0x04 ] = { .id   = TUNER_ABSENT,
2446 		     .name = "PAL_D" },
2447 	[ 0x05 ] = { .id   = TUNER_ABSENT,
2448 		     .name = "SECAM" },
2449 
2450 	[ 0x10 ] = { .id   = TUNER_ABSENT,
2451 		     .fm   = 1,
2452 		     .name = "TEMIC_4049" },
2453 	[ 0x11 ] = { .id   = TUNER_TEMIC_4136FY5,
2454 		     .name = "TEMIC_4136" },
2455 	[ 0x12 ] = { .id   = TUNER_ABSENT,
2456 		     .name = "TEMIC_4146" },
2457 
2458 	[ 0x20 ] = { .id   = TUNER_PHILIPS_FQ1216ME,
2459 		     .fm   = 1,
2460 		     .name = "PHILIPS_FQ1216_MK3" },
2461 	[ 0x21 ] = { .id   = TUNER_ABSENT, .fm = 1,
2462 		     .name = "PHILIPS_FQ1236_MK3" },
2463 	[ 0x22 ] = { .id   = TUNER_ABSENT,
2464 		     .name = "PHILIPS_FI1236_MK3" },
2465 	[ 0x23 ] = { .id   = TUNER_ABSENT,
2466 		     .name = "PHILIPS_FI1216_MK3" },
2467 };
2468 
gdi_eeprom(struct cx88_core * core,u8 * eeprom_data)2469 static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
2470 {
2471 	char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
2472 		? gdi_tuner[eeprom_data[0x0d]].name : NULL;
2473 
2474 	info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown");
2475 	if (NULL == name)
2476 		return;
2477 	core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
2478 	core->board.radio.type = gdi_tuner[eeprom_data[0x0d]].fm ?
2479 		CX88_RADIO : 0;
2480 }
2481 
2482 /* ------------------------------------------------------------------- */
2483 /* some Divco specific stuff                                           */
cx88_dvico_xc2028_callback(struct cx88_core * core,int command,int arg)2484 static int cx88_dvico_xc2028_callback(struct cx88_core *core,
2485 				      int command, int arg)
2486 {
2487 	switch (command) {
2488 	case XC2028_TUNER_RESET:
2489 		switch (core->boardnr) {
2490 		case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2491 			/* GPIO-4 xc3028 tuner */
2492 
2493 			cx_set(MO_GP0_IO, 0x00001000);
2494 			cx_clear(MO_GP0_IO, 0x00000010);
2495 			msleep(100);
2496 			cx_set(MO_GP0_IO, 0x00000010);
2497 			msleep(100);
2498 			break;
2499 		default:
2500 			cx_write(MO_GP0_IO, 0x101000);
2501 			mdelay(5);
2502 			cx_set(MO_GP0_IO, 0x101010);
2503 		}
2504 		break;
2505 	default:
2506 		return -EINVAL;
2507 	}
2508 
2509 	return 0;
2510 }
2511 
2512 
2513 /* ----------------------------------------------------------------------- */
2514 /* some Geniatech specific stuff                                           */
2515 
cx88_xc3028_geniatech_tuner_callback(struct cx88_core * core,int command,int mode)2516 static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core,
2517 						int command, int mode)
2518 {
2519 	switch (command) {
2520 	case XC2028_TUNER_RESET:
2521 		switch (INPUT(core->input).type) {
2522 		case CX88_RADIO:
2523 			break;
2524 		case CX88_VMUX_DVB:
2525 			cx_write(MO_GP1_IO, 0x030302);
2526 			mdelay(50);
2527 			break;
2528 		default:
2529 			cx_write(MO_GP1_IO, 0x030301);
2530 			mdelay(50);
2531 		}
2532 		cx_write(MO_GP1_IO, 0x101010);
2533 		mdelay(50);
2534 		cx_write(MO_GP1_IO, 0x101000);
2535 		mdelay(50);
2536 		cx_write(MO_GP1_IO, 0x101010);
2537 		mdelay(50);
2538 		return 0;
2539 	}
2540 	return -EINVAL;
2541 }
2542 
2543 /* ------------------------------------------------------------------- */
2544 /* some Divco specific stuff                                           */
cx88_pv_8000gt_callback(struct cx88_core * core,int command,int arg)2545 static int cx88_pv_8000gt_callback(struct cx88_core *core,
2546 				   int command, int arg)
2547 {
2548 	switch (command) {
2549 	case XC2028_TUNER_RESET:
2550 		cx_write(MO_GP2_IO, 0xcf7);
2551 		mdelay(50);
2552 		cx_write(MO_GP2_IO, 0xef5);
2553 		mdelay(50);
2554 		cx_write(MO_GP2_IO, 0xcf7);
2555 		break;
2556 	default:
2557 		return -EINVAL;
2558 	}
2559 
2560 	return 0;
2561 }
2562 
2563 /* ----------------------------------------------------------------------- */
2564 /* some DViCO specific stuff                                               */
2565 
dvico_fusionhdtv_hybrid_init(struct cx88_core * core)2566 static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
2567 {
2568 	struct i2c_msg msg = { .addr = 0x45, .flags = 0 };
2569 	int i, err;
2570 	static u8 init_bufs[13][5] = {
2571 		{ 0x10, 0x00, 0x20, 0x01, 0x03 },
2572 		{ 0x10, 0x10, 0x01, 0x00, 0x21 },
2573 		{ 0x10, 0x10, 0x10, 0x00, 0xCA },
2574 		{ 0x10, 0x10, 0x12, 0x00, 0x08 },
2575 		{ 0x10, 0x10, 0x13, 0x00, 0x0A },
2576 		{ 0x10, 0x10, 0x16, 0x01, 0xC0 },
2577 		{ 0x10, 0x10, 0x22, 0x01, 0x3D },
2578 		{ 0x10, 0x10, 0x73, 0x01, 0x2E },
2579 		{ 0x10, 0x10, 0x72, 0x00, 0xC5 },
2580 		{ 0x10, 0x10, 0x71, 0x01, 0x97 },
2581 		{ 0x10, 0x10, 0x70, 0x00, 0x0F },
2582 		{ 0x10, 0x10, 0xB0, 0x00, 0x01 },
2583 		{ 0x03, 0x0C },
2584 	};
2585 
2586 	for (i = 0; i < ARRAY_SIZE(init_bufs); i++) {
2587 		msg.buf = init_bufs[i];
2588 		msg.len = (i != 12 ? 5 : 2);
2589 		err = i2c_transfer(&core->i2c_adap, &msg, 1);
2590 		if (err != 1) {
2591 			warn_printk(core, "dvico_fusionhdtv_hybrid_init buf %d "
2592 					  "failed (err = %d)!\n", i, err);
2593 			return;
2594 		}
2595 	}
2596 }
2597 
cx88_xc2028_tuner_callback(struct cx88_core * core,int command,int arg)2598 static int cx88_xc2028_tuner_callback(struct cx88_core *core,
2599 				      int command, int arg)
2600 {
2601 	/* Board-specific callbacks */
2602 	switch (core->boardnr) {
2603 	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
2604 	case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
2605 	case CX88_BOARD_GENIATECH_X8000_MT:
2606 	case CX88_BOARD_KWORLD_ATSC_120:
2607 		return cx88_xc3028_geniatech_tuner_callback(core,
2608 							command, arg);
2609 	case CX88_BOARD_PROLINK_PV_8000GT:
2610 	case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
2611 		return cx88_pv_8000gt_callback(core, command, arg);
2612 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2613 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2614 		return cx88_dvico_xc2028_callback(core, command, arg);
2615 	}
2616 
2617 	switch (command) {
2618 	case XC2028_TUNER_RESET:
2619 		switch (INPUT(core->input).type) {
2620 		case CX88_RADIO:
2621 			info_printk(core, "setting GPIO to radio!\n");
2622 			cx_write(MO_GP0_IO, 0x4ff);
2623 			mdelay(250);
2624 			cx_write(MO_GP2_IO, 0xff);
2625 			mdelay(250);
2626 			break;
2627 		case CX88_VMUX_DVB:	/* Digital TV*/
2628 		default:		/* Analog TV */
2629 			info_printk(core, "setting GPIO to TV!\n");
2630 			break;
2631 		}
2632 		cx_write(MO_GP1_IO, 0x101010);
2633 		mdelay(250);
2634 		cx_write(MO_GP1_IO, 0x101000);
2635 		mdelay(250);
2636 		cx_write(MO_GP1_IO, 0x101010);
2637 		mdelay(250);
2638 		return 0;
2639 	}
2640 	return -EINVAL;
2641 }
2642 
2643 /* ----------------------------------------------------------------------- */
2644 /* Tuner callback function. Currently only needed for the Pinnacle 	   *
2645  * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both	   *
2646  * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c)    */
2647 
cx88_xc5000_tuner_callback(struct cx88_core * core,int command,int arg)2648 static int cx88_xc5000_tuner_callback(struct cx88_core *core,
2649 				      int command, int arg)
2650 {
2651 	switch (core->boardnr) {
2652 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
2653 		if (command == 0) { /* This is the reset command from xc5000 */
2654 			/* Reset XC5000 tuner via SYS_RSTO_pin */
2655 			cx_write(MO_SRST_IO, 0);
2656 			msleep(10);
2657 			cx_write(MO_SRST_IO, 1);
2658 			return 0;
2659 		} else {
2660 			err_printk(core, "xc5000: unknown tuner "
2661 				   "callback command.\n");
2662 			return -EINVAL;
2663 		}
2664 		break;
2665 	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
2666 		if (command == 0) { /* This is the reset command from xc5000 */
2667 			cx_clear(MO_GP0_IO, 0x00000010);
2668 			msleep(10);
2669 			cx_set(MO_GP0_IO, 0x00000010);
2670 			return 0;
2671 		} else {
2672 			printk(KERN_ERR
2673 				"xc5000: unknown tuner callback command.\n");
2674 			return -EINVAL;
2675 		}
2676 		break;
2677 	}
2678 	return 0; /* Should never be here */
2679 }
2680 
cx88_tuner_callback(void * priv,int component,int command,int arg)2681 int cx88_tuner_callback(void *priv, int component, int command, int arg)
2682 {
2683 	struct i2c_algo_bit_data *i2c_algo = priv;
2684 	struct cx88_core *core;
2685 
2686 	if (!i2c_algo) {
2687 		printk(KERN_ERR "cx88: Error - i2c private data undefined.\n");
2688 		return -EINVAL;
2689 	}
2690 
2691 	core = i2c_algo->data;
2692 
2693 	if (!core) {
2694 		printk(KERN_ERR "cx88: Error - device struct undefined.\n");
2695 		return -EINVAL;
2696 	}
2697 
2698 	if (component != DVB_FRONTEND_COMPONENT_TUNER)
2699 		return -EINVAL;
2700 
2701 	switch (core->board.tuner_type) {
2702 		case TUNER_XC2028:
2703 			info_printk(core, "Calling XC2028/3028 callback\n");
2704 			return cx88_xc2028_tuner_callback(core, command, arg);
2705 		case TUNER_XC5000:
2706 			info_printk(core, "Calling XC5000 callback\n");
2707 			return cx88_xc5000_tuner_callback(core, command, arg);
2708 	}
2709 	err_printk(core, "Error: Calling callback for tuner %d\n",
2710 		   core->board.tuner_type);
2711 	return -EINVAL;
2712 }
2713 EXPORT_SYMBOL(cx88_tuner_callback);
2714 
2715 /* ----------------------------------------------------------------------- */
2716 
cx88_card_list(struct cx88_core * core,struct pci_dev * pci)2717 static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
2718 {
2719 	int i;
2720 
2721 	if (0 == pci->subsystem_vendor &&
2722 	    0 == pci->subsystem_device) {
2723 		printk(KERN_ERR
2724 		       "%s: Your board has no valid PCI Subsystem ID and thus can't\n"
2725 		       "%s: be autodetected.  Please pass card=<n> insmod option to\n"
2726 		       "%s: workaround that.  Redirect complaints to the vendor of\n"
2727 		       "%s: the TV card.  Best regards,\n"
2728 		       "%s:         -- tux\n",
2729 		       core->name,core->name,core->name,core->name,core->name);
2730 	} else {
2731 		printk(KERN_ERR
2732 		       "%s: Your board isn't known (yet) to the driver.  You can\n"
2733 		       "%s: try to pick one of the existing card configs via\n"
2734 		       "%s: card=<n> insmod option.  Updating to the latest\n"
2735 		       "%s: version might help as well.\n",
2736 		       core->name,core->name,core->name,core->name);
2737 	}
2738 	err_printk(core, "Here is a list of valid choices for the card=<n> "
2739 		   "insmod option:\n");
2740 	for (i = 0; i < ARRAY_SIZE(cx88_boards); i++)
2741 		printk(KERN_ERR "%s:    card=%d -> %s\n",
2742 		       core->name, i, cx88_boards[i].name);
2743 }
2744 
cx88_card_setup_pre_i2c(struct cx88_core * core)2745 static void cx88_card_setup_pre_i2c(struct cx88_core *core)
2746 {
2747 	switch (core->boardnr) {
2748 	case CX88_BOARD_HAUPPAUGE_HVR1300:
2749 		/*
2750 		 * Bring the 702 demod up before i2c scanning/attach or devices are hidden
2751 		 * We leave here with the 702 on the bus
2752 		 *
2753 		 * "reset the IR receiver on GPIO[3]"
2754 		 * Reported by Mike Crash <mike AT mikecrash.com>
2755 		 */
2756 		cx_write(MO_GP0_IO, 0x0000ef88);
2757 		udelay(1000);
2758 		cx_clear(MO_GP0_IO, 0x00000088);
2759 		udelay(50);
2760 		cx_set(MO_GP0_IO, 0x00000088); /* 702 out of reset */
2761 		udelay(1000);
2762 		break;
2763 
2764 	case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
2765 	case CX88_BOARD_PROLINK_PV_8000GT:
2766 		cx_write(MO_GP2_IO, 0xcf7);
2767 		mdelay(50);
2768 		cx_write(MO_GP2_IO, 0xef5);
2769 		mdelay(50);
2770 		cx_write(MO_GP2_IO, 0xcf7);
2771 		msleep(10);
2772 		break;
2773 
2774 	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
2775 		/* Enable the xc5000 tuner */
2776 		cx_set(MO_GP0_IO, 0x00001010);
2777 		break;
2778 
2779 	case CX88_BOARD_HAUPPAUGE_HVR3000:
2780 	case CX88_BOARD_HAUPPAUGE_HVR4000:
2781 		/* Init GPIO */
2782 		cx_write(MO_GP0_IO, core->board.input[0].gpio0);
2783 		udelay(1000);
2784 		cx_clear(MO_GP0_IO, 0x00000080);
2785 		udelay(50);
2786 		cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
2787 		udelay(1000);
2788 		break;
2789 	}
2790 }
2791 
2792 /*
2793  * Sets board-dependent xc3028 configuration
2794  */
cx88_setup_xc3028(struct cx88_core * core,struct xc2028_ctrl * ctl)2795 void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
2796 {
2797 	memset(ctl, 0, sizeof(*ctl));
2798 
2799 	ctl->fname   = XC2028_DEFAULT_FIRMWARE;
2800 	ctl->max_len = 64;
2801 
2802 	switch (core->boardnr) {
2803 	case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
2804 		/* Now works with firmware version 2.7 */
2805 		if (core->i2c_algo.udelay < 16)
2806 			core->i2c_algo.udelay = 16;
2807 		break;
2808 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2809 		ctl->demod = XC3028_FE_ZARLINK456;
2810 		break;
2811 	case CX88_BOARD_KWORLD_ATSC_120:
2812 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2813 		ctl->demod = XC3028_FE_OREN538;
2814 		break;
2815 	case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
2816 	case CX88_BOARD_PROLINK_PV_8000GT:
2817 		/*
2818 		 * Those boards uses non-MTS firmware
2819 		 */
2820 		break;
2821 	case CX88_BOARD_PINNACLE_HYBRID_PCTV:
2822 		ctl->demod = XC3028_FE_ZARLINK456;
2823 		ctl->mts = 1;
2824 		break;
2825 	default:
2826 		ctl->demod = XC3028_FE_OREN538;
2827 		ctl->mts = 1;
2828 	}
2829 }
2830 EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
2831 
cx88_card_setup(struct cx88_core * core)2832 static void cx88_card_setup(struct cx88_core *core)
2833 {
2834 	static u8 eeprom[256];
2835 	struct tuner_setup tun_setup;
2836 	unsigned int mode_mask = T_RADIO     |
2837 				 T_ANALOG_TV |
2838 				 T_DIGITAL_TV;
2839 
2840 	memset(&tun_setup, 0, sizeof(tun_setup));
2841 
2842 	if (0 == core->i2c_rc) {
2843 		core->i2c_client.addr = 0xa0 >> 1;
2844 		tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom));
2845 	}
2846 
2847 	switch (core->boardnr) {
2848 	case CX88_BOARD_HAUPPAUGE:
2849 	case CX88_BOARD_HAUPPAUGE_ROSLYN:
2850 		if (0 == core->i2c_rc)
2851 			hauppauge_eeprom(core, eeprom+8);
2852 		break;
2853 	case CX88_BOARD_GDI:
2854 		if (0 == core->i2c_rc)
2855 			gdi_eeprom(core, eeprom);
2856 		break;
2857 	case CX88_BOARD_WINFAST2000XP_EXPERT:
2858 		if (0 == core->i2c_rc)
2859 			leadtek_eeprom(core, eeprom);
2860 		break;
2861 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
2862 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
2863 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
2864 	case CX88_BOARD_HAUPPAUGE_HVR1100:
2865 	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
2866 	case CX88_BOARD_HAUPPAUGE_HVR3000:
2867 	case CX88_BOARD_HAUPPAUGE_HVR1300:
2868 	case CX88_BOARD_HAUPPAUGE_HVR4000:
2869 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
2870 		if (0 == core->i2c_rc)
2871 			hauppauge_eeprom(core, eeprom);
2872 		break;
2873 	case CX88_BOARD_KWORLD_DVBS_100:
2874 		cx_write(MO_GP0_IO, 0x000007f8);
2875 		cx_write(MO_GP1_IO, 0x00000001);
2876 		break;
2877 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2878 		/* GPIO0:0 is hooked to demod reset */
2879 		/* GPIO0:4 is hooked to xc3028 reset */
2880 		cx_write(MO_GP0_IO, 0x00111100);
2881 		msleep(1);
2882 		cx_write(MO_GP0_IO, 0x00111111);
2883 		break;
2884 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
2885 		/* GPIO0:6 is hooked to FX2 reset pin */
2886 		cx_set(MO_GP0_IO, 0x00004040);
2887 		cx_clear(MO_GP0_IO, 0x00000040);
2888 		msleep(1000);
2889 		cx_set(MO_GP0_IO, 0x00004040);
2890 		/* FALLTHROUGH */
2891 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
2892 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
2893 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
2894 		/* GPIO0:0 is hooked to mt352 reset pin */
2895 		cx_set(MO_GP0_IO, 0x00000101);
2896 		cx_clear(MO_GP0_IO, 0x00000001);
2897 		msleep(1);
2898 		cx_set(MO_GP0_IO, 0x00000101);
2899 		if (0 == core->i2c_rc &&
2900 		    core->boardnr == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
2901 			dvico_fusionhdtv_hybrid_init(core);
2902 		break;
2903 	case CX88_BOARD_KWORLD_DVB_T:
2904 	case CX88_BOARD_DNTV_LIVE_DVB_T:
2905 		cx_set(MO_GP0_IO, 0x00000707);
2906 		cx_set(MO_GP2_IO, 0x00000101);
2907 		cx_clear(MO_GP2_IO, 0x00000001);
2908 		msleep(1);
2909 		cx_clear(MO_GP0_IO, 0x00000007);
2910 		cx_set(MO_GP2_IO, 0x00000101);
2911 		break;
2912 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
2913 		cx_write(MO_GP0_IO, 0x00080808);
2914 		break;
2915 	case CX88_BOARD_ATI_HDTVWONDER:
2916 		if (0 == core->i2c_rc) {
2917 			/* enable tuner */
2918 			int i;
2919 			static const u8 buffer [][2] = {
2920 				{0x10,0x12},
2921 				{0x13,0x04},
2922 				{0x16,0x00},
2923 				{0x14,0x04},
2924 				{0x17,0x00}
2925 			};
2926 			core->i2c_client.addr = 0x0a;
2927 
2928 			for (i = 0; i < ARRAY_SIZE(buffer); i++)
2929 				if (2 != i2c_master_send(&core->i2c_client,
2930 							buffer[i],2))
2931 					warn_printk(core, "Unable to enable "
2932 						    "tuner(%i).\n", i);
2933 		}
2934 		break;
2935 	case CX88_BOARD_MSI_TVANYWHERE_MASTER:
2936 	{
2937 		struct v4l2_priv_tun_config tea5767_cfg;
2938 		struct tea5767_ctrl ctl;
2939 
2940 		memset(&ctl, 0, sizeof(ctl));
2941 
2942 		ctl.high_cut  = 1;
2943 		ctl.st_noise  = 1;
2944 		ctl.deemph_75 = 1;
2945 		ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
2946 
2947 		tea5767_cfg.tuner = TUNER_TEA5767;
2948 		tea5767_cfg.priv  = &ctl;
2949 
2950 		cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
2951 		break;
2952 	}
2953 	case  CX88_BOARD_TEVII_S420:
2954 	case  CX88_BOARD_TEVII_S460:
2955 	case  CX88_BOARD_OMICOM_SS4_PCI:
2956 	case  CX88_BOARD_TBS_8910:
2957 	case  CX88_BOARD_TBS_8920:
2958 	case  CX88_BOARD_PROF_6200:
2959 	case  CX88_BOARD_PROF_7300:
2960 	case  CX88_BOARD_SATTRADE_ST4200:
2961 		cx_write(MO_SRST_IO, 0);
2962 		msleep(100);
2963 		cx_write(MO_SRST_IO, 1);
2964 		msleep(100);
2965 		break;
2966 	} /*end switch() */
2967 
2968 
2969 	/* Setup tuners */
2970 	if ((core->board.radio_type != UNSET)) {
2971 		tun_setup.mode_mask      = T_RADIO;
2972 		tun_setup.type           = core->board.radio_type;
2973 		tun_setup.addr           = core->board.radio_addr;
2974 		tun_setup.tuner_callback = cx88_tuner_callback;
2975 		cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
2976 		mode_mask &= ~T_RADIO;
2977 	}
2978 
2979 	if (core->board.tuner_type != TUNER_ABSENT) {
2980 		tun_setup.mode_mask      = mode_mask;
2981 		tun_setup.type           = core->board.tuner_type;
2982 		tun_setup.addr           = core->board.tuner_addr;
2983 		tun_setup.tuner_callback = cx88_tuner_callback;
2984 
2985 		cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
2986 	}
2987 
2988 	if (core->board.tda9887_conf) {
2989 		struct v4l2_priv_tun_config tda9887_cfg;
2990 
2991 		tda9887_cfg.tuner = TUNER_TDA9887;
2992 		tda9887_cfg.priv  = &core->board.tda9887_conf;
2993 
2994 		cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
2995 	}
2996 
2997 	if (core->board.tuner_type == TUNER_XC2028) {
2998 		struct v4l2_priv_tun_config  xc2028_cfg;
2999 		struct xc2028_ctrl           ctl;
3000 
3001 		/* Fills device-dependent initialization parameters */
3002 		cx88_setup_xc3028(core, &ctl);
3003 
3004 		/* Sends parameters to xc2028/3028 tuner */
3005 		memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
3006 		xc2028_cfg.tuner = TUNER_XC2028;
3007 		xc2028_cfg.priv  = &ctl;
3008 		info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
3009 			    ctl.fname);
3010 		cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
3011 	}
3012 	cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
3013 }
3014 
3015 /* ------------------------------------------------------------------ */
3016 
cx88_pci_quirks(const char * name,struct pci_dev * pci)3017 static int cx88_pci_quirks(const char *name, struct pci_dev *pci)
3018 {
3019 	unsigned int lat = UNSET;
3020 	u8 ctrl = 0;
3021 	u8 value;
3022 
3023 	/* check pci quirks */
3024 	if (pci_pci_problems & PCIPCI_TRITON) {
3025 		printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
3026 		       name);
3027 		ctrl |= CX88X_EN_TBFX;
3028 	}
3029 	if (pci_pci_problems & PCIPCI_NATOMA) {
3030 		printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
3031 		       name);
3032 		ctrl |= CX88X_EN_TBFX;
3033 	}
3034 	if (pci_pci_problems & PCIPCI_VIAETBF) {
3035 		printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
3036 		       name);
3037 		ctrl |= CX88X_EN_TBFX;
3038 	}
3039 	if (pci_pci_problems & PCIPCI_VSFX) {
3040 		printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
3041 		       name);
3042 		ctrl |= CX88X_EN_VSFX;
3043 	}
3044 #ifdef PCIPCI_ALIMAGIK
3045 	if (pci_pci_problems & PCIPCI_ALIMAGIK) {
3046 		printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
3047 		       name);
3048 		lat = 0x0A;
3049 	}
3050 #endif
3051 
3052 	/* check insmod options */
3053 	if (UNSET != latency)
3054 		lat = latency;
3055 
3056 	/* apply stuff */
3057 	if (ctrl) {
3058 		pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
3059 		value |= ctrl;
3060 		pci_write_config_byte(pci, CX88X_DEVCTRL, value);
3061 	}
3062 	if (UNSET != lat) {
3063 		printk(KERN_INFO "%s: setting pci latency timer to %d\n",
3064 		       name, latency);
3065 		pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
3066 	}
3067 	return 0;
3068 }
3069 
cx88_get_resources(const struct cx88_core * core,struct pci_dev * pci)3070 int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci)
3071 {
3072 	if (request_mem_region(pci_resource_start(pci,0),
3073 			       pci_resource_len(pci,0),
3074 			       core->name))
3075 		return 0;
3076 	printk(KERN_ERR
3077 	       "%s/%d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n",
3078 	       core->name, PCI_FUNC(pci->devfn),
3079 	       (unsigned long long)pci_resource_start(pci, 0),
3080 	       pci->subsystem_vendor, pci->subsystem_device);
3081 	return -EBUSY;
3082 }
3083 
3084 /* Allocate and initialize the cx88 core struct.  One should hold the
3085  * devlist mutex before calling this.  */
cx88_core_create(struct pci_dev * pci,int nr)3086 struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
3087 {
3088 	struct cx88_core *core;
3089 	int i;
3090 
3091 	core = kzalloc(sizeof(*core), GFP_KERNEL);
3092 
3093 	atomic_inc(&core->refcount);
3094 	core->pci_bus  = pci->bus->number;
3095 	core->pci_slot = PCI_SLOT(pci->devfn);
3096 	core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT |
3097 			    PCI_INT_BRDG_BERRINT | PCI_INT_SRC_DMA_BERRINT |
3098 			    PCI_INT_DST_DMA_BERRINT | PCI_INT_IPB_DMA_BERRINT;
3099 	mutex_init(&core->lock);
3100 
3101 	core->nr = nr;
3102 	sprintf(core->name, "cx88[%d]", core->nr);
3103 	if (0 != cx88_get_resources(core, pci)) {
3104 		kfree(core);
3105 		return NULL;
3106 	}
3107 
3108 	/* PCI stuff */
3109 	cx88_pci_quirks(core->name, pci);
3110 	core->lmmio = ioremap(pci_resource_start(pci, 0),
3111 			      pci_resource_len(pci, 0));
3112 	core->bmmio = (u8 __iomem *)core->lmmio;
3113 
3114 	/* board config */
3115 	core->boardnr = UNSET;
3116 	if (card[core->nr] < ARRAY_SIZE(cx88_boards))
3117 		core->boardnr = card[core->nr];
3118 	for (i = 0; UNSET == core->boardnr && i < ARRAY_SIZE(cx88_subids); i++)
3119 		if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
3120 		    pci->subsystem_device == cx88_subids[i].subdevice)
3121 			core->boardnr = cx88_subids[i].card;
3122 	if (UNSET == core->boardnr) {
3123 		core->boardnr = CX88_BOARD_UNKNOWN;
3124 		cx88_card_list(core, pci);
3125 	}
3126 
3127 	memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
3128 
3129 	if (!core->board.num_frontends && (core->board.mpeg & CX88_MPEG_DVB))
3130 		core->board.num_frontends = 1;
3131 
3132 	info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
3133 		pci->subsystem_vendor, pci->subsystem_device, core->board.name,
3134 		core->boardnr, card[core->nr] == core->boardnr ?
3135 		"insmod option" : "autodetected",
3136 		core->board.num_frontends);
3137 
3138 	if (tuner[core->nr] != UNSET)
3139 		core->board.tuner_type = tuner[core->nr];
3140 	if (radio[core->nr] != UNSET)
3141 		core->board.radio_type = radio[core->nr];
3142 
3143 	info_printk(core, "TV tuner type %d, Radio tuner type %d\n",
3144 		    core->board.tuner_type, core->board.radio_type);
3145 
3146 	/* init hardware */
3147 	cx88_reset(core);
3148 	cx88_card_setup_pre_i2c(core);
3149 	cx88_i2c_init(core, pci);
3150 
3151 	/* load tuner module, if needed */
3152 	if (TUNER_ABSENT != core->board.tuner_type)
3153 		request_module("tuner");
3154 
3155 	cx88_card_setup(core);
3156 	cx88_ir_init(core, pci);
3157 
3158 	return core;
3159 }
3160