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