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