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_DVICO_FUSIONHDTV_DVB_T_PRO] = {
1785                .name           = "DViCO FusionHDTV DVB-T PRO",
1786                .tuner_type     = TUNER_XC2028,
1787                .tuner_addr     = 0x61,
1788                .radio_type     = UNSET,
1789                .radio_addr     = ADDR_UNSET,
1790                .input          = { {
1791                        .type   = CX88_VMUX_COMPOSITE1,
1792                        .vmux   = 1,
1793                        .gpio0  = 0x000067df,
1794                }, {
1795                        .type   = CX88_VMUX_SVIDEO,
1796                        .vmux   = 2,
1797                        .gpio0  = 0x000067df,
1798                } },
1799                .mpeg           = CX88_MPEG_DVB,
1800        },
1801        [CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD] = {
1802                .name           = "DViCO FusionHDTV 7 Gold",
1803                .tuner_type     = TUNER_XC5000,
1804                .radio_type     = UNSET,
1805                .tuner_addr     = ADDR_UNSET,
1806                .radio_addr     = ADDR_UNSET,
1807                .input          = { {
1808                        .type   = CX88_VMUX_TELEVISION,
1809                        .vmux   = 0,
1810                        .gpio0  = 0x10df,
1811                }, {
1812                        .type   = CX88_VMUX_COMPOSITE1,
1813                        .vmux   = 1,
1814                        .gpio0  = 0x16d9,
1815                }, {
1816                        .type   = CX88_VMUX_SVIDEO,
1817                        .vmux   = 2,
1818                        .gpio0  = 0x16d9,
1819                } },
1820                .mpeg           = CX88_MPEG_DVB,
1821        },
1822        [CX88_BOARD_PROLINK_PV_8000GT] = {
1823                .name           = "Prolink Pixelview MPEG 8000GT",
1824                .tuner_type     = TUNER_XC2028,
1825                .tuner_addr     = 0x61,
1826                .input          = { {
1827                        .type   = CX88_VMUX_TELEVISION,
1828                        .vmux   = 0,
1829                        .gpio0 = 0x0ff,
1830                        .gpio2 = 0x0cfb,
1831                }, {
1832                        .type   = CX88_VMUX_COMPOSITE1,
1833                        .vmux   = 1,
1834                        .gpio2 = 0x0cfb,
1835                }, {
1836                        .type   = CX88_VMUX_SVIDEO,
1837                        .vmux   = 2,
1838                        .gpio2 = 0x0cfb,
1839                } },
1840                .radio = {
1841                        .type   = CX88_RADIO,
1842                        .gpio2 = 0x0cfb,
1843                },
1844        },
1845        [CX88_BOARD_PROLINK_PV_GLOBAL_XTREME] = {
1846                .name           = "Prolink Pixelview Global Extreme",
1847                .tuner_type     = TUNER_XC2028,
1848                .tuner_addr     = 0x61,
1849                .input          = { {
1850                        .type   = CX88_VMUX_TELEVISION,
1851                        .vmux   = 0,
1852                        .gpio0 = 0x04fb,
1853                        .gpio1 = 0x04080,
1854                        .gpio2 = 0x0cf7,
1855                }, {
1856                        .type   = CX88_VMUX_COMPOSITE1,
1857                        .vmux   = 1,
1858                        .gpio0 = 0x04fb,
1859                        .gpio1 = 0x04080,
1860                        .gpio2 = 0x0cfb,
1861                }, {
1862                        .type   = CX88_VMUX_SVIDEO,
1863                        .vmux   = 2,
1864                        .gpio0 = 0x04fb,
1865                        .gpio1 = 0x04080,
1866                        .gpio2 = 0x0cfb,
1867                } },
1868                .radio = {
1869                        .type   = CX88_RADIO,
1870                        .gpio0 = 0x04ff,
1871                        .gpio1 = 0x04080,
1872                        .gpio2 = 0x0cf7,
1873                },
1874        },
1875        /*
1876         * Both radio, analog and ATSC work with this board.
1877         * However, for analog to work, s5h1409 gate should be open,
1878         * otherwise, tuner-xc3028 won't be detected.
1879         * A proper fix require using the newer i2c methods to add
1880         * tuner-xc3028 without doing an i2c probe.
1881         */
1882        [CX88_BOARD_KWORLD_ATSC_120] = {
1883                .name           = "Kworld PlusTV HD PCI 120 (ATSC 120)",
1884                .tuner_type     = TUNER_XC2028,
1885                .radio_type     = UNSET,
1886                .tuner_addr     = ADDR_UNSET,
1887                .radio_addr     = ADDR_UNSET,
1888                .input          = { {
1889                        .type   = CX88_VMUX_TELEVISION,
1890                        .vmux   = 0,
1891                        .gpio0  = 0x000000ff,
1892                        .gpio1  = 0x0000f35d,
1893                        .gpio2  = 0x00000000,
1894                }, {
1895                        .type   = CX88_VMUX_COMPOSITE1,
1896                        .vmux   = 1,
1897                        .gpio0  = 0x000000ff,
1898                        .gpio1  = 0x0000f37e,
1899                        .gpio2  = 0x00000000,
1900                }, {
1901                        .type   = CX88_VMUX_SVIDEO,
1902                        .vmux   = 2,
1903                        .gpio0  = 0x000000ff,
1904                        .gpio1  = 0x0000f37e,
1905                        .gpio2  = 0x00000000,
1906                } },
1907                .radio = {
1908                        .type   = CX88_RADIO,
1909                        .gpio0  = 0x000000ff,
1910                        .gpio1  = 0x0000f35d,
1911                        .gpio2  = 0x00000000,
1912                },
1913                .mpeg           = CX88_MPEG_DVB,
1914        },
1915        [CX88_BOARD_HAUPPAUGE_HVR4000] = {
1916                .name           = "Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid",
1917                .tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
1918                .radio_type     = UNSET,
1919                .tuner_addr     = ADDR_UNSET,
1920                .radio_addr     = ADDR_UNSET,
1921                .tda9887_conf   = TDA9887_PRESENT,
1922                .audio_chip     = CX88_AUDIO_WM8775,
1923                /*
1924                 * GPIO0 (WINTV2000)
1925                 *
1926                 * Analogue     SAT     DVB-T
1927                 * Antenna      0xc4bf  0xc4bb
1928                 * Composite    0xc4bf  0xc4bb
1929                 * S-Video      0xc4bf  0xc4bb
1930                 * Composite1   0xc4ff  0xc4fb
1931                 * S-Video1     0xc4ff  0xc4fb
1932                 *
1933                 * BIT  VALUE   FUNCTION GP{x}_IO
1934                 * 0    1       I:?
1935                 * 1    1       I:?
1936                 * 2    1       O:MPEG PORT 0=DVB-T 1=DVB-S
1937                 * 3    1       I:?
1938                 * 4    1       I:?
1939                 * 5    1       I:?
1940                 * 6    0       O:INPUT SELECTOR 0=INTERNAL 1=EXPANSION
1941                 * 7    1       O:DVB-T DEMOD RESET LOW
1942                 *
1943                 * BIT  VALUE   FUNCTION GP{x}_OE
1944                 * 8    0       I
1945                 * 9    0       I
1946                 * a    1       O
1947                 * b    0       I
1948                 * c    0       I
1949                 * d    0       I
1950                 * e    1       O
1951                 * f    1       O
1952                 *
1953                 * WM8775 ADC
1954                 *
1955                 * 1: TV Audio / FM Mono
1956                 * 2: Line-In
1957                 * 3: Line-In Expansion
1958                 * 4: FM Stereo
1959                 */
1960                .input          = { {
1961                        .type   = CX88_VMUX_TELEVISION,
1962                        .vmux   = 0,
1963                        .gpio0  = 0xc4bf,
1964                        /* 1: TV Audio / FM Mono */
1965                        .audioroute = 1,
1966                }, {
1967                        .type   = CX88_VMUX_COMPOSITE1,
1968                        .vmux   = 1,
1969                        .gpio0  = 0xc4bf,
1970                        /* 2: Line-In */
1971                        .audioroute = 2,
1972                }, {
1973                        .type   = CX88_VMUX_SVIDEO,
1974                        .vmux   = 2,
1975                        .gpio0  = 0xc4bf,
1976                        /* 2: Line-In */
1977                        .audioroute = 2,
1978                } },
1979                .radio = {
1980                        .type   = CX88_RADIO,
1981                        .gpio0  = 0xc4bf,
1982                        /* 4: FM Stereo */
1983                        .audioroute = 8,
1984                },
1985                .mpeg           = CX88_MPEG_DVB,
1986                .num_frontends  = 2,
1987        },
1988        [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
1989                .name           = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
1990                .tuner_type     = UNSET,
1991                .radio_type     = UNSET,
1992                .tuner_addr     = ADDR_UNSET,
1993                .radio_addr     = ADDR_UNSET,
1994                .input          = { {
1995                        .type   = CX88_VMUX_DVB,
1996                        .vmux   = 0,
1997                } },
1998                .mpeg           = CX88_MPEG_DVB,
1999        },
2000        [CX88_BOARD_TEVII_S420] = {
2001                .name           = "TeVii S420 DVB-S",
2002                .tuner_type     = UNSET,
2003                .radio_type     = UNSET,
2004                .tuner_addr     = ADDR_UNSET,
2005                .radio_addr     = ADDR_UNSET,
2006                .input          = { {
2007                        .type   = CX88_VMUX_DVB,
2008                        .vmux   = 0,
2009                } },
2010                .mpeg           = CX88_MPEG_DVB,
2011        },
2012        [CX88_BOARD_TEVII_S460] = {
2013                .name           = "TeVii S460 DVB-S/S2",
2014                .tuner_type     = UNSET,
2015                .radio_type     = UNSET,
2016                .tuner_addr     = ADDR_UNSET,
2017                .radio_addr     = ADDR_UNSET,
2018                .input          = { {
2019                        .type   = CX88_VMUX_DVB,
2020                        .vmux   = 0,
2021                } },
2022                .mpeg           = CX88_MPEG_DVB,
2023        },
2024        [CX88_BOARD_TEVII_S464] = {
2025                .name           = "TeVii S464 DVB-S/S2",
2026                .tuner_type     = UNSET,
2027                .radio_type     = UNSET,
2028                .tuner_addr     = ADDR_UNSET,
2029                .radio_addr     = ADDR_UNSET,
2030                .input          = { {
2031                        .type   = CX88_VMUX_DVB,
2032                        .vmux   = 0,
2033                } },
2034                .mpeg           = CX88_MPEG_DVB,
2035        },
2036        [CX88_BOARD_OMICOM_SS4_PCI] = {
2037                .name           = "Omicom SS4 DVB-S/S2 PCI",
2038                .tuner_type     = UNSET,
2039                .radio_type     = UNSET,
2040                .tuner_addr     = ADDR_UNSET,
2041                .radio_addr     = ADDR_UNSET,
2042                .input          = { {
2043                        .type   = CX88_VMUX_DVB,
2044                        .vmux   = 0,
2045                } },
2046                .mpeg           = CX88_MPEG_DVB,
2047        },
2048        [CX88_BOARD_TBS_8910] = {
2049                .name           = "TBS 8910 DVB-S",
2050                .tuner_type     = UNSET,
2051                .radio_type     = UNSET,
2052                .tuner_addr     = ADDR_UNSET,
2053                .radio_addr     = ADDR_UNSET,
2054                .input          = { {
2055                        .type   = CX88_VMUX_DVB,
2056                        .vmux   = 0,
2057                } },
2058                .mpeg           = CX88_MPEG_DVB,
2059        },
2060        [CX88_BOARD_TBS_8920] = {
2061                .name           = "TBS 8920 DVB-S/S2",
2062                .tuner_type     = UNSET,
2063                .radio_type     = UNSET,
2064                .tuner_addr     = ADDR_UNSET,
2065                .radio_addr     = ADDR_UNSET,
2066                .input          = { {
2067                        .type   = CX88_VMUX_DVB,
2068                        .vmux   = 0,
2069                        .gpio0  = 0x8080,
2070                } },
2071                .mpeg           = CX88_MPEG_DVB,
2072        },
2073        [CX88_BOARD_PROF_6200] = {
2074                .name           = "Prof 6200 DVB-S",
2075                .tuner_type     = UNSET,
2076                .radio_type     = UNSET,
2077                .tuner_addr     = ADDR_UNSET,
2078                .radio_addr     = ADDR_UNSET,
2079                .input          = { {
2080                        .type   = CX88_VMUX_DVB,
2081                        .vmux   = 0,
2082                } },
2083                .mpeg           = CX88_MPEG_DVB,
2084        },
2085        [CX88_BOARD_PROF_7300] = {
2086                .name           = "PROF 7300 DVB-S/S2",
2087                .tuner_type     = UNSET,
2088                .radio_type     = UNSET,
2089                .tuner_addr     = ADDR_UNSET,
2090                .radio_addr     = ADDR_UNSET,
2091                .input          = { {
2092                        .type   = CX88_VMUX_DVB,
2093                        .vmux   = 0,
2094                } },
2095                .mpeg           = CX88_MPEG_DVB,
2096        },
2097        [CX88_BOARD_SATTRADE_ST4200] = {
2098                .name           = "SATTRADE ST4200 DVB-S/S2",
2099                .tuner_type     = UNSET,
2100                .radio_type     = UNSET,
2101                .tuner_addr     = ADDR_UNSET,
2102                .radio_addr     = ADDR_UNSET,
2103                .input          = { {
2104                        .type   = CX88_VMUX_DVB,
2105                        .vmux   = 0,
2106                } },
2107                .mpeg           = CX88_MPEG_DVB,
2108        },
2109        [CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII] = {
2110                .name           = "Terratec Cinergy HT PCI MKII",
2111                .tuner_type     = TUNER_XC2028,
2112                .tuner_addr     = 0x61,
2113                .radio_type     = UNSET,
2114                .radio_addr     = ADDR_UNSET,
2115                .input          = { {
2116                        .type   = CX88_VMUX_TELEVISION,
2117                        .vmux   = 0,
2118                        .gpio0  = 0x004ff,
2119                        .gpio1  = 0x010ff,
2120                        .gpio2  = 0x00001,
2121                }, {
2122                        .type   = CX88_VMUX_COMPOSITE1,
2123                        .vmux   = 1,
2124                        .gpio0  = 0x004fb,
2125                        .gpio1  = 0x010ef,
2126                        .audioroute = 1,
2127                }, {
2128                        .type   = CX88_VMUX_SVIDEO,
2129                        .vmux   = 2,
2130                        .gpio0  = 0x004fb,
2131                        .gpio1  = 0x010ef,
2132                        .audioroute = 1,
2133                } },
2134                .radio = {
2135                        .type   = CX88_RADIO,
2136                        .gpio0  = 0x004ff,
2137                        .gpio1  = 0x010ff,
2138                        .gpio2  = 0x0ff,
2139                },
2140                .mpeg           = CX88_MPEG_DVB,
2141        },
2142        [CX88_BOARD_HAUPPAUGE_IRONLY] = {
2143                .name           = "Hauppauge WinTV-IR Only",
2144                .tuner_type     = UNSET,
2145                .radio_type     = UNSET,
2146                .tuner_addr     = ADDR_UNSET,
2147                .radio_addr     = ADDR_UNSET,
2148        },
2149        [CX88_BOARD_WINFAST_DTV1800H] = {
2150                .name           = "Leadtek WinFast DTV1800 Hybrid",
2151                .tuner_type     = TUNER_XC2028,
2152                .radio_type     = UNSET,
2153                .tuner_addr     = 0x61,
2154                .radio_addr     = ADDR_UNSET,
2155                /*
2156                 * GPIO setting
2157                 *
2158                 *  2: mute (0=off,1=on)
2159                 * 12: tuner reset pin
2160                 * 13: audio source (0=tuner audio,1=line in)
2161                 * 14: FM (0=on,1=off ???)
2162                 */
2163                .input          = { {
2164                        .type   = CX88_VMUX_TELEVISION,
2165                        .vmux   = 0,
2166                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2167                        .gpio1  = 0x6040,       /* pin 13 = 0, pin 14 = 1 */
2168                        .gpio2  = 0x0000,
2169                }, {
2170                        .type   = CX88_VMUX_COMPOSITE1,
2171                        .vmux   = 1,
2172                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2173                        .gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
2174                        .gpio2  = 0x0000,
2175                }, {
2176                        .type   = CX88_VMUX_SVIDEO,
2177                        .vmux   = 2,
2178                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2179                        .gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
2180                        .gpio2  = 0x0000,
2181                } },
2182                .radio = {
2183                        .type   = CX88_RADIO,
2184                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2185                        .gpio1  = 0x6000,       /* pin 13 = 0, pin 14 = 0 */
2186                        .gpio2  = 0x0000,
2187                },
2188                .mpeg           = CX88_MPEG_DVB,
2189        },
2190        [CX88_BOARD_WINFAST_DTV1800H_XC4000] = {
2191                .name           = "Leadtek WinFast DTV1800 H (XC4000)",
2192                .tuner_type     = TUNER_XC4000,
2193                .radio_type     = UNSET,
2194                .tuner_addr     = 0x61,
2195                .radio_addr     = ADDR_UNSET,
2196                /*
2197                 * GPIO setting
2198                 *
2199                 *  2: mute (0=off,1=on)
2200                 * 12: tuner reset pin
2201                 * 13: audio source (0=tuner audio,1=line in)
2202                 * 14: FM (0=on,1=off ???)
2203                 */
2204                .input          = { {
2205                        .type   = CX88_VMUX_TELEVISION,
2206                        .vmux   = 0,
2207                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2208                        .gpio1  = 0x6040,       /* pin 13 = 0, pin 14 = 1 */
2209                        .gpio2  = 0x0000,
2210                }, {
2211                        .type   = CX88_VMUX_COMPOSITE1,
2212                        .vmux   = 1,
2213                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2214                        .gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
2215                        .gpio2  = 0x0000,
2216                }, {
2217                        .type   = CX88_VMUX_SVIDEO,
2218                        .vmux   = 2,
2219                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2220                        .gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
2221                        .gpio2  = 0x0000,
2222                } },
2223                .radio = {
2224                        .type   = CX88_RADIO,
2225                        .gpio0  = 0x0400,       /* pin 2 = 0 */
2226                        .gpio1  = 0x6000,       /* pin 13 = 0, pin 14 = 0 */
2227                        .gpio2  = 0x0000,
2228                },
2229                .mpeg           = CX88_MPEG_DVB,
2230        },
2231        [CX88_BOARD_WINFAST_DTV2000H_PLUS] = {
2232                .name           = "Leadtek WinFast DTV2000 H PLUS",
2233                .tuner_type     = TUNER_XC4000,
2234                .radio_type     = UNSET,
2235                .tuner_addr     = 0x61,
2236                .radio_addr     = ADDR_UNSET,
2237                /*
2238                 * GPIO
2239                 *   2: 1: mute audio
2240                 *  12: 0: reset XC4000
2241                 *  13: 1: audio input is line in (0: tuner)
2242                 *  14: 0: FM radio
2243                 *  16: 0: RF input is cable
2244                 */
2245                .input          = { {
2246                        .type   = CX88_VMUX_TELEVISION,
2247                        .vmux   = 0,
2248                        .gpio0  = 0x0403,
2249                        .gpio1  = 0xF0D7,
2250                        .gpio2  = 0x0101,
2251                        .gpio3  = 0x0000,
2252                }, {
2253                        .type   = CX88_VMUX_CABLE,
2254                        .vmux   = 0,
2255                        .gpio0  = 0x0403,
2256                        .gpio1  = 0xF0D7,
2257                        .gpio2  = 0x0100,
2258                        .gpio3  = 0x0000,
2259                }, {
2260                        .type   = CX88_VMUX_COMPOSITE1,
2261                        .vmux   = 1,
2262                        .gpio0  = 0x0403,       /* was 0x0407 */
2263                        .gpio1  = 0xF0F7,
2264                        .gpio2  = 0x0101,
2265                        .gpio3  = 0x0000,
2266                }, {
2267                        .type   = CX88_VMUX_SVIDEO,
2268                        .vmux   = 2,
2269                        .gpio0  = 0x0403,       /* was 0x0407 */
2270                        .gpio1  = 0xF0F7,
2271                        .gpio2  = 0x0101,
2272                        .gpio3  = 0x0000,
2273                } },
2274                .radio = {
2275                        .type   = CX88_RADIO,
2276                        .gpio0  = 0x0403,
2277                        .gpio1  = 0xF097,
2278                        .gpio2  = 0x0100,
2279                        .gpio3  = 0x0000,
2280                },
2281                .mpeg           = CX88_MPEG_DVB,
2282        },
2283        [CX88_BOARD_PROF_7301] = {
2284                .name           = "Prof 7301 DVB-S/S2",
2285                .tuner_type     = UNSET,
2286                .radio_type     = UNSET,
2287                .tuner_addr     = ADDR_UNSET,
2288                .radio_addr     = ADDR_UNSET,
2289                .input          = { {
2290                        .type   = CX88_VMUX_DVB,
2291                        .vmux   = 0,
2292                } },
2293                .mpeg           = CX88_MPEG_DVB,
2294        },
2295        [CX88_BOARD_TWINHAN_VP1027_DVBS] = {
2296                .name           = "Twinhan VP-1027 DVB-S",
2297                .tuner_type     = UNSET,
2298                .radio_type     = UNSET,
2299                .tuner_addr     = ADDR_UNSET,
2300                .radio_addr     = ADDR_UNSET,
2301                .input          = { {
2302                       .type   = CX88_VMUX_DVB,
2303                       .vmux   = 0,
2304                } },
2305                .mpeg           = CX88_MPEG_DVB,
2306        },
2307};
2308
2309/* ------------------------------------------------------------------ */
2310/* PCI subsystem IDs                                                  */
2311
2312static const struct cx88_subid cx88_subids[] = {
2313        {
2314                .subvendor = 0x0070,
2315                .subdevice = 0x3400,
2316                .card      = CX88_BOARD_HAUPPAUGE,
2317        }, {
2318                .subvendor = 0x0070,
2319                .subdevice = 0x3401,
2320                .card      = CX88_BOARD_HAUPPAUGE,
2321        }, {
2322                .subvendor = 0x14c7,
2323                .subdevice = 0x0106,
2324                .card      = CX88_BOARD_GDI,
2325        }, {
2326                .subvendor = 0x14c7,
2327                .subdevice = 0x0107, /* with mpeg encoder */
2328                .card      = CX88_BOARD_GDI,
2329        }, {
2330                .subvendor = PCI_VENDOR_ID_ATI,
2331                .subdevice = 0x00f8,
2332                .card      = CX88_BOARD_ATI_WONDER_PRO,
2333        }, {
2334                .subvendor = PCI_VENDOR_ID_ATI,
2335                .subdevice = 0x00f9,
2336                .card      = CX88_BOARD_ATI_WONDER_PRO,
2337        }, {
2338                .subvendor = 0x107d,
2339                .subdevice = 0x6611,
2340                .card      = CX88_BOARD_WINFAST2000XP_EXPERT,
2341        }, {
2342                .subvendor = 0x107d,
2343                .subdevice = 0x6613,    /* NTSC */
2344                .card      = CX88_BOARD_WINFAST2000XP_EXPERT,
2345        }, {
2346                .subvendor = 0x107d,
2347                .subdevice = 0x6620,
2348                .card      = CX88_BOARD_WINFAST_DV2000,
2349        }, {
2350                .subvendor = 0x107d,
2351                .subdevice = 0x663b,
2352                .card      = CX88_BOARD_LEADTEK_PVR2000,
2353        }, {
2354                .subvendor = 0x107d,
2355                .subdevice = 0x663c,
2356                .card      = CX88_BOARD_LEADTEK_PVR2000,
2357        }, {
2358                .subvendor = 0x1461,
2359                .subdevice = 0x000b,
2360                .card      = CX88_BOARD_AVERTV_STUDIO_303,
2361        }, {
2362                .subvendor = 0x1462,
2363                .subdevice = 0x8606,
2364                .card      = CX88_BOARD_MSI_TVANYWHERE_MASTER,
2365        }, {
2366                .subvendor = 0x10fc,
2367                .subdevice = 0xd003,
2368                .card      = CX88_BOARD_IODATA_GVVCP3PCI,
2369        }, {
2370                .subvendor = 0x1043,
2371                .subdevice = 0x4823,  /* with mpeg encoder */
2372                .card      = CX88_BOARD_ASUS_PVR_416,
2373        }, {
2374                .subvendor = 0x17de,
2375                .subdevice = 0x08a6,
2376                .card      = CX88_BOARD_KWORLD_DVB_T,
2377        }, {
2378                .subvendor = 0x18ac,
2379                .subdevice = 0xd810,
2380                .card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
2381        }, {
2382                .subvendor = 0x18ac,
2383                .subdevice = 0xd820,
2384                .card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
2385        }, {
2386                .subvendor = 0x18ac,
2387                .subdevice = 0xdb00,
2388                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
2389        }, {
2390                .subvendor = 0x0070,
2391                .subdevice = 0x9002,
2392                .card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
2393        }, {
2394                .subvendor = 0x14f1,
2395                .subdevice = 0x0187,
2396                .card      = CX88_BOARD_CONEXANT_DVB_T1,
2397        }, {
2398                .subvendor = 0x1540,
2399                .subdevice = 0x2580,
2400                .card      = CX88_BOARD_PROVIDEO_PV259,
2401        }, {
2402                .subvendor = 0x18ac,
2403                .subdevice = 0xdb10,
2404                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
2405        }, {
2406                .subvendor = 0x1554,
2407                .subdevice = 0x4811,
2408                .card      = CX88_BOARD_PIXELVIEW,
2409        }, {
2410                .subvendor = 0x7063,
2411                .subdevice = 0x3000, /* HD-3000 card */
2412                .card      = CX88_BOARD_PCHDTV_HD3000,
2413        }, {
2414                .subvendor = 0x17de,
2415                .subdevice = 0xa8a6,
2416                .card      = CX88_BOARD_DNTV_LIVE_DVB_T,
2417        }, {
2418                .subvendor = 0x0070,
2419                .subdevice = 0x2801,
2420                .card      = CX88_BOARD_HAUPPAUGE_ROSLYN,
2421        }, {
2422                .subvendor = 0x14f1,
2423                .subdevice = 0x0342,
2424                .card      = CX88_BOARD_DIGITALLOGIC_MEC,
2425        }, {
2426                .subvendor = 0x10fc,
2427                .subdevice = 0xd035,
2428                .card      = CX88_BOARD_IODATA_GVBCTV7E,
2429        }, {
2430                .subvendor = 0x1421,
2431                .subdevice = 0x0334,
2432                .card      = CX88_BOARD_ADSTECH_DVB_T_PCI,
2433        }, {
2434                .subvendor = 0x153b,
2435                .subdevice = 0x1166,
2436                .card      = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
2437        }, {
2438                .subvendor = 0x18ac,
2439                .subdevice = 0xd500,
2440                .card      = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
2441        }, {
2442                .subvendor = 0x1461,
2443                .subdevice = 0x8011,
2444                .card      = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
2445        }, {
2446                .subvendor = PCI_VENDOR_ID_ATI,
2447                .subdevice = 0xa101,
2448                .card      = CX88_BOARD_ATI_HDTVWONDER,
2449        }, {
2450                .subvendor = 0x107d,
2451                .subdevice = 0x665f,
2452                .card      = CX88_BOARD_WINFAST_DTV1000,
2453        }, {
2454                .subvendor = 0x1461,
2455                .subdevice = 0x000a,
2456                .card      = CX88_BOARD_AVERTV_303,
2457        }, {
2458                .subvendor = 0x0070,
2459                .subdevice = 0x9200,
2460                .card      = CX88_BOARD_HAUPPAUGE_NOVASE2_S1,
2461        }, {
2462                .subvendor = 0x0070,
2463                .subdevice = 0x9201,
2464                .card      = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
2465        }, {
2466                .subvendor = 0x0070,
2467                .subdevice = 0x9202,
2468                .card      = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
2469        }, {
2470                .subvendor = 0x17de,
2471                .subdevice = 0x08b2,
2472                .card      = CX88_BOARD_KWORLD_DVBS_100,
2473        }, {
2474                .subvendor = 0x0070,
2475                .subdevice = 0x9400,
2476                .card      = CX88_BOARD_HAUPPAUGE_HVR1100,
2477        }, {
2478                .subvendor = 0x0070,
2479                .subdevice = 0x9402,
2480                .card      = CX88_BOARD_HAUPPAUGE_HVR1100,
2481        }, {
2482                .subvendor = 0x0070,
2483                .subdevice = 0x9800,
2484                .card      = CX88_BOARD_HAUPPAUGE_HVR1100LP,
2485        }, {
2486                .subvendor = 0x0070,
2487                .subdevice = 0x9802,
2488                .card      = CX88_BOARD_HAUPPAUGE_HVR1100LP,
2489        }, {
2490                .subvendor = 0x0070,
2491                .subdevice = 0x9001,
2492                .card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
2493        }, {
2494                .subvendor = 0x1822,
2495                .subdevice = 0x0025,
2496                .card      = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
2497        }, {
2498                .subvendor = 0x17de,
2499                .subdevice = 0x08a1,
2500                .card      = CX88_BOARD_KWORLD_DVB_T_CX22702,
2501        }, {
2502                .subvendor = 0x18ac,
2503                .subdevice = 0xdb50,
2504                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
2505        }, {
2506                .subvendor = 0x18ac,
2507                .subdevice = 0xdb54,
2508                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
2509                /* Re-branded DViCO: DigitalNow DVB-T Dual */
2510        }, {
2511                .subvendor = 0x18ac,
2512                .subdevice = 0xdb11,
2513                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
2514                /* Re-branded DViCO: UltraView DVB-T Plus */
2515        }, {
2516                .subvendor = 0x18ac,
2517                .subdevice = 0xdb30,
2518                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO,
2519        }, {
2520                .subvendor = 0x17de,
2521                .subdevice = 0x0840,
2522                .card      = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
2523        }, {
2524                .subvendor = 0x1421,
2525                .subdevice = 0x0305,
2526                .card      = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
2527        }, {
2528                .subvendor = 0x18ac,
2529                .subdevice = 0xdb40,
2530                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
2531        }, {
2532                .subvendor = 0x18ac,
2533                .subdevice = 0xdb44,
2534                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
2535        }, {
2536                .subvendor = 0x7063,
2537                .subdevice = 0x5500,
2538                .card      = CX88_BOARD_PCHDTV_HD5500,
2539        }, {
2540                .subvendor = 0x17de,
2541                .subdevice = 0x0841,
2542                .card      = CX88_BOARD_KWORLD_MCE200_DELUXE,
2543        }, {
2544                .subvendor = 0x1822,
2545                .subdevice = 0x0019,
2546                .card      = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
2547        }, {
2548                .subvendor = 0x1554,
2549                .subdevice = 0x4813,
2550                .card      = CX88_BOARD_PIXELVIEW_PLAYTV_P7000,
2551        }, {
2552                .subvendor = 0x14f1,
2553                .subdevice = 0x0842,
2554                .card      = CX88_BOARD_NPGTECH_REALTV_TOP10FM,
2555        }, {
2556                .subvendor = 0x107d,
2557                .subdevice = 0x665e,
2558                .card      = CX88_BOARD_WINFAST_DTV2000H,
2559        }, {
2560                .subvendor = 0x107d,
2561                .subdevice = 0x6f2b,
2562                .card      = CX88_BOARD_WINFAST_DTV2000H_J,
2563        }, {
2564                .subvendor = 0x18ac,
2565                .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */
2566                .card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
2567        }, {
2568                .subvendor = 0x14f1,
2569                .subdevice = 0x0084,
2570                .card      = CX88_BOARD_GENIATECH_DVBS,
2571        }, {
2572                .subvendor = 0x0070,
2573                .subdevice = 0x1404,
2574                .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2575        }, {
2576                .subvendor = 0x18ac,
2577                .subdevice = 0xdc00,
2578                .card      = CX88_BOARD_SAMSUNG_SMT_7020,
2579        }, {
2580                .subvendor = 0x18ac,
2581                .subdevice = 0xdccd,
2582                .card      = CX88_BOARD_SAMSUNG_SMT_7020,
2583        }, {
2584                .subvendor = 0x1461,
2585                .subdevice = 0xc111, /* AverMedia M150-D */
2586                /* This board is known to work with the ASUS PVR416 config */
2587                .card      = CX88_BOARD_ASUS_PVR_416,
2588        }, {
2589                .subvendor = 0xc180,
2590                .subdevice = 0xc980,
2591                .card      = CX88_BOARD_TE_DTV_250_OEM_SWANN,
2592        }, {
2593                .subvendor = 0x0070,
2594                .subdevice = 0x9600,
2595                .card      = CX88_BOARD_HAUPPAUGE_HVR1300,
2596        }, {
2597                .subvendor = 0x0070,
2598                .subdevice = 0x9601,
2599                .card      = CX88_BOARD_HAUPPAUGE_HVR1300,
2600        }, {
2601                .subvendor = 0x0070,
2602                .subdevice = 0x9602,
2603                .card      = CX88_BOARD_HAUPPAUGE_HVR1300,
2604        }, {
2605                .subvendor = 0x107d,
2606                .subdevice = 0x6632,
2607                .card      = CX88_BOARD_LEADTEK_PVR2000,
2608        }, {
2609                .subvendor = 0x12ab,
2610                .subdevice = 0x2300, /* Club3D Zap TV2100 */
2611                .card      = CX88_BOARD_KWORLD_DVB_T_CX22702,
2612        }, {
2613                .subvendor = 0x0070,
2614                .subdevice = 0x9000,
2615                .card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
2616        }, {
2617                .subvendor = 0x0070,
2618                .subdevice = 0x1400,
2619                .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2620        }, {
2621                .subvendor = 0x0070,
2622                .subdevice = 0x1401,
2623                .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2624        }, {
2625                .subvendor = 0x0070,
2626                .subdevice = 0x1402,
2627                .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
2628        }, {
2629                .subvendor = 0x1421,
2630                .subdevice = 0x0341, /* ADS Tech InstantTV DVB-S */
2631                .card      = CX88_BOARD_KWORLD_DVBS_100,
2632        }, {
2633                .subvendor = 0x1421,
2634                .subdevice = 0x0390,
2635                .card      = CX88_BOARD_ADSTECH_PTV_390,
2636        }, {
2637                .subvendor = 0x11bd,
2638                .subdevice = 0x0051,
2639                .card      = CX88_BOARD_PINNACLE_PCTV_HD_800i,
2640        }, {
2641                .subvendor = 0x18ac,
2642                .subdevice = 0xd530,
2643                .card      = CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO,
2644        }, {
2645                .subvendor = 0x12ab,
2646                .subdevice = 0x1788,
2647                .card      = CX88_BOARD_PINNACLE_HYBRID_PCTV,
2648        }, {
2649                .subvendor = 0x14f1,
2650                .subdevice = 0xea3d,
2651                .card      = CX88_BOARD_POWERCOLOR_REAL_ANGEL,
2652        }, {
2653                .subvendor = 0x107d,
2654                .subdevice = 0x6f18,
2655                .card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
2656        }, {
2657                .subvendor = 0x14f1,
2658                .subdevice = 0x8852,
2659                .card      = CX88_BOARD_GENIATECH_X8000_MT,
2660        }, {
2661                .subvendor = 0x18ac,
2662                .subdevice = 0xd610,
2663                .card      = CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD,
2664        }, {
2665                .subvendor = 0x1554,
2666                .subdevice = 0x4935,
2667                .card      = CX88_BOARD_PROLINK_PV_8000GT,
2668        }, {
2669                .subvendor = 0x1554,
2670                .subdevice = 0x4976,
2671                .card      = CX88_BOARD_PROLINK_PV_GLOBAL_XTREME,
2672        }, {
2673                .subvendor = 0x17de,
2674                .subdevice = 0x08c1,
2675                .card      = CX88_BOARD_KWORLD_ATSC_120,
2676        }, {
2677                .subvendor = 0x0070,
2678                .subdevice = 0x6900,
2679                .card      = CX88_BOARD_HAUPPAUGE_HVR4000,
2680        }, {
2681                .subvendor = 0x0070,
2682                .subdevice = 0x6904,
2683                .card      = CX88_BOARD_HAUPPAUGE_HVR4000,
2684        }, {
2685                .subvendor = 0x0070,
2686                .subdevice = 0x6902,
2687                .card      = CX88_BOARD_HAUPPAUGE_HVR4000,
2688        }, {
2689                .subvendor = 0x0070,
2690                .subdevice = 0x6905,
2691                .card      = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
2692        }, {
2693                .subvendor = 0x0070,
2694                .subdevice = 0x6906,
2695                .card      = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
2696        }, {
2697                .subvendor = 0xd420,
2698                .subdevice = 0x9022,
2699                .card      = CX88_BOARD_TEVII_S420,
2700        }, {
2701                .subvendor = 0xd460,
2702                .subdevice = 0x9022,
2703                .card      = CX88_BOARD_TEVII_S460,
2704        }, {
2705                .subvendor = 0xd464,
2706                .subdevice = 0x9022,
2707                .card      = CX88_BOARD_TEVII_S464,
2708        }, {
2709                .subvendor = 0xA044,
2710                .subdevice = 0x2011,
2711                .card      = CX88_BOARD_OMICOM_SS4_PCI,
2712        }, {
2713                .subvendor = 0x8910,
2714                .subdevice = 0x8888,
2715                .card      = CX88_BOARD_TBS_8910,
2716        }, {
2717                .subvendor = 0x8920,
2718                .subdevice = 0x8888,
2719                .card      = CX88_BOARD_TBS_8920,
2720        }, {
2721                .subvendor = 0xb022,
2722                .subdevice = 0x3022,
2723                .card      = CX88_BOARD_PROF_6200,
2724        }, {
2725                .subvendor = 0xB033,
2726                .subdevice = 0x3033,
2727                .card      = CX88_BOARD_PROF_7300,
2728        }, {
2729                .subvendor = 0xb200,
2730                .subdevice = 0x4200,
2731                .card      = CX88_BOARD_SATTRADE_ST4200,
2732        }, {
2733                .subvendor = 0x153b,
2734                .subdevice = 0x1177,
2735                .card      = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
2736        }, {
2737                .subvendor = 0x0070,
2738                .subdevice = 0x9290,
2739                .card      = CX88_BOARD_HAUPPAUGE_IRONLY,
2740        }, {
2741                .subvendor = 0x107d,
2742                .subdevice = 0x6654,
2743                .card      = CX88_BOARD_WINFAST_DTV1800H,
2744        }, {
2745                /* WinFast DTV1800 H with XC4000 tuner */
2746                .subvendor = 0x107d,
2747                .subdevice = 0x6f38,
2748                .card      = CX88_BOARD_WINFAST_DTV1800H_XC4000,
2749        }, {
2750                .subvendor = 0x107d,
2751                .subdevice = 0x6f42,
2752                .card      = CX88_BOARD_WINFAST_DTV2000H_PLUS,
2753        }, {
2754                /* PVR2000 PAL Model [107d:6630] */
2755                .subvendor = 0x107d,
2756                .subdevice = 0x6630,
2757                .card      = CX88_BOARD_LEADTEK_PVR2000,
2758        }, {
2759                /* PVR2000 PAL Model [107d:6638] */
2760                .subvendor = 0x107d,
2761                .subdevice = 0x6638,
2762                .card      = CX88_BOARD_LEADTEK_PVR2000,
2763        }, {
2764                /* PVR2000 NTSC Model [107d:6631] */
2765                .subvendor = 0x107d,
2766                .subdevice = 0x6631,
2767                .card      = CX88_BOARD_LEADTEK_PVR2000,
2768        }, {
2769                /* PVR2000 NTSC Model [107d:6637] */
2770                .subvendor = 0x107d,
2771                .subdevice = 0x6637,
2772                .card      = CX88_BOARD_LEADTEK_PVR2000,
2773        }, {
2774                /* PVR2000 NTSC Model [107d:663d] */
2775                .subvendor = 0x107d,
2776                .subdevice = 0x663d,
2777                .card      = CX88_BOARD_LEADTEK_PVR2000,
2778        }, {
2779                /* DV2000 NTSC Model [107d:6621] */
2780                .subvendor = 0x107d,
2781                .subdevice = 0x6621,
2782                .card      = CX88_BOARD_WINFAST_DV2000,
2783        }, {
2784                /* TV2000 XP Global [107d:6618]  */
2785                .subvendor = 0x107d,
2786                .subdevice = 0x6618,
2787                .card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
2788        }, {
2789                /* TV2000 XP Global [107d:6618] */
2790                .subvendor = 0x107d,
2791                .subdevice = 0x6619,
2792                .card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
2793        }, {
2794                /* WinFast TV2000 XP Global with XC4000 tuner */
2795                .subvendor = 0x107d,
2796                .subdevice = 0x6f36,
2797                .card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36,
2798        }, {
2799                /* WinFast TV2000 XP Global with XC4000 tuner and different GPIOs */
2800                .subvendor = 0x107d,
2801                .subdevice = 0x6f43,
2802                .card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43,
2803        }, {
2804                .subvendor = 0xb034,
2805                .subdevice = 0x3034,
2806                .card      = CX88_BOARD_PROF_7301,
2807        }, {
2808                .subvendor = 0x1822,
2809                .subdevice = 0x0023,
2810                .card      = CX88_BOARD_TWINHAN_VP1027_DVBS,
2811        },
2812};
2813
2814/*
2815 * some leadtek specific stuff
2816 */
2817static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
2818{
2819        if (eeprom_data[4] != 0x7d ||
2820            eeprom_data[5] != 0x10 ||
2821            eeprom_data[7] != 0x66) {
2822                pr_warn("Leadtek eeprom invalid.\n");
2823                return;
2824        }
2825
2826        /* Terry Wu <terrywu2009@gmail.com> */
2827        switch (eeprom_data[6]) {
2828        case 0x13: /* SSID 6613 for TV2000 XP Expert NTSC Model */
2829        case 0x21: /* SSID 6621 for DV2000 NTSC Model */
2830        case 0x31: /* SSID 6631 for PVR2000 NTSC Model */
2831        case 0x37: /* SSID 6637 for PVR2000 NTSC Model */
2832        case 0x3d: /* SSID 6637 for PVR2000 NTSC Model */
2833                core->board.tuner_type = TUNER_PHILIPS_FM1236_MK3;
2834                break;
2835        default:
2836                core->board.tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
2837                break;
2838        }
2839
2840        pr_info("Leadtek Winfast 2000XP Expert config: tuner=%d, eeprom[0]=0x%02x\n",
2841                core->board.tuner_type, eeprom_data[0]);
2842}
2843
2844static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2845{
2846        struct tveeprom tv;
2847
2848        tveeprom_hauppauge_analog(&tv, eeprom_data);
2849        core->board.tuner_type = tv.tuner_type;
2850        core->tuner_formats = tv.tuner_formats;
2851        core->board.radio.type = tv.has_radio ? CX88_RADIO : 0;
2852        core->model = tv.model;
2853
2854        /* Make sure we support the board model */
2855        switch (tv.model) {
2856        case 14009: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in) */
2857        case 14019: /* WinTV-HVR3000 (Retail, IR Blaster, b/panel video, 3.5mm audio in) */
2858        case 14029: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge) */
2859        case 14109: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - low profile) */
2860        case 14129: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge - LP) */
2861        case 14559: /* WinTV-HVR3000 (OEM, no IR, b/panel video, 3.5mm audio in) */
2862        case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */
2863        case 14659: /* WinTV-HVR3000 (OEM, no IR, b/panel video, RCA audio in - Low profile) */
2864        case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */
2865        case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
2866        case 34519: /* WinTV-PCI-FM */
2867        case 69009:
2868                /* WinTV-HVR4000 (DVBS/S2/T, Video and IR, back panel inputs) */
2869        case 69100: /* WinTV-HVR4000LITE (DVBS/S2, IR) */
2870        case 69500: /* WinTV-HVR4000LITE (DVBS/S2, No IR) */
2871        case 69559:
2872                /* WinTV-HVR4000 (DVBS/S2/T, Video no IR, back panel inputs) */
2873        case 69569: /* WinTV-HVR4000 (DVBS/S2/T, Video no IR) */
2874        case 90002: /* Nova-T-PCI (9002) */
2875        case 92001: /* Nova-S-Plus (Video and IR) */
2876        case 92002: /* Nova-S-Plus (Video and IR) */
2877        case 90003: /* Nova-T-PCI (9002 No RF out) */
2878        case 90500: /* Nova-T-PCI (oem) */
2879        case 90501: /* Nova-T-PCI (oem/IR) */
2880        case 92000: /* Nova-SE2 (OEM, No Video or IR) */
2881        case 92900: /* WinTV-IROnly (No analog or digital Video inputs) */
2882        case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
2883        case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
2884        case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
2885        case 96019: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX/TX) */
2886        case 96559: /* WinTV-HVR1300 (PAL Video, MPEG Video no IR) */
2887        case 96569: /* WinTV-HVR1300 () */
2888        case 96659: /* WinTV-HVR1300 () */
2889        case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
2890                /* known */
2891                break;
2892        case CX88_BOARD_SAMSUNG_SMT_7020:
2893                cx_set(MO_GP0_IO, 0x008989FF);
2894                break;
2895        default:
2896                pr_warn("warning: unknown hauppauge model #%d\n", tv.model);
2897                break;
2898        }
2899
2900        pr_info("hauppauge eeprom: model=%d\n", tv.model);
2901}
2902
2903/*
2904 * some GDI (was: Modular Technology) specific stuff
2905 */
2906
2907static const struct {
2908        int  id;
2909        int  fm;
2910        const char *name;
2911} gdi_tuner[] = {
2912        [0x01] = { .id   = UNSET,
2913                   .name = "NTSC_M" },
2914        [0x02] = { .id   = UNSET,
2915                   .name = "PAL_B" },
2916        [0x03] = { .id   = UNSET,
2917                   .name = "PAL_I" },
2918        [0x04] = { .id   = UNSET,
2919                   .name = "PAL_D" },
2920        [0x05] = { .id   = UNSET,
2921                   .name = "SECAM" },
2922
2923        [0x10] = { .id   = UNSET,
2924                   .fm   = 1,
2925                   .name = "TEMIC_4049" },
2926        [0x11] = { .id   = TUNER_TEMIC_4136FY5,
2927                   .name = "TEMIC_4136" },
2928        [0x12] = { .id   = UNSET,
2929                   .name = "TEMIC_4146" },
2930
2931        [0x20] = { .id   = TUNER_PHILIPS_FQ1216ME,
2932                   .fm   = 1,
2933                   .name = "PHILIPS_FQ1216_MK3" },
2934        [0x21] = { .id   = UNSET, .fm = 1,
2935                   .name = "PHILIPS_FQ1236_MK3" },
2936        [0x22] = { .id   = UNSET,
2937                   .name = "PHILIPS_FI1236_MK3" },
2938        [0x23] = { .id   = UNSET,
2939                   .name = "PHILIPS_FI1216_MK3" },
2940};
2941
2942static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
2943{
2944        const char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
2945                ? gdi_tuner[eeprom_data[0x0d]].name : NULL;
2946
2947        pr_info("GDI: tuner=%s\n", name ? name : "unknown");
2948        if (!name)
2949                return;
2950        core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
2951        core->board.radio.type = gdi_tuner[eeprom_data[0x0d]].fm ?
2952                CX88_RADIO : 0;
2953}
2954
2955/*
2956 * some Divco specific stuff
2957 */
2958static int cx88_dvico_xc2028_callback(struct cx88_core *core,
2959                                      int command, int arg)
2960{
2961        switch (command) {
2962        case XC2028_TUNER_RESET:
2963                switch (core->boardnr) {
2964                case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2965                        /* GPIO-4 xc3028 tuner */
2966
2967                        cx_set(MO_GP0_IO, 0x00001000);
2968                        cx_clear(MO_GP0_IO, 0x00000010);
2969                        msleep(100);
2970                        cx_set(MO_GP0_IO, 0x00000010);
2971                        msleep(100);
2972                        break;
2973                default:
2974                        cx_write(MO_GP0_IO, 0x101000);
2975                        mdelay(5);
2976                        cx_set(MO_GP0_IO, 0x101010);
2977                }
2978                break;
2979        default:
2980                return -EINVAL;
2981        }
2982
2983        return 0;
2984}
2985
2986/*
2987 * some Geniatech specific stuff
2988 */
2989
2990static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core,
2991                                                int command, int mode)
2992{
2993        switch (command) {
2994        case XC2028_TUNER_RESET:
2995                switch (INPUT(core->input).type) {
2996                case CX88_RADIO:
2997                        break;
2998                case CX88_VMUX_DVB:
2999                        cx_write(MO_GP1_IO, 0x030302);
3000                        mdelay(50);
3001                        break;
3002                default:
3003                        cx_write(MO_GP1_IO, 0x030301);
3004                        mdelay(50);
3005                }
3006                cx_write(MO_GP1_IO, 0x101010);
3007                mdelay(50);
3008                cx_write(MO_GP1_IO, 0x101000);
3009                mdelay(50);
3010                cx_write(MO_GP1_IO, 0x101010);
3011                mdelay(50);
3012                return 0;
3013        }
3014        return -EINVAL;
3015}
3016
3017static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core,
3018                                             int command, int arg)
3019{
3020        switch (command) {
3021        case XC2028_TUNER_RESET:
3022                /* GPIO 12 (xc3028 tuner reset) */
3023                cx_set(MO_GP1_IO, 0x1010);
3024                mdelay(50);
3025                cx_clear(MO_GP1_IO, 0x10);
3026                mdelay(75);
3027                cx_set(MO_GP1_IO, 0x10);
3028                mdelay(75);
3029                return 0;
3030        }
3031        return -EINVAL;
3032}
3033
3034static int cx88_xc4000_winfast2000h_plus_callback(struct cx88_core *core,
3035                                                  int command, int arg)
3036{
3037        switch (command) {
3038        case XC4000_TUNER_RESET:
3039                /* GPIO 12 (xc4000 tuner reset) */
3040                cx_set(MO_GP1_IO, 0x1010);
3041                mdelay(50);
3042                cx_clear(MO_GP1_IO, 0x10);
3043                mdelay(75);
3044                cx_set(MO_GP1_IO, 0x10);
3045                mdelay(75);
3046                return 0;
3047        }
3048        return -EINVAL;
3049}
3050
3051/*
3052 * some Divco specific stuff
3053 */
3054static int cx88_pv_8000gt_callback(struct cx88_core *core,
3055                                   int command, int arg)
3056{
3057        switch (command) {
3058        case XC2028_TUNER_RESET:
3059                cx_write(MO_GP2_IO, 0xcf7);
3060                mdelay(50);
3061                cx_write(MO_GP2_IO, 0xef5);
3062                mdelay(50);
3063                cx_write(MO_GP2_IO, 0xcf7);
3064                break;
3065        default:
3066                return -EINVAL;
3067        }
3068
3069        return 0;
3070}
3071
3072/*
3073 * some DViCO specific stuff
3074 */
3075
3076static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
3077{
3078        struct i2c_msg msg = { .addr = 0x45, .flags = 0 };
3079        int i, err;
3080        static u8 init_bufs[13][5] = {
3081                { 0x10, 0x00, 0x20, 0x01, 0x03 },
3082                { 0x10, 0x10, 0x01, 0x00, 0x21 },
3083                { 0x10, 0x10, 0x10, 0x00, 0xCA },
3084                { 0x10, 0x10, 0x12, 0x00, 0x08 },
3085                { 0x10, 0x10, 0x13, 0x00, 0x0A },
3086                { 0x10, 0x10, 0x16, 0x01, 0xC0 },
3087                { 0x10, 0x10, 0x22, 0x01, 0x3D },
3088                { 0x10, 0x10, 0x73, 0x01, 0x2E },
3089                { 0x10, 0x10, 0x72, 0x00, 0xC5 },
3090                { 0x10, 0x10, 0x71, 0x01, 0x97 },
3091                { 0x10, 0x10, 0x70, 0x00, 0x0F },
3092                { 0x10, 0x10, 0xB0, 0x00, 0x01 },
3093                { 0x03, 0x0C },
3094        };
3095
3096        for (i = 0; i < ARRAY_SIZE(init_bufs); i++) {
3097                msg.buf = init_bufs[i];
3098                msg.len = (i != 12 ? 5 : 2);
3099                err = i2c_transfer(&core->i2c_adap, &msg, 1);
3100                if (err != 1) {
3101                        pr_warn("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n",
3102                                i, err);
3103                        return;
3104                }
3105        }
3106}
3107
3108static int cx88_xc2028_tuner_callback(struct cx88_core *core,
3109                                      int command, int arg)
3110{
3111        /* Board-specific callbacks */
3112        switch (core->boardnr) {
3113        case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
3114        case CX88_BOARD_GENIATECH_X8000_MT:
3115        case CX88_BOARD_KWORLD_ATSC_120:
3116                return cx88_xc3028_geniatech_tuner_callback(core,
3117                                                        command, arg);
3118        case CX88_BOARD_PROLINK_PV_8000GT:
3119        case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
3120                return cx88_pv_8000gt_callback(core, command, arg);
3121        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
3122        case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
3123                return cx88_dvico_xc2028_callback(core, command, arg);
3124        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
3125        case CX88_BOARD_WINFAST_DTV1800H:
3126                return cx88_xc3028_winfast1800h_callback(core, command, arg);
3127        }
3128
3129        switch (command) {
3130        case XC2028_TUNER_RESET:
3131                switch (INPUT(core->input).type) {
3132                case CX88_RADIO:
3133                        dprintk(1, "setting GPIO to radio!\n");
3134                        cx_write(MO_GP0_IO, 0x4ff);
3135                        mdelay(250);
3136                        cx_write(MO_GP2_IO, 0xff);
3137                        mdelay(250);
3138                        break;
3139                case CX88_VMUX_DVB:     /* Digital TV*/
3140                default:                /* Analog TV */
3141                        dprintk(1, "setting GPIO to TV!\n");
3142                        break;
3143                }
3144                cx_write(MO_GP1_IO, 0x101010);
3145                mdelay(250);
3146                cx_write(MO_GP1_IO, 0x101000);
3147                mdelay(250);
3148                cx_write(MO_GP1_IO, 0x101010);
3149                mdelay(250);
3150                return 0;
3151        }
3152        return -EINVAL;
3153}
3154
3155static int cx88_xc4000_tuner_callback(struct cx88_core *core,
3156                                      int command, int arg)
3157{
3158        /* Board-specific callbacks */
3159        switch (core->boardnr) {
3160        case CX88_BOARD_WINFAST_DTV1800H_XC4000:
3161        case CX88_BOARD_WINFAST_DTV2000H_PLUS:
3162        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
3163        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
3164                return cx88_xc4000_winfast2000h_plus_callback(core,
3165                                                              command, arg);
3166        }
3167        return -EINVAL;
3168}
3169
3170/*
3171 * Tuner callback function. Currently only needed for the Pinnacle
3172 * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both
3173 * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c)
3174 */
3175static int cx88_xc5000_tuner_callback(struct cx88_core *core,
3176                                      int command, int arg)
3177{
3178        switch (core->boardnr) {
3179        case CX88_BOARD_PINNACLE_PCTV_HD_800i:
3180                if (command == 0) { /* This is the reset command from xc5000 */
3181
3182                        /*
3183                         * djh - According to the engineer at PCTV Systems,
3184                         * the xc5000 reset pin is supposed to be on GPIO12.
3185                         * However, despite three nights of effort, pulling
3186                         * that GPIO low didn't reset the xc5000.  While
3187                         * pulling MO_SRST_IO low does reset the xc5000, this
3188                         * also resets in the s5h1409 being reset as well.
3189                         * This causes tuning to always fail since the internal
3190                         * state of the s5h1409 does not match the driver's
3191                         * state.  Given that the only two conditions in which
3192                         * the driver performs a reset is during firmware load
3193                         * and powering down the chip, I am taking out the
3194                         * reset.  We know that the chip is being reset
3195                         * when the cx88 comes online, and not being able to
3196                         * do power management for this board is worse than
3197                         * not having any tuning at all.
3198                         */
3199                        return 0;
3200                }
3201
3202                dprintk(1, "xc5000: unknown tuner callback command.\n");
3203                return -EINVAL;
3204        case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
3205                if (command == 0) { /* This is the reset command from xc5000 */
3206                        cx_clear(MO_GP0_IO, 0x00000010);
3207                        usleep_range(10000, 20000);
3208                        cx_set(MO_GP0_IO, 0x00000010);
3209                        return 0;
3210                }
3211
3212                dprintk(1, "xc5000: unknown tuner callback command.\n");
3213                return -EINVAL;
3214        }
3215        return 0; /* Should never be here */
3216}
3217
3218int cx88_tuner_callback(void *priv, int component, int command, int arg)
3219{
3220        struct i2c_algo_bit_data *i2c_algo = priv;
3221        struct cx88_core *core;
3222
3223        if (!i2c_algo) {
3224                pr_err("Error - i2c private data undefined.\n");
3225                return -EINVAL;
3226        }
3227
3228        core = i2c_algo->data;
3229
3230        if (!core) {
3231                pr_err("Error - device struct undefined.\n");
3232                return -EINVAL;
3233        }
3234
3235        if (component != DVB_FRONTEND_COMPONENT_TUNER)
3236                return -EINVAL;
3237
3238        switch (core->board.tuner_type) {
3239        case TUNER_XC2028:
3240                dprintk(1, "Calling XC2028/3028 callback\n");
3241                return cx88_xc2028_tuner_callback(core, command, arg);
3242        case TUNER_XC4000:
3243                dprintk(1, "Calling XC4000 callback\n");
3244                return cx88_xc4000_tuner_callback(core, command, arg);
3245        case TUNER_XC5000:
3246                dprintk(1, "Calling XC5000 callback\n");
3247                return cx88_xc5000_tuner_callback(core, command, arg);
3248        }
3249        pr_err("Error: Calling callback for tuner %d\n",
3250               core->board.tuner_type);
3251        return -EINVAL;
3252}
3253EXPORT_SYMBOL(cx88_tuner_callback);
3254
3255/* ----------------------------------------------------------------------- */
3256
3257static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
3258{
3259        int i;
3260
3261        if (!pci->subsystem_vendor && !pci->subsystem_device) {
3262                pr_err("Your board has no valid PCI Subsystem ID and thus can't\n");
3263                pr_err("be autodetected.  Please pass card=<n> insmod option to\n");
3264                pr_err("workaround that.  Redirect complaints to the vendor of\n");
3265                pr_err("the TV card\n");
3266        } else {
3267                pr_err("Your board isn't known (yet) to the driver.  You can\n");
3268                pr_err("try to pick one of the existing card configs via\n");
3269                pr_err("card=<n> insmod option.  Updating to the latest\n");
3270                pr_err("version might help as well.\n");
3271        }
3272        pr_err("Here is a list of valid choices for the card=<n> insmod option:\n");
3273        for (i = 0; i < ARRAY_SIZE(cx88_boards); i++)
3274                pr_err("    card=%d -> %s\n", i, cx88_boards[i].name);
3275}
3276
3277static void cx88_card_setup_pre_i2c(struct cx88_core *core)
3278{
3279        switch (core->boardnr) {
3280        case CX88_BOARD_HAUPPAUGE_HVR1300:
3281                /*
3282                 * Bring the 702 demod up before i2c scanning/attach or
3283                 * devices are hidden.
3284                 *
3285                 * We leave here with the 702 on the bus
3286                 *
3287                 * "reset the IR receiver on GPIO[3]"
3288                 * Reported by Mike Crash <mike AT mikecrash.com>
3289                 */
3290                cx_write(MO_GP0_IO, 0x0000ef88);
3291                udelay(1000);
3292                cx_clear(MO_GP0_IO, 0x00000088);
3293                udelay(50);
3294                cx_set(MO_GP0_IO, 0x00000088); /* 702 out of reset */
3295                udelay(1000);
3296                break;
3297
3298        case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
3299        case CX88_BOARD_PROLINK_PV_8000GT:
3300                cx_write(MO_GP2_IO, 0xcf7);
3301                msleep(50);
3302                cx_write(MO_GP2_IO, 0xef5);
3303                msleep(50);
3304                cx_write(MO_GP2_IO, 0xcf7);
3305                usleep_range(10000, 20000);
3306                break;
3307
3308        case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
3309                /* Enable the xc5000 tuner */
3310                cx_set(MO_GP0_IO, 0x00001010);
3311                break;
3312
3313        case CX88_BOARD_WINFAST_DTV2000H_J:
3314        case CX88_BOARD_HAUPPAUGE_HVR3000:
3315        case CX88_BOARD_HAUPPAUGE_HVR4000:
3316                /* Init GPIO */
3317                cx_write(MO_GP0_IO, core->board.input[0].gpio0);
3318                udelay(1000);
3319                cx_clear(MO_GP0_IO, 0x00000080);
3320                udelay(50);
3321                cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
3322                udelay(1000);
3323                break;
3324
3325        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
3326        case CX88_BOARD_WINFAST_DTV1800H:
3327                cx88_xc3028_winfast1800h_callback(core, XC2028_TUNER_RESET, 0);
3328                break;
3329
3330        case CX88_BOARD_WINFAST_DTV1800H_XC4000:
3331        case CX88_BOARD_WINFAST_DTV2000H_PLUS:
3332        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
3333        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
3334                cx88_xc4000_winfast2000h_plus_callback(core,
3335                                                       XC4000_TUNER_RESET, 0);
3336                break;
3337
3338        case CX88_BOARD_TWINHAN_VP1027_DVBS:
3339                cx_write(MO_GP0_IO, 0x00003230);
3340                cx_write(MO_GP0_IO, 0x00003210);
3341                usleep_range(10000, 20000);
3342                cx_write(MO_GP0_IO, 0x00001230);
3343                break;
3344        }
3345}
3346
3347/*
3348 * Sets board-dependent xc3028 configuration
3349 */
3350void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
3351{
3352        memset(ctl, 0, sizeof(*ctl));
3353
3354        ctl->fname   = XC2028_DEFAULT_FIRMWARE;
3355        ctl->max_len = 64;
3356
3357        switch (core->boardnr) {
3358        case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
3359                /* Now works with firmware version 2.7 */
3360                if (core->i2c_algo.udelay < 16)
3361                        core->i2c_algo.udelay = 16;
3362                break;
3363        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
3364        case CX88_BOARD_WINFAST_DTV1800H:
3365                ctl->demod = XC3028_FE_ZARLINK456;
3366                break;
3367        case CX88_BOARD_KWORLD_ATSC_120:
3368        case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
3369                ctl->demod = XC3028_FE_OREN538;
3370                break;
3371        case CX88_BOARD_GENIATECH_X8000_MT:
3372                /*
3373                 * FIXME: For this board, the xc3028 never recovers after being
3374                 * powered down (the reset GPIO probably is not set properly).
3375                 * We don't have access to the hardware so we cannot determine
3376                 * which GPIO is used for xc3028, so just disable power xc3028
3377                 * power management for now
3378                 */
3379                ctl->disable_power_mgmt = 1;
3380                break;
3381        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
3382        case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
3383        case CX88_BOARD_PROLINK_PV_8000GT:
3384                /*
3385                 * Those boards uses non-MTS firmware
3386                 */
3387                break;
3388        case CX88_BOARD_PINNACLE_HYBRID_PCTV:
3389        case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
3390                ctl->demod = XC3028_FE_ZARLINK456;
3391                ctl->mts = 1;
3392                break;
3393        default:
3394                ctl->demod = XC3028_FE_OREN538;
3395                ctl->mts = 1;
3396        }
3397}
3398EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
3399
3400static void cx88_card_setup(struct cx88_core *core)
3401{
3402        static u8 eeprom[256];
3403        struct tuner_setup tun_setup;
3404        unsigned int mode_mask = T_RADIO | T_ANALOG_TV;
3405
3406        memset(&tun_setup, 0, sizeof(tun_setup));
3407
3408        if (!core->i2c_rc) {
3409                core->i2c_client.addr = 0xa0 >> 1;
3410                tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom));
3411        }
3412
3413        switch (core->boardnr) {
3414        case CX88_BOARD_HAUPPAUGE:
3415        case CX88_BOARD_HAUPPAUGE_ROSLYN:
3416                if (!core->i2c_rc)
3417                        hauppauge_eeprom(core, eeprom + 8);
3418                break;
3419        case CX88_BOARD_GDI:
3420                if (!core->i2c_rc)
3421                        gdi_eeprom(core, eeprom);
3422                break;
3423        case CX88_BOARD_LEADTEK_PVR2000:
3424        case CX88_BOARD_WINFAST_DV2000:
3425        case CX88_BOARD_WINFAST2000XP_EXPERT:
3426                if (!core->i2c_rc)
3427                        leadtek_eeprom(core, eeprom);
3428                break;
3429        case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
3430        case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
3431        case CX88_BOARD_HAUPPAUGE_DVB_T1:
3432        case CX88_BOARD_HAUPPAUGE_HVR1100:
3433        case CX88_BOARD_HAUPPAUGE_HVR1100LP:
3434        case CX88_BOARD_HAUPPAUGE_HVR3000:
3435        case CX88_BOARD_HAUPPAUGE_HVR1300:
3436        case CX88_BOARD_HAUPPAUGE_HVR4000:
3437        case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
3438        case CX88_BOARD_HAUPPAUGE_IRONLY:
3439                if (!core->i2c_rc)
3440                        hauppauge_eeprom(core, eeprom);
3441                break;
3442        case CX88_BOARD_KWORLD_DVBS_100:
3443                cx_write(MO_GP0_IO, 0x000007f8);
3444                cx_write(MO_GP1_IO, 0x00000001);
3445                break;
3446        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
3447                /* GPIO0:0 is hooked to demod reset */
3448                /* GPIO0:4 is hooked to xc3028 reset */
3449                cx_write(MO_GP0_IO, 0x00111100);
3450                usleep_range(10000, 20000);
3451                cx_write(MO_GP0_IO, 0x00111111);
3452                break;
3453        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
3454                /* GPIO0:6 is hooked to FX2 reset pin */
3455                cx_set(MO_GP0_IO, 0x00004040);
3456                cx_clear(MO_GP0_IO, 0x00000040);
3457                msleep(1000);
3458                cx_set(MO_GP0_IO, 0x00004040);
3459                /* FALLTHROUGH */
3460        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
3461        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
3462        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
3463                /* GPIO0:0 is hooked to mt352 reset pin */
3464                cx_set(MO_GP0_IO, 0x00000101);
3465                cx_clear(MO_GP0_IO, 0x00000001);
3466                usleep_range(10000, 20000);
3467                cx_set(MO_GP0_IO, 0x00000101);
3468                if (!core->i2c_rc &&
3469                    core->boardnr == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
3470                        dvico_fusionhdtv_hybrid_init(core);
3471                break;
3472        case CX88_BOARD_KWORLD_DVB_T:
3473        case CX88_BOARD_DNTV_LIVE_DVB_T:
3474                cx_set(MO_GP0_IO, 0x00000707);
3475                cx_set(MO_GP2_IO, 0x00000101);
3476                cx_clear(MO_GP2_IO, 0x00000001);
3477                usleep_range(10000, 20000);
3478                cx_clear(MO_GP0_IO, 0x00000007);
3479                cx_set(MO_GP2_IO, 0x00000101);
3480                break;
3481        case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
3482                cx_write(MO_GP0_IO, 0x00080808);
3483                break;
3484        case CX88_BOARD_ATI_HDTVWONDER:
3485                if (!core->i2c_rc) {
3486                        /* enable tuner */
3487                        int i;
3488                        static const u8 buffer[][2] = {
3489                                {0x10, 0x12},
3490                                {0x13, 0x04},
3491                                {0x16, 0x00},
3492                                {0x14, 0x04},
3493                                {0x17, 0x00}
3494                        };
3495                        core->i2c_client.addr = 0x0a;
3496
3497                        for (i = 0; i < ARRAY_SIZE(buffer); i++)
3498                                if (i2c_master_send(&core->i2c_client,
3499                                                    buffer[i], 2) != 2)
3500                                        pr_warn("Unable to enable tuner(%i).\n",
3501                                                i);
3502                }
3503                break;
3504        case CX88_BOARD_MSI_TVANYWHERE_MASTER:
3505        {
3506                struct v4l2_priv_tun_config tea5767_cfg;
3507                struct tea5767_ctrl ctl;
3508
3509                memset(&ctl, 0, sizeof(ctl));
3510
3511                ctl.high_cut  = 1;
3512                ctl.st_noise  = 1;
3513                ctl.deemph_75 = 1;
3514                ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
3515
3516                tea5767_cfg.tuner = TUNER_TEA5767;
3517                tea5767_cfg.priv  = &ctl;
3518
3519                call_all(core, tuner, s_config, &tea5767_cfg);
3520                break;
3521        }
3522        case  CX88_BOARD_TEVII_S420:
3523        case  CX88_BOARD_TEVII_S460:
3524        case  CX88_BOARD_TEVII_S464:
3525        case  CX88_BOARD_OMICOM_SS4_PCI:
3526        case  CX88_BOARD_TBS_8910:
3527        case  CX88_BOARD_TBS_8920:
3528        case  CX88_BOARD_PROF_6200:
3529        case  CX88_BOARD_PROF_7300:
3530        case  CX88_BOARD_PROF_7301:
3531        case  CX88_BOARD_SATTRADE_ST4200:
3532                cx_write(MO_GP0_IO, 0x8000);
3533                msleep(100);
3534                cx_write(MO_SRST_IO, 0);
3535                usleep_range(10000, 20000);
3536                cx_write(MO_GP0_IO, 0x8080);
3537                msleep(100);
3538                cx_write(MO_SRST_IO, 1);
3539                msleep(100);
3540                break;
3541        } /*end switch() */
3542
3543        /* Setup tuners */
3544        if (core->board.radio_type != UNSET) {
3545                tun_setup.mode_mask      = T_RADIO;
3546                tun_setup.type           = core->board.radio_type;
3547                tun_setup.addr           = core->board.radio_addr;
3548                tun_setup.tuner_callback = cx88_tuner_callback;
3549                call_all(core, tuner, s_type_addr, &tun_setup);
3550                mode_mask &= ~T_RADIO;
3551        }
3552
3553        if (core->board.tuner_type != UNSET) {
3554                tun_setup.mode_mask      = mode_mask;
3555                tun_setup.type           = core->board.tuner_type;
3556                tun_setup.addr           = core->board.tuner_addr;
3557                tun_setup.tuner_callback = cx88_tuner_callback;
3558
3559                call_all(core, tuner, s_type_addr, &tun_setup);
3560        }
3561
3562        if (core->board.tda9887_conf) {
3563                struct v4l2_priv_tun_config tda9887_cfg;
3564
3565                tda9887_cfg.tuner = TUNER_TDA9887;
3566                tda9887_cfg.priv  = &core->board.tda9887_conf;
3567
3568                call_all(core, tuner, s_config, &tda9887_cfg);
3569        }
3570
3571        if (core->board.tuner_type == TUNER_XC2028) {
3572                struct v4l2_priv_tun_config  xc2028_cfg;
3573                struct xc2028_ctrl           ctl;
3574
3575                /* Fills device-dependent initialization parameters */
3576                cx88_setup_xc3028(core, &ctl);
3577
3578                /* Sends parameters to xc2028/3028 tuner */
3579                memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
3580                xc2028_cfg.tuner = TUNER_XC2028;
3581                xc2028_cfg.priv  = &ctl;
3582                dprintk(1, "Asking xc2028/3028 to load firmware %s\n",
3583                        ctl.fname);
3584                call_all(core, tuner, s_config, &xc2028_cfg);
3585        }
3586        call_all(core, tuner, standby);
3587}
3588
3589/* ------------------------------------------------------------------ */
3590
3591static int cx88_pci_quirks(const char *name, struct pci_dev *pci)
3592{
3593        unsigned int lat = UNSET;
3594        u8 ctrl = 0;
3595        u8 value;
3596
3597        /* check pci quirks */
3598        if (pci_pci_problems & PCIPCI_TRITON) {
3599                pr_info("quirk: PCIPCI_TRITON -- set TBFX\n");
3600                ctrl |= CX88X_EN_TBFX;
3601        }
3602        if (pci_pci_problems & PCIPCI_NATOMA) {
3603                pr_info("quirk: PCIPCI_NATOMA -- set TBFX\n");
3604                ctrl |= CX88X_EN_TBFX;
3605        }
3606        if (pci_pci_problems & PCIPCI_VIAETBF) {
3607                pr_info("quirk: PCIPCI_VIAETBF -- set TBFX\n");
3608                ctrl |= CX88X_EN_TBFX;
3609        }
3610        if (pci_pci_problems & PCIPCI_VSFX) {
3611                pr_info("quirk: PCIPCI_VSFX -- set VSFX\n");
3612                ctrl |= CX88X_EN_VSFX;
3613        }
3614#ifdef PCIPCI_ALIMAGIK
3615        if (pci_pci_problems & PCIPCI_ALIMAGIK) {
3616                pr_info("quirk: PCIPCI_ALIMAGIK -- latency fixup\n");
3617                lat = 0x0A;
3618        }
3619#endif
3620
3621        /* check insmod options */
3622        if (latency != UNSET)
3623                lat = latency;
3624
3625        /* apply stuff */
3626        if (ctrl) {
3627                pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
3628                value |= ctrl;
3629                pci_write_config_byte(pci, CX88X_DEVCTRL, value);
3630        }
3631        if (lat != UNSET) {
3632                pr_info("setting pci latency timer to %d\n", latency);
3633                pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
3634        }
3635        return 0;
3636}
3637
3638int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci)
3639{
3640        if (request_mem_region(pci_resource_start(pci, 0),
3641                               pci_resource_len(pci, 0),
3642                               core->name))
3643                return 0;
3644        pr_err("func %d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n",
3645               PCI_FUNC(pci->devfn),
3646               (unsigned long long)pci_resource_start(pci, 0),
3647               pci->subsystem_vendor, pci->subsystem_device);
3648        return -EBUSY;
3649}
3650
3651/*
3652 * Allocate and initialize the cx88 core struct.  One should hold the
3653 * devlist mutex before calling this.
3654 */
3655struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
3656{
3657        struct cx88_core *core;
3658        int i;
3659
3660        core = kzalloc(sizeof(*core), GFP_KERNEL);
3661        if (!core)
3662                return NULL;
3663
3664        refcount_set(&core->refcount, 1);
3665        core->pci_bus  = pci->bus->number;
3666        core->pci_slot = PCI_SLOT(pci->devfn);
3667        core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT |
3668                            PCI_INT_BRDG_BERRINT | PCI_INT_SRC_DMA_BERRINT |
3669                            PCI_INT_DST_DMA_BERRINT | PCI_INT_IPB_DMA_BERRINT;
3670        mutex_init(&core->lock);
3671
3672        core->nr = nr;
3673        sprintf(core->name, "cx88[%d]", core->nr);
3674
3675        /*
3676         * Note: Setting initial standard here would cause first call to
3677         * cx88_set_tvnorm() to return without programming any registers.  Leave
3678         * it blank for at this point and it will get set later in
3679         * cx8800_initdev()
3680         */
3681        core->tvnorm  = 0;
3682
3683        core->width   = 320;
3684        core->height  = 240;
3685        core->field   = V4L2_FIELD_INTERLACED;
3686
3687        strscpy(core->v4l2_dev.name, core->name, sizeof(core->v4l2_dev.name));
3688        if (v4l2_device_register(NULL, &core->v4l2_dev)) {
3689                kfree(core);
3690                return NULL;
3691        }
3692
3693        if (v4l2_ctrl_handler_init(&core->video_hdl, 13)) {
3694                v4l2_device_unregister(&core->v4l2_dev);
3695                kfree(core);
3696                return NULL;
3697        }
3698
3699        if (v4l2_ctrl_handler_init(&core->audio_hdl, 13)) {
3700                v4l2_ctrl_handler_free(&core->video_hdl);
3701                v4l2_device_unregister(&core->v4l2_dev);
3702                kfree(core);
3703                return NULL;
3704        }
3705
3706        if (cx88_get_resources(core, pci) != 0) {
3707                v4l2_ctrl_handler_free(&core->video_hdl);
3708                v4l2_ctrl_handler_free(&core->audio_hdl);
3709                v4l2_device_unregister(&core->v4l2_dev);
3710                kfree(core);
3711                return NULL;
3712        }
3713
3714        /* PCI stuff */
3715        cx88_pci_quirks(core->name, pci);
3716        core->lmmio = ioremap(pci_resource_start(pci, 0),
3717                              pci_resource_len(pci, 0));
3718        core->bmmio = (u8 __iomem *)core->lmmio;
3719
3720        if (!core->lmmio) {
3721                release_mem_region(pci_resource_start(pci, 0),
3722                                   pci_resource_len(pci, 0));
3723                v4l2_ctrl_handler_free(&core->video_hdl);
3724                v4l2_ctrl_handler_free(&core->audio_hdl);
3725                v4l2_device_unregister(&core->v4l2_dev);
3726                kfree(core);
3727                return NULL;
3728        }
3729
3730        /* board config */
3731        core->boardnr = UNSET;
3732        if (card[core->nr] < ARRAY_SIZE(cx88_boards))
3733                core->boardnr = card[core->nr];
3734        for (i = 0; core->boardnr == UNSET && i < ARRAY_SIZE(cx88_subids); i++)
3735                if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
3736                    pci->subsystem_device == cx88_subids[i].subdevice)
3737                        core->boardnr = cx88_subids[i].card;
3738        if (core->boardnr == UNSET) {
3739                core->boardnr = CX88_BOARD_UNKNOWN;
3740                cx88_card_list(core, pci);
3741        }
3742
3743        core->board = cx88_boards[core->boardnr];
3744
3745        if (!core->board.num_frontends && (core->board.mpeg & CX88_MPEG_DVB))
3746                core->board.num_frontends = 1;
3747
3748        pr_info("subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
3749                pci->subsystem_vendor, pci->subsystem_device, core->board.name,
3750                core->boardnr, card[core->nr] == core->boardnr ?
3751                "insmod option" : "autodetected",
3752                core->board.num_frontends);
3753
3754        if (tuner[core->nr] != UNSET)
3755                core->board.tuner_type = tuner[core->nr];
3756        if (radio[core->nr] != UNSET)
3757                core->board.radio_type = radio[core->nr];
3758
3759        dprintk(1, "TV tuner type %d, Radio tuner type %d\n",
3760                core->board.tuner_type, core->board.radio_type);
3761
3762        /* init hardware */
3763        cx88_reset(core);
3764        cx88_card_setup_pre_i2c(core);
3765        cx88_i2c_init(core, pci);
3766
3767        /* load tuner module, if needed */
3768        if (core->board.tuner_type != UNSET) {
3769                /*
3770                 * Ignore 0x6b and 0x6f on cx88 boards.
3771                 * FusionHDTV5 RT Gold has an ir receiver at 0x6b
3772                 * and an RTC at 0x6f which can get corrupted if probed.
3773                 */
3774                static const unsigned short tv_addrs[] = {
3775                        0x42, 0x43, 0x4a, 0x4b,         /* tda8290 */
3776                        0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
3777                        0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e,
3778                        I2C_CLIENT_END
3779                };
3780                int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT);
3781
3782                /*
3783                 * I don't trust the radio_type as is stored in the card
3784                 * definitions, so we just probe for it.
3785                 * The radio_type is sometimes missing, or set to UNSET but
3786                 * later code configures a tea5767.
3787                 */
3788                v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
3789                                    "tuner", 0,
3790                                    v4l2_i2c_tuner_addrs(ADDRS_RADIO));
3791                if (has_demod)
3792                        v4l2_i2c_new_subdev(&core->v4l2_dev,
3793                                            &core->i2c_adap, "tuner",
3794                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
3795                if (core->board.tuner_addr == ADDR_UNSET) {
3796                        v4l2_i2c_new_subdev(&core->v4l2_dev,
3797                                            &core->i2c_adap, "tuner",
3798                                0, has_demod ? tv_addrs + 4 : tv_addrs);
3799                } else {
3800                        v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
3801                                            "tuner", core->board.tuner_addr,
3802                                            NULL);
3803                }
3804        }
3805
3806        cx88_card_setup(core);
3807        if (!disable_ir) {
3808                cx88_i2c_init_ir(core);
3809                cx88_ir_init(core, pci);
3810        }
3811
3812        return core;
3813}
3814