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