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