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