Showing error 1638

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: drivers/media/video/cx88/cx88-cards.c
Line in file: 3011
Project: Linux Kernel
Project version: 2.6.28
Tools: Smatch (1.59)
Entered: 2013-09-10 07:54:05 UTC


Source:

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