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