linux/drivers/media/pci/saa7164/saa7164-cards.c
<<
>>
Prefs
   1/*
   2 *  Driver for the NXP SAA7164 PCIe bridge
   3 *
   4 *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *
  15 *  GNU General Public License for more details.
  16 */
  17
  18#include <linux/init.h>
  19#include <linux/module.h>
  20#include <linux/pci.h>
  21#include <linux/delay.h>
  22
  23#include "saa7164.h"
  24
  25/* The Bridge API needs to understand register widths (in bytes) for the
  26 * attached I2C devices, so we can simplify the virtual i2c mechansms
  27 * and keep the -i2c.c implementation clean.
  28 */
  29#define REGLEN_0bit     0
  30#define REGLEN_8bit     1
  31#define REGLEN_16bit    2
  32
  33struct saa7164_board saa7164_boards[] = {
  34        [SAA7164_BOARD_UNKNOWN] = {
  35                /* Bridge will not load any firmware, without knowing
  36                 * the rev this would be fatal. */
  37                .name           = "Unknown",
  38        },
  39        [SAA7164_BOARD_UNKNOWN_REV2] = {
  40                /* Bridge will load the v2 f/w and dump descriptors */
  41                /* Required during new board bringup */
  42                .name           = "Generic Rev2",
  43                .chiprev        = SAA7164_CHIP_REV2,
  44        },
  45        [SAA7164_BOARD_UNKNOWN_REV3] = {
  46                /* Bridge will load the v2 f/w and dump descriptors */
  47                /* Required during new board bringup */
  48                .name           = "Generic Rev3",
  49                .chiprev        = SAA7164_CHIP_REV3,
  50        },
  51        [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
  52                .name           = "Hauppauge WinTV-HVR2200",
  53                .porta          = SAA7164_MPEG_DVB,
  54                .portb          = SAA7164_MPEG_DVB,
  55                .portc          = SAA7164_MPEG_ENCODER,
  56                .portd          = SAA7164_MPEG_ENCODER,
  57                .porte          = SAA7164_MPEG_VBI,
  58                .portf          = SAA7164_MPEG_VBI,
  59                .chiprev        = SAA7164_CHIP_REV3,
  60                .unit           = {{
  61                        .id             = 0x1d,
  62                        .type           = SAA7164_UNIT_EEPROM,
  63                        .name           = "4K EEPROM",
  64                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
  65                        .i2c_bus_addr   = 0xa0 >> 1,
  66                        .i2c_reg_len    = REGLEN_8bit,
  67                }, {
  68                        .id             = 0x04,
  69                        .type           = SAA7164_UNIT_TUNER,
  70                        .name           = "TDA18271-1",
  71                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
  72                        .i2c_bus_addr   = 0xc0 >> 1,
  73                        .i2c_reg_len    = REGLEN_8bit,
  74                }, {
  75                        .id             = 0x1b,
  76                        .type           = SAA7164_UNIT_TUNER,
  77                        .name           = "TDA18271-2",
  78                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
  79                        .i2c_bus_addr   = 0xc0 >> 1,
  80                        .i2c_reg_len    = REGLEN_8bit,
  81                }, {
  82                        .id             = 0x1e,
  83                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
  84                        .name           = "TDA10048-1",
  85                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
  86                        .i2c_bus_addr   = 0x10 >> 1,
  87                        .i2c_reg_len    = REGLEN_8bit,
  88                }, {
  89                        .id             = 0x1f,
  90                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
  91                        .name           = "TDA10048-2",
  92                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
  93                        .i2c_bus_addr   = 0x12 >> 1,
  94                        .i2c_reg_len    = REGLEN_8bit,
  95                } },
  96        },
  97        [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
  98                .name           = "Hauppauge WinTV-HVR2200",
  99                .porta          = SAA7164_MPEG_DVB,
 100                .portb          = SAA7164_MPEG_DVB,
 101                .portc          = SAA7164_MPEG_ENCODER,
 102                .portd          = SAA7164_MPEG_ENCODER,
 103                .porte          = SAA7164_MPEG_VBI,
 104                .portf          = SAA7164_MPEG_VBI,
 105                .chiprev        = SAA7164_CHIP_REV2,
 106                .unit           = {{
 107                        .id             = 0x06,
 108                        .type           = SAA7164_UNIT_EEPROM,
 109                        .name           = "4K EEPROM",
 110                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 111                        .i2c_bus_addr   = 0xa0 >> 1,
 112                        .i2c_reg_len    = REGLEN_8bit,
 113                }, {
 114                        .id             = 0x04,
 115                        .type           = SAA7164_UNIT_TUNER,
 116                        .name           = "TDA18271-1",
 117                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 118                        .i2c_bus_addr   = 0xc0 >> 1,
 119                        .i2c_reg_len    = REGLEN_8bit,
 120                }, {
 121                        .id             = 0x05,
 122                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 123                        .name           = "TDA10048-1",
 124                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 125                        .i2c_bus_addr   = 0x10 >> 1,
 126                        .i2c_reg_len    = REGLEN_8bit,
 127                }, {
 128                        .id             = 0x1e,
 129                        .type           = SAA7164_UNIT_TUNER,
 130                        .name           = "TDA18271-2",
 131                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 132                        .i2c_bus_addr   = 0xc0 >> 1,
 133                        .i2c_reg_len    = REGLEN_8bit,
 134                }, {
 135                        .id             = 0x1f,
 136                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 137                        .name           = "TDA10048-2",
 138                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 139                        .i2c_bus_addr   = 0x12 >> 1,
 140                        .i2c_reg_len    = REGLEN_8bit,
 141                } },
 142        },
 143        [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
 144                .name           = "Hauppauge WinTV-HVR2200",
 145                .porta          = SAA7164_MPEG_DVB,
 146                .portb          = SAA7164_MPEG_DVB,
 147                .portc          = SAA7164_MPEG_ENCODER,
 148                .portd          = SAA7164_MPEG_ENCODER,
 149                .porte          = SAA7164_MPEG_VBI,
 150                .portf          = SAA7164_MPEG_VBI,
 151                .chiprev        = SAA7164_CHIP_REV2,
 152                .unit           = {{
 153                        .id             = 0x1d,
 154                        .type           = SAA7164_UNIT_EEPROM,
 155                        .name           = "4K EEPROM",
 156                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 157                        .i2c_bus_addr   = 0xa0 >> 1,
 158                        .i2c_reg_len    = REGLEN_8bit,
 159                }, {
 160                        .id             = 0x04,
 161                        .type           = SAA7164_UNIT_TUNER,
 162                        .name           = "TDA18271-1",
 163                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 164                        .i2c_bus_addr   = 0xc0 >> 1,
 165                        .i2c_reg_len    = REGLEN_8bit,
 166                }, {
 167                        .id             = 0x05,
 168                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 169                        .name           = "TDA8290-1",
 170                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 171                        .i2c_bus_addr   = 0x84 >> 1,
 172                        .i2c_reg_len    = REGLEN_8bit,
 173                }, {
 174                        .id             = 0x1b,
 175                        .type           = SAA7164_UNIT_TUNER,
 176                        .name           = "TDA18271-2",
 177                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 178                        .i2c_bus_addr   = 0xc0 >> 1,
 179                        .i2c_reg_len    = REGLEN_8bit,
 180                }, {
 181                        .id             = 0x1c,
 182                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 183                        .name           = "TDA8290-2",
 184                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 185                        .i2c_bus_addr   = 0x84 >> 1,
 186                        .i2c_reg_len    = REGLEN_8bit,
 187                }, {
 188                        .id             = 0x1e,
 189                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 190                        .name           = "TDA10048-1",
 191                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 192                        .i2c_bus_addr   = 0x10 >> 1,
 193                        .i2c_reg_len    = REGLEN_8bit,
 194                }, {
 195                        .id             = 0x1f,
 196                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 197                        .name           = "TDA10048-2",
 198                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 199                        .i2c_bus_addr   = 0x12 >> 1,
 200                        .i2c_reg_len    = REGLEN_8bit,
 201                } },
 202        },
 203        [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = {
 204                .name           = "Hauppauge WinTV-HVR2200",
 205                .porta          = SAA7164_MPEG_DVB,
 206                .portb          = SAA7164_MPEG_DVB,
 207                .portc          = SAA7164_MPEG_ENCODER,
 208                .portd          = SAA7164_MPEG_ENCODER,
 209                .porte          = SAA7164_MPEG_VBI,
 210                .portf          = SAA7164_MPEG_VBI,
 211                .chiprev        = SAA7164_CHIP_REV3,
 212                .unit           = {{
 213                        .id             = 0x1d,
 214                        .type           = SAA7164_UNIT_EEPROM,
 215                        .name           = "4K EEPROM",
 216                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 217                        .i2c_bus_addr   = 0xa0 >> 1,
 218                        .i2c_reg_len    = REGLEN_8bit,
 219                }, {
 220                        .id             = 0x04,
 221                        .type           = SAA7164_UNIT_TUNER,
 222                        .name           = "TDA18271-1",
 223                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 224                        .i2c_bus_addr   = 0xc0 >> 1,
 225                        .i2c_reg_len    = REGLEN_8bit,
 226                }, {
 227                        .id             = 0x05,
 228                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 229                        .name           = "TDA8290-1",
 230                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 231                        .i2c_bus_addr   = 0x84 >> 1,
 232                        .i2c_reg_len    = REGLEN_8bit,
 233                }, {
 234                        .id             = 0x1b,
 235                        .type           = SAA7164_UNIT_TUNER,
 236                        .name           = "TDA18271-2",
 237                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 238                        .i2c_bus_addr   = 0xc0 >> 1,
 239                        .i2c_reg_len    = REGLEN_8bit,
 240                }, {
 241                        .id             = 0x1c,
 242                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 243                        .name           = "TDA8290-2",
 244                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 245                        .i2c_bus_addr   = 0x84 >> 1,
 246                        .i2c_reg_len    = REGLEN_8bit,
 247                }, {
 248                        .id             = 0x1e,
 249                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 250                        .name           = "TDA10048-1",
 251                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 252                        .i2c_bus_addr   = 0x10 >> 1,
 253                        .i2c_reg_len    = REGLEN_8bit,
 254                }, {
 255                        .id             = 0x1f,
 256                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 257                        .name           = "TDA10048-2",
 258                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 259                        .i2c_bus_addr   = 0x12 >> 1,
 260                        .i2c_reg_len    = REGLEN_8bit,
 261                } },
 262        },
 263        [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
 264                .name           = "Hauppauge WinTV-HVR2250",
 265                .porta          = SAA7164_MPEG_DVB,
 266                .portb          = SAA7164_MPEG_DVB,
 267                .portc          = SAA7164_MPEG_ENCODER,
 268                .portd          = SAA7164_MPEG_ENCODER,
 269                .porte          = SAA7164_MPEG_VBI,
 270                .portf          = SAA7164_MPEG_VBI,
 271                .chiprev        = SAA7164_CHIP_REV3,
 272                .unit           = {{
 273                        .id             = 0x22,
 274                        .type           = SAA7164_UNIT_EEPROM,
 275                        .name           = "4K EEPROM",
 276                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 277                        .i2c_bus_addr   = 0xa0 >> 1,
 278                        .i2c_reg_len    = REGLEN_8bit,
 279                }, {
 280                        .id             = 0x04,
 281                        .type           = SAA7164_UNIT_TUNER,
 282                        .name           = "TDA18271-1",
 283                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 284                        .i2c_bus_addr   = 0xc0 >> 1,
 285                        .i2c_reg_len    = REGLEN_8bit,
 286                }, {
 287                        .id             = 0x07,
 288                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 289                        .name           = "CX24228/S5H1411-1 (TOP)",
 290                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 291                        .i2c_bus_addr   = 0x32 >> 1,
 292                        .i2c_reg_len    = REGLEN_8bit,
 293                }, {
 294                        .id             = 0x08,
 295                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 296                        .name           = "CX24228/S5H1411-1 (QAM)",
 297                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 298                        .i2c_bus_addr   = 0x34 >> 1,
 299                        .i2c_reg_len    = REGLEN_8bit,
 300                }, {
 301                        .id             = 0x1e,
 302                        .type           = SAA7164_UNIT_TUNER,
 303                        .name           = "TDA18271-2",
 304                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 305                        .i2c_bus_addr   = 0xc0 >> 1,
 306                        .i2c_reg_len    = REGLEN_8bit,
 307                }, {
 308                        .id             = 0x20,
 309                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 310                        .name           = "CX24228/S5H1411-2 (TOP)",
 311                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 312                        .i2c_bus_addr   = 0x32 >> 1,
 313                        .i2c_reg_len    = REGLEN_8bit,
 314                }, {
 315                        .id             = 0x23,
 316                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 317                        .name           = "CX24228/S5H1411-2 (QAM)",
 318                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 319                        .i2c_bus_addr   = 0x34 >> 1,
 320                        .i2c_reg_len    = REGLEN_8bit,
 321                } },
 322        },
 323        [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
 324                .name           = "Hauppauge WinTV-HVR2250",
 325                .porta          = SAA7164_MPEG_DVB,
 326                .portb          = SAA7164_MPEG_DVB,
 327                .portc          = SAA7164_MPEG_ENCODER,
 328                .portd          = SAA7164_MPEG_ENCODER,
 329                .porte          = SAA7164_MPEG_VBI,
 330                .portf          = SAA7164_MPEG_VBI,
 331                .chiprev        = SAA7164_CHIP_REV3,
 332                .unit           = {{
 333                        .id             = 0x28,
 334                        .type           = SAA7164_UNIT_EEPROM,
 335                        .name           = "4K EEPROM",
 336                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 337                        .i2c_bus_addr   = 0xa0 >> 1,
 338                        .i2c_reg_len    = REGLEN_8bit,
 339                }, {
 340                        .id             = 0x04,
 341                        .type           = SAA7164_UNIT_TUNER,
 342                        .name           = "TDA18271-1",
 343                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 344                        .i2c_bus_addr   = 0xc0 >> 1,
 345                        .i2c_reg_len    = REGLEN_8bit,
 346                }, {
 347                        .id             = 0x07,
 348                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 349                        .name           = "CX24228/S5H1411-1 (TOP)",
 350                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 351                        .i2c_bus_addr   = 0x32 >> 1,
 352                        .i2c_reg_len    = REGLEN_8bit,
 353                }, {
 354                        .id             = 0x08,
 355                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 356                        .name           = "CX24228/S5H1411-1 (QAM)",
 357                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 358                        .i2c_bus_addr   = 0x34 >> 1,
 359                        .i2c_reg_len    = REGLEN_8bit,
 360                }, {
 361                        .id             = 0x24,
 362                        .type           = SAA7164_UNIT_TUNER,
 363                        .name           = "TDA18271-2",
 364                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 365                        .i2c_bus_addr   = 0xc0 >> 1,
 366                        .i2c_reg_len    = REGLEN_8bit,
 367                }, {
 368                        .id             = 0x26,
 369                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 370                        .name           = "CX24228/S5H1411-2 (TOP)",
 371                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 372                        .i2c_bus_addr   = 0x32 >> 1,
 373                        .i2c_reg_len    = REGLEN_8bit,
 374                }, {
 375                        .id             = 0x29,
 376                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 377                        .name           = "CX24228/S5H1411-2 (QAM)",
 378                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 379                        .i2c_bus_addr   = 0x34 >> 1,
 380                        .i2c_reg_len    = REGLEN_8bit,
 381                } },
 382        },
 383        [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
 384                .name           = "Hauppauge WinTV-HVR2250",
 385                .porta          = SAA7164_MPEG_DVB,
 386                .portb          = SAA7164_MPEG_DVB,
 387                .portc          = SAA7164_MPEG_ENCODER,
 388                .portd          = SAA7164_MPEG_ENCODER,
 389                .porte          = SAA7164_MPEG_VBI,
 390                .portf          = SAA7164_MPEG_VBI,
 391                .chiprev        = SAA7164_CHIP_REV3,
 392                .unit           = {{
 393                        .id             = 0x26,
 394                        .type           = SAA7164_UNIT_EEPROM,
 395                        .name           = "4K EEPROM",
 396                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 397                        .i2c_bus_addr   = 0xa0 >> 1,
 398                        .i2c_reg_len    = REGLEN_8bit,
 399                }, {
 400                        .id             = 0x04,
 401                        .type           = SAA7164_UNIT_TUNER,
 402                        .name           = "TDA18271-1",
 403                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 404                        .i2c_bus_addr   = 0xc0 >> 1,
 405                        .i2c_reg_len    = REGLEN_8bit,
 406                }, {
 407                        .id             = 0x07,
 408                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 409                        .name           = "CX24228/S5H1411-1 (TOP)",
 410                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 411                        .i2c_bus_addr   = 0x32 >> 1,
 412                        .i2c_reg_len    = REGLEN_8bit,
 413                }, {
 414                        .id             = 0x08,
 415                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 416                        .name           = "CX24228/S5H1411-1 (QAM)",
 417                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 418                        .i2c_bus_addr   = 0x34 >> 1,
 419                        .i2c_reg_len    = REGLEN_8bit,
 420                }, {
 421                        .id             = 0x22,
 422                        .type           = SAA7164_UNIT_TUNER,
 423                        .name           = "TDA18271-2",
 424                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 425                        .i2c_bus_addr   = 0xc0 >> 1,
 426                        .i2c_reg_len    = REGLEN_8bit,
 427                }, {
 428                        .id             = 0x24,
 429                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 430                        .name           = "CX24228/S5H1411-2 (TOP)",
 431                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 432                        .i2c_bus_addr   = 0x32 >> 1,
 433                        .i2c_reg_len    = REGLEN_8bit,
 434                }, {
 435                        .id             = 0x27,
 436                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 437                        .name           = "CX24228/S5H1411-2 (QAM)",
 438                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 439                        .i2c_bus_addr   = 0x34 >> 1,
 440                        .i2c_reg_len    = REGLEN_8bit,
 441                } },
 442        },
 443        [SAA7164_BOARD_HAUPPAUGE_HVR2200_5] = {
 444                .name           = "Hauppauge WinTV-HVR2200",
 445                .porta          = SAA7164_MPEG_DVB,
 446                .portb          = SAA7164_MPEG_DVB,
 447                .chiprev        = SAA7164_CHIP_REV3,
 448                .unit           = {{
 449                        .id             = 0x23,
 450                        .type           = SAA7164_UNIT_EEPROM,
 451                        .name           = "4K EEPROM",
 452                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 453                        .i2c_bus_addr   = 0xa0 >> 1,
 454                        .i2c_reg_len    = REGLEN_8bit,
 455                }, {
 456                        .id             = 0x04,
 457                        .type           = SAA7164_UNIT_TUNER,
 458                        .name           = "TDA18271-1",
 459                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 460                        .i2c_bus_addr   = 0xc0 >> 1,
 461                        .i2c_reg_len    = REGLEN_8bit,
 462                }, {
 463                        .id             = 0x05,
 464                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 465                        .name           = "TDA8290-1",
 466                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 467                        .i2c_bus_addr   = 0x84 >> 1,
 468                        .i2c_reg_len    = REGLEN_8bit,
 469                }, {
 470                        .id             = 0x21,
 471                        .type           = SAA7164_UNIT_TUNER,
 472                        .name           = "TDA18271-2",
 473                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 474                        .i2c_bus_addr   = 0xc0 >> 1,
 475                        .i2c_reg_len    = REGLEN_8bit,
 476                }, {
 477                        .id             = 0x22,
 478                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 479                        .name           = "TDA8290-2",
 480                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 481                        .i2c_bus_addr   = 0x84 >> 1,
 482                        .i2c_reg_len    = REGLEN_8bit,
 483                }, {
 484                        .id             = 0x24,
 485                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 486                        .name           = "TDA10048-1",
 487                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 488                        .i2c_bus_addr   = 0x10 >> 1,
 489                        .i2c_reg_len    = REGLEN_8bit,
 490                }, {
 491                        .id             = 0x25,
 492                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 493                        .name           = "TDA10048-2",
 494                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 495                        .i2c_bus_addr   = 0x12 >> 1,
 496                        .i2c_reg_len    = REGLEN_8bit,
 497                } },
 498        },
 499        [SAA7164_BOARD_HAUPPAUGE_HVR2255proto] = {
 500                .name           = "Hauppauge WinTV-HVR2255(proto)",
 501                .porta          = SAA7164_MPEG_DVB,
 502                .portb          = SAA7164_MPEG_DVB,
 503                .portc          = SAA7164_MPEG_ENCODER,
 504                .portd          = SAA7164_MPEG_ENCODER,
 505                .porte          = SAA7164_MPEG_VBI,
 506                .portf          = SAA7164_MPEG_VBI,
 507                .chiprev        = SAA7164_CHIP_REV3,
 508                .unit           = {{
 509                        .id             = 0x27,
 510                        .type           = SAA7164_UNIT_EEPROM,
 511                        .name           = "4K EEPROM",
 512                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 513                        .i2c_bus_addr   = 0xa0 >> 1,
 514                        .i2c_reg_len    = REGLEN_8bit,
 515                }, {
 516                        .id             = 0x04,
 517                        .type           = SAA7164_UNIT_TUNER,
 518                        .name           = "SI2157-1",
 519                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 520                        .i2c_bus_addr   = 0xc0 >> 1,
 521                        .i2c_reg_len    = REGLEN_0bit,
 522                }, {
 523                        .id             = 0x06,
 524                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 525                        .name           = "LGDT3306",
 526                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 527                        .i2c_bus_addr   = 0xb2 >> 1,
 528                        .i2c_reg_len    = REGLEN_8bit,
 529                }, {
 530                        .id             = 0x24,
 531                        .type           = SAA7164_UNIT_TUNER,
 532                        .name           = "SI2157-2",
 533                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 534                        .i2c_bus_addr   = 0xc0 >> 1,
 535                        .i2c_reg_len    = REGLEN_0bit,
 536                }, {
 537                        .id             = 0x26,
 538                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 539                        .name           = "LGDT3306-2",
 540                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 541                        .i2c_bus_addr   = 0x1c >> 1,
 542                        .i2c_reg_len    = REGLEN_8bit,
 543                } },
 544        },
 545        [SAA7164_BOARD_HAUPPAUGE_HVR2255] = {
 546                .name           = "Hauppauge WinTV-HVR2255",
 547                .porta          = SAA7164_MPEG_DVB,
 548                .portb          = SAA7164_MPEG_DVB,
 549                .portc          = SAA7164_MPEG_ENCODER,
 550                .portd          = SAA7164_MPEG_ENCODER,
 551                .porte          = SAA7164_MPEG_VBI,
 552                .portf          = SAA7164_MPEG_VBI,
 553                .chiprev        = SAA7164_CHIP_REV3,
 554                .unit           = {{
 555                        .id             = 0x28,
 556                        .type           = SAA7164_UNIT_EEPROM,
 557                        .name           = "4K EEPROM",
 558                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 559                        .i2c_bus_addr   = 0xa0 >> 1,
 560                        .i2c_reg_len    = REGLEN_8bit,
 561                }, {
 562                        .id             = 0x04,
 563                        .type           = SAA7164_UNIT_TUNER,
 564                        .name           = "SI2157-1",
 565                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 566                        .i2c_bus_addr   = 0xc0 >> 1,
 567                        .i2c_reg_len    = REGLEN_0bit,
 568                }, {
 569                        .id             = 0x06,
 570                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 571                        .name           = "LGDT3306-1",
 572                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 573                        .i2c_bus_addr   = 0xb2 >> 1,
 574                        .i2c_reg_len    = REGLEN_8bit,
 575                }, {
 576                        .id             = 0x25,
 577                        .type           = SAA7164_UNIT_TUNER,
 578                        .name           = "SI2157-2",
 579                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 580                        .i2c_bus_addr   = 0xc0 >> 1,
 581                        .i2c_reg_len    = REGLEN_0bit,
 582                }, {
 583                        .id             = 0x27,
 584                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 585                        .name           = "LGDT3306-2",
 586                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 587                        .i2c_bus_addr   = 0x1c >> 1,
 588                        .i2c_reg_len    = REGLEN_8bit,
 589                } },
 590        },
 591        [SAA7164_BOARD_HAUPPAUGE_HVR2205] = {
 592                .name           = "Hauppauge WinTV-HVR2205",
 593                .porta          = SAA7164_MPEG_DVB,
 594                .portb          = SAA7164_MPEG_DVB,
 595                .portc          = SAA7164_MPEG_ENCODER,
 596                .portd          = SAA7164_MPEG_ENCODER,
 597                .porte          = SAA7164_MPEG_VBI,
 598                .portf          = SAA7164_MPEG_VBI,
 599                .chiprev        = SAA7164_CHIP_REV3,
 600                .unit           = {{
 601                        .id             = 0x28,
 602                        .type           = SAA7164_UNIT_EEPROM,
 603                        .name           = "4K EEPROM",
 604                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 605                        .i2c_bus_addr   = 0xa0 >> 1,
 606                        .i2c_reg_len    = REGLEN_8bit,
 607                }, {
 608                        .id             = 0x04,
 609                        .type           = SAA7164_UNIT_TUNER,
 610                        .name           = "SI2157-1",
 611                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 612                        .i2c_bus_addr   = 0xc0 >> 1,
 613                        .i2c_reg_len    = REGLEN_0bit,
 614                }, {
 615                        .id             = 0x06,
 616                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 617                        .name           = "SI2168-1",
 618                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 619                        .i2c_bus_addr   = 0xc8 >> 1,
 620                        .i2c_reg_len    = REGLEN_0bit,
 621                }, {
 622                        .id             = 0x25,
 623                        .type           = SAA7164_UNIT_TUNER,
 624                        .name           = "SI2157-2",
 625                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 626                        .i2c_bus_addr   = 0xc0 >> 1,
 627                        .i2c_reg_len    = REGLEN_0bit,
 628                }, {
 629                        .id             = 0x27,
 630                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 631                        .name           = "SI2168-2",
 632                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 633                        .i2c_bus_addr   = 0xcc >> 1,
 634                        .i2c_reg_len    = REGLEN_0bit,
 635                } },
 636        },
 637};
 638const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
 639
 640/* ------------------------------------------------------------------ */
 641/* PCI subsystem IDs                                                  */
 642
 643struct saa7164_subid saa7164_subids[] = {
 644        {
 645                .subvendor = 0x0070,
 646                .subdevice = 0x8880,
 647                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
 648        }, {
 649                .subvendor = 0x0070,
 650                .subdevice = 0x8810,
 651                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
 652        }, {
 653                .subvendor = 0x0070,
 654                .subdevice = 0x8980,
 655                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200,
 656        }, {
 657                .subvendor = 0x0070,
 658                .subdevice = 0x8900,
 659                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
 660        }, {
 661                .subvendor = 0x0070,
 662                .subdevice = 0x8901,
 663                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
 664        }, {
 665                .subvendor = 0x0070,
 666                .subdevice = 0x88A1,
 667                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
 668        }, {
 669                .subvendor = 0x0070,
 670                .subdevice = 0x8891,
 671                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
 672        }, {
 673                .subvendor = 0x0070,
 674                .subdevice = 0x8851,
 675                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
 676        }, {
 677                .subvendor = 0x0070,
 678                .subdevice = 0x8940,
 679                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
 680        }, {
 681                .subvendor = 0x0070,
 682                .subdevice = 0x8953,
 683                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
 684        }, {
 685                .subvendor = 0x0070,
 686                .subdevice = 0xf111,
 687                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2255,
 688                /* Prototype card left here for documenation purposes.
 689                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2255proto,
 690                */
 691        }, {
 692                .subvendor = 0x0070,
 693                .subdevice = 0xf123,
 694                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2205,
 695        }, {
 696                .subvendor = 0x0070,
 697                .subdevice = 0xf120,
 698                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2205,
 699        },
 700};
 701const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
 702
 703void saa7164_card_list(struct saa7164_dev *dev)
 704{
 705        int i;
 706
 707        if (0 == dev->pci->subsystem_vendor &&
 708            0 == dev->pci->subsystem_device) {
 709                printk(KERN_ERR
 710                        "%s: Board has no valid PCIe Subsystem ID and can't\n"
 711                        "%s: be autodetected. Pass card=<n> insmod option to\n"
 712                        "%s: workaround that. Send complaints to the vendor\n"
 713                        "%s: of the TV card. Best regards,\n"
 714                        "%s:         -- tux\n",
 715                        dev->name, dev->name, dev->name, dev->name, dev->name);
 716        } else {
 717                printk(KERN_ERR
 718                        "%s: Your board isn't known (yet) to the driver.\n"
 719                        "%s: Try to pick one of the existing card configs via\n"
 720                        "%s: card=<n> insmod option.  Updating to the latest\n"
 721                        "%s: version might help as well.\n",
 722                        dev->name, dev->name, dev->name, dev->name);
 723        }
 724
 725        printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod option:\n",
 726               dev->name);
 727
 728        for (i = 0; i < saa7164_bcount; i++)
 729                printk(KERN_ERR "%s:    card=%d -> %s\n",
 730                       dev->name, i, saa7164_boards[i].name);
 731}
 732
 733/* TODO: clean this define up into the -cards.c structs */
 734#define PCIEBRIDGE_UNITID 2
 735
 736void saa7164_gpio_setup(struct saa7164_dev *dev)
 737{
 738        switch (dev->board) {
 739        case SAA7164_BOARD_HAUPPAUGE_HVR2200:
 740        case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
 741        case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
 742        case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
 743        case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
 744        case SAA7164_BOARD_HAUPPAUGE_HVR2250:
 745        case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
 746        case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
 747        case SAA7164_BOARD_HAUPPAUGE_HVR2255proto:
 748        case SAA7164_BOARD_HAUPPAUGE_HVR2255:
 749        case SAA7164_BOARD_HAUPPAUGE_HVR2205:
 750                /*
 751                HVR2200 / HVR2250
 752                GPIO 2: s5h1411 / tda10048-1 demod reset
 753                GPIO 3: s5h1411 / tda10048-2 demod reset
 754                GPIO 7: IRBlaster Zilog reset
 755                 */
 756
 757                /* HVR2255
 758                 * GPIO 2: lgdg3306-1 demod reset
 759                 * GPIO 3: lgdt3306-2 demod reset
 760                 */
 761
 762                /* HVR2205
 763                 * GPIO 2: si2168-1 demod reset
 764                 * GPIO 3: si2168-2 demod reset
 765                 */
 766
 767                /* Reset parts by going in and out of reset */
 768                saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
 769                saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
 770
 771                msleep(20);
 772
 773                saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
 774                saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
 775                break;
 776        }
 777}
 778
 779static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
 780{
 781        struct tveeprom tv;
 782
 783        tveeprom_hauppauge_analog(&tv, eeprom_data);
 784
 785        /* Make sure we support the board model */
 786        switch (tv.model) {
 787        case 88001:
 788                /* Development board - Limit circulation */
 789                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 790                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
 791        case 88021:
 792                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 793                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
 794                break;
 795        case 88041:
 796                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 797                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
 798                break;
 799        case 88061:
 800                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 801                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
 802                break;
 803        case 89519:
 804        case 89609:
 805                /* WinTV-HVR2200 (PCIe, Retail, full-height)
 806                 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
 807                break;
 808        case 89619:
 809                /* WinTV-HVR2200 (PCIe, Retail, half-height)
 810                 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
 811                break;
 812        case 151009:
 813                /* First production board rev B2I6 */
 814                /* WinTV-HVR2205 (PCIe, Retail, full-height bracket)
 815                 * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */
 816                break;
 817        case 151609:
 818                /* First production board rev B2I6 */
 819                /* WinTV-HVR2205 (PCIe, Retail, half-height bracket)
 820                 * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */
 821                break;
 822        case 151061:
 823                /* First production board rev B1I6 */
 824                /* WinTV-HVR2255 (PCIe, Retail, full-height bracket)
 825                 * ATSC/QAM (SI2157/LGDT3306) and basic analog, FM */
 826                break;
 827        default:
 828                printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
 829                        dev->name, tv.model);
 830                break;
 831        }
 832
 833        printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
 834                tv.model);
 835}
 836
 837void saa7164_card_setup(struct saa7164_dev *dev)
 838{
 839        static u8 eeprom[256];
 840
 841        if (dev->i2c_bus[0].i2c_rc == 0) {
 842                if (saa7164_api_read_eeprom(dev, &eeprom[0],
 843                        sizeof(eeprom)) < 0)
 844                        return;
 845        }
 846
 847        switch (dev->board) {
 848        case SAA7164_BOARD_HAUPPAUGE_HVR2200:
 849        case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
 850        case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
 851        case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
 852        case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
 853        case SAA7164_BOARD_HAUPPAUGE_HVR2250:
 854        case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
 855        case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
 856        case SAA7164_BOARD_HAUPPAUGE_HVR2255proto:
 857        case SAA7164_BOARD_HAUPPAUGE_HVR2255:
 858        case SAA7164_BOARD_HAUPPAUGE_HVR2205:
 859                hauppauge_eeprom(dev, &eeprom[0]);
 860                break;
 861        }
 862}
 863
 864/* With most other drivers, the kernel expects to communicate with subdrivers
 865 * through i2c. This bridge does not allow that, it does not expose any direct
 866 * access to I2C. Instead we have to communicate through the device f/w for
 867 * register access to 'processing units'. Each unit has a unique
 868 * id, regardless of how the physical implementation occurs across
 869 * the three physical i2c busses. The being said if we want leverge of
 870 * the existing kernel drivers for tuners and demods we have to 'speak i2c',
 871 * to this bridge implements 3 virtual i2c buses. This is a helper function
 872 * for those.
 873 *
 874 * Description: Translate the kernels notion of an i2c address and bus into
 875 * the appropriate unitid.
 876 */
 877int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
 878{
 879        /* For a given bus and i2c device address, return the saa7164 unique
 880         * unitid. < 0 on error */
 881
 882        struct saa7164_dev *dev = bus->dev;
 883        struct saa7164_unit *unit;
 884        int i;
 885
 886        for (i = 0; i < SAA7164_MAX_UNITS; i++) {
 887                unit = &saa7164_boards[dev->board].unit[i];
 888
 889                if (unit->type == SAA7164_UNIT_UNDEFINED)
 890                        continue;
 891                if ((bus->nr == unit->i2c_bus_nr) &&
 892                        (addr == unit->i2c_bus_addr))
 893                        return unit->id;
 894        }
 895
 896        return -1;
 897}
 898
 899/* The 7164 API needs to know the i2c register length in advance.
 900 * this is a helper function. Based on a specific chip addr and bus return the
 901 * reg length.
 902 */
 903int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
 904{
 905        /* For a given bus and i2c device address, return the
 906         * saa7164 registry address width. < 0 on error
 907         */
 908
 909        struct saa7164_dev *dev = bus->dev;
 910        struct saa7164_unit *unit;
 911        int i;
 912
 913        for (i = 0; i < SAA7164_MAX_UNITS; i++) {
 914                unit = &saa7164_boards[dev->board].unit[i];
 915
 916                if (unit->type == SAA7164_UNIT_UNDEFINED)
 917                        continue;
 918
 919                if ((bus->nr == unit->i2c_bus_nr) &&
 920                        (addr == unit->i2c_bus_addr))
 921                        return unit->i2c_reg_len;
 922        }
 923
 924        return -1;
 925}
 926/* TODO: implement a 'findeeprom' functio like the above and fix any other
 927 * eeprom related todo's in -api.c.
 928 */
 929
 930/* Translate a unitid into a x readable device name, for display purposes.  */
 931char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
 932{
 933        char *undefed = "UNDEFINED";
 934        char *bridge = "BRIDGE";
 935        struct saa7164_unit *unit;
 936        int i;
 937
 938        if (unitid == 0)
 939                return bridge;
 940
 941        for (i = 0; i < SAA7164_MAX_UNITS; i++) {
 942                unit = &saa7164_boards[dev->board].unit[i];
 943
 944                if (unit->type == SAA7164_UNIT_UNDEFINED)
 945                        continue;
 946
 947                if (unitid == unit->id)
 948                                return unit->name;
 949        }
 950
 951        return undefed;
 952}
 953
 954