linux/drivers/media/video/saa7164/saa7164-cards.c
<<
>>
Prefs
   1/*
   2 *  Driver for the NXP SAA7164 PCIe bridge
   3 *
   4 *  Copyright (c) 2009 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 *  You should have received a copy of the GNU General Public License
  18 *  along with this program; if not, write to the Free Software
  19 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 */
  21
  22#include <linux/init.h>
  23#include <linux/module.h>
  24#include <linux/pci.h>
  25#include <linux/delay.h>
  26
  27#include "saa7164.h"
  28
  29/* The Bridge API needs to understand register widths (in bytes) for the
  30 * attached I2C devices, so we can simplify the virtual i2c mechansms
  31 * and keep the -i2c.c implementation clean.
  32 */
  33#define REGLEN_8bit     1
  34#define REGLEN_16bit    2
  35
  36struct saa7164_board saa7164_boards[] = {
  37        [SAA7164_BOARD_UNKNOWN] = {
  38                /* Bridge will not load any firmware, without knowing
  39                 * the rev this would be fatal. */
  40                .name           = "Unknown",
  41        },
  42        [SAA7164_BOARD_UNKNOWN_REV2] = {
  43                /* Bridge will load the v2 f/w and dump descriptors */
  44                /* Required during new board bringup */
  45                .name           = "Generic Rev2",
  46                .chiprev        = SAA7164_CHIP_REV2,
  47        },
  48        [SAA7164_BOARD_UNKNOWN_REV3] = {
  49                /* Bridge will load the v2 f/w and dump descriptors */
  50                /* Required during new board bringup */
  51                .name           = "Generic Rev3",
  52                .chiprev        = SAA7164_CHIP_REV3,
  53        },
  54        [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
  55                .name           = "Hauppauge WinTV-HVR2200",
  56                .porta          = SAA7164_MPEG_DVB,
  57                .portb          = SAA7164_MPEG_DVB,
  58                .chiprev        = SAA7164_CHIP_REV3,
  59                .unit           = {{
  60                        .id             = 0x1d,
  61                        .type           = SAA7164_UNIT_EEPROM,
  62                        .name           = "4K EEPROM",
  63                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
  64                        .i2c_bus_addr   = 0xa0 >> 1,
  65                        .i2c_reg_len    = REGLEN_8bit,
  66                }, {
  67                        .id             = 0x04,
  68                        .type           = SAA7164_UNIT_TUNER,
  69                        .name           = "TDA18271-1",
  70                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
  71                        .i2c_bus_addr   = 0xc0 >> 1,
  72                        .i2c_reg_len    = REGLEN_8bit,
  73                }, {
  74                        .id             = 0x1b,
  75                        .type           = SAA7164_UNIT_TUNER,
  76                        .name           = "TDA18271-2",
  77                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
  78                        .i2c_bus_addr   = 0xc0 >> 1,
  79                        .i2c_reg_len    = REGLEN_8bit,
  80                }, {
  81                        .id             = 0x1e,
  82                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
  83                        .name           = "TDA10048-1",
  84                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
  85                        .i2c_bus_addr   = 0x10 >> 1,
  86                        .i2c_reg_len    = REGLEN_8bit,
  87                }, {
  88                        .id             = 0x1f,
  89                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
  90                        .name           = "TDA10048-2",
  91                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
  92                        .i2c_bus_addr   = 0x12 >> 1,
  93                        .i2c_reg_len    = REGLEN_8bit,
  94                } },
  95        },
  96        [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
  97                .name           = "Hauppauge WinTV-HVR2200",
  98                .porta          = SAA7164_MPEG_DVB,
  99                .portb          = SAA7164_MPEG_DVB,
 100                .chiprev        = SAA7164_CHIP_REV2,
 101                .unit           = {{
 102                        .id             = 0x06,
 103                        .type           = SAA7164_UNIT_EEPROM,
 104                        .name           = "4K EEPROM",
 105                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 106                        .i2c_bus_addr   = 0xa0 >> 1,
 107                        .i2c_reg_len    = REGLEN_8bit,
 108                }, {
 109                        .id             = 0x04,
 110                        .type           = SAA7164_UNIT_TUNER,
 111                        .name           = "TDA18271-1",
 112                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 113                        .i2c_bus_addr   = 0xc0 >> 1,
 114                        .i2c_reg_len    = REGLEN_8bit,
 115                }, {
 116                        .id             = 0x05,
 117                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 118                        .name           = "TDA10048-1",
 119                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 120                        .i2c_bus_addr   = 0x10 >> 1,
 121                        .i2c_reg_len    = REGLEN_8bit,
 122                }, {
 123                        .id             = 0x1e,
 124                        .type           = SAA7164_UNIT_TUNER,
 125                        .name           = "TDA18271-2",
 126                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 127                        .i2c_bus_addr   = 0xc0 >> 1,
 128                        .i2c_reg_len    = REGLEN_8bit,
 129                }, {
 130                        .id             = 0x1f,
 131                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 132                        .name           = "TDA10048-2",
 133                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 134                        .i2c_bus_addr   = 0x12 >> 1,
 135                        .i2c_reg_len    = REGLEN_8bit,
 136                } },
 137        },
 138        [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
 139                .name           = "Hauppauge WinTV-HVR2200",
 140                .porta          = SAA7164_MPEG_DVB,
 141                .portb          = SAA7164_MPEG_DVB,
 142                .chiprev        = SAA7164_CHIP_REV2,
 143                .unit           = {{
 144                        .id             = 0x1d,
 145                        .type           = SAA7164_UNIT_EEPROM,
 146                        .name           = "4K EEPROM",
 147                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 148                        .i2c_bus_addr   = 0xa0 >> 1,
 149                        .i2c_reg_len    = REGLEN_8bit,
 150                }, {
 151                        .id             = 0x04,
 152                        .type           = SAA7164_UNIT_TUNER,
 153                        .name           = "TDA18271-1",
 154                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 155                        .i2c_bus_addr   = 0xc0 >> 1,
 156                        .i2c_reg_len    = REGLEN_8bit,
 157                }, {
 158                        .id             = 0x05,
 159                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 160                        .name           = "TDA8290-1",
 161                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 162                        .i2c_bus_addr   = 0x84 >> 1,
 163                        .i2c_reg_len    = REGLEN_8bit,
 164                }, {
 165                        .id             = 0x1b,
 166                        .type           = SAA7164_UNIT_TUNER,
 167                        .name           = "TDA18271-2",
 168                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 169                        .i2c_bus_addr   = 0xc0 >> 1,
 170                        .i2c_reg_len    = REGLEN_8bit,
 171                }, {
 172                        .id             = 0x1c,
 173                        .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
 174                        .name           = "TDA8290-2",
 175                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 176                        .i2c_bus_addr   = 0x84 >> 1,
 177                        .i2c_reg_len    = REGLEN_8bit,
 178                }, {
 179                        .id             = 0x1e,
 180                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 181                        .name           = "TDA10048-1",
 182                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 183                        .i2c_bus_addr   = 0x10 >> 1,
 184                        .i2c_reg_len    = REGLEN_8bit,
 185                }, {
 186                        .id             = 0x1f,
 187                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 188                        .name           = "TDA10048-2",
 189                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 190                        .i2c_bus_addr   = 0x12 >> 1,
 191                        .i2c_reg_len    = REGLEN_8bit,
 192                } },
 193        },
 194        [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
 195                .name           = "Hauppauge WinTV-HVR2250",
 196                .porta          = SAA7164_MPEG_DVB,
 197                .portb          = SAA7164_MPEG_DVB,
 198                .chiprev        = SAA7164_CHIP_REV3,
 199                .unit           = {{
 200                        .id             = 0x22,
 201                        .type           = SAA7164_UNIT_EEPROM,
 202                        .name           = "4K EEPROM",
 203                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 204                        .i2c_bus_addr   = 0xa0 >> 1,
 205                        .i2c_reg_len    = REGLEN_8bit,
 206                }, {
 207                        .id             = 0x04,
 208                        .type           = SAA7164_UNIT_TUNER,
 209                        .name           = "TDA18271-1",
 210                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 211                        .i2c_bus_addr   = 0xc0 >> 1,
 212                        .i2c_reg_len    = REGLEN_8bit,
 213                }, {
 214                        .id             = 0x07,
 215                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 216                        .name           = "CX24228/S5H1411-1 (TOP)",
 217                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 218                        .i2c_bus_addr   = 0x32 >> 1,
 219                        .i2c_reg_len    = REGLEN_8bit,
 220                }, {
 221                        .id             = 0x08,
 222                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 223                        .name           = "CX24228/S5H1411-1 (QAM)",
 224                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 225                        .i2c_bus_addr   = 0x34 >> 1,
 226                        .i2c_reg_len    = REGLEN_8bit,
 227                }, {
 228                        .id             = 0x1e,
 229                        .type           = SAA7164_UNIT_TUNER,
 230                        .name           = "TDA18271-2",
 231                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 232                        .i2c_bus_addr   = 0xc0 >> 1,
 233                        .i2c_reg_len    = REGLEN_8bit,
 234                }, {
 235                        .id             = 0x20,
 236                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 237                        .name           = "CX24228/S5H1411-2 (TOP)",
 238                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 239                        .i2c_bus_addr   = 0x32 >> 1,
 240                        .i2c_reg_len    = REGLEN_8bit,
 241                }, {
 242                        .id             = 0x23,
 243                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 244                        .name           = "CX24228/S5H1411-2 (QAM)",
 245                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 246                        .i2c_bus_addr   = 0x34 >> 1,
 247                        .i2c_reg_len    = REGLEN_8bit,
 248                } },
 249        },
 250        [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
 251                .name           = "Hauppauge WinTV-HVR2250",
 252                .porta          = SAA7164_MPEG_DVB,
 253                .portb          = SAA7164_MPEG_DVB,
 254                .chiprev        = SAA7164_CHIP_REV3,
 255                .unit           = {{
 256                        .id             = 0x28,
 257                        .type           = SAA7164_UNIT_EEPROM,
 258                        .name           = "4K EEPROM",
 259                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 260                        .i2c_bus_addr   = 0xa0 >> 1,
 261                        .i2c_reg_len    = REGLEN_8bit,
 262                }, {
 263                        .id             = 0x04,
 264                        .type           = SAA7164_UNIT_TUNER,
 265                        .name           = "TDA18271-1",
 266                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 267                        .i2c_bus_addr   = 0xc0 >> 1,
 268                        .i2c_reg_len    = REGLEN_8bit,
 269                }, {
 270                        .id             = 0x07,
 271                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 272                        .name           = "CX24228/S5H1411-1 (TOP)",
 273                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 274                        .i2c_bus_addr   = 0x32 >> 1,
 275                        .i2c_reg_len    = REGLEN_8bit,
 276                }, {
 277                        .id             = 0x08,
 278                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 279                        .name           = "CX24228/S5H1411-1 (QAM)",
 280                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 281                        .i2c_bus_addr   = 0x34 >> 1,
 282                        .i2c_reg_len    = REGLEN_8bit,
 283                }, {
 284                        .id             = 0x24,
 285                        .type           = SAA7164_UNIT_TUNER,
 286                        .name           = "TDA18271-2",
 287                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 288                        .i2c_bus_addr   = 0xc0 >> 1,
 289                        .i2c_reg_len    = REGLEN_8bit,
 290                }, {
 291                        .id             = 0x26,
 292                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 293                        .name           = "CX24228/S5H1411-2 (TOP)",
 294                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 295                        .i2c_bus_addr   = 0x32 >> 1,
 296                        .i2c_reg_len    = REGLEN_8bit,
 297                }, {
 298                        .id             = 0x29,
 299                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 300                        .name           = "CX24228/S5H1411-2 (QAM)",
 301                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 302                        .i2c_bus_addr   = 0x34 >> 1,
 303                        .i2c_reg_len    = REGLEN_8bit,
 304                } },
 305        },
 306        [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
 307                .name           = "Hauppauge WinTV-HVR2250",
 308                .porta          = SAA7164_MPEG_DVB,
 309                .portb          = SAA7164_MPEG_DVB,
 310                .chiprev        = SAA7164_CHIP_REV3,
 311                .unit           = {{
 312                        .id             = 0x26,
 313                        .type           = SAA7164_UNIT_EEPROM,
 314                        .name           = "4K EEPROM",
 315                        .i2c_bus_nr     = SAA7164_I2C_BUS_0,
 316                        .i2c_bus_addr   = 0xa0 >> 1,
 317                        .i2c_reg_len    = REGLEN_8bit,
 318                }, {
 319                        .id             = 0x04,
 320                        .type           = SAA7164_UNIT_TUNER,
 321                        .name           = "TDA18271-1",
 322                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 323                        .i2c_bus_addr   = 0xc0 >> 1,
 324                        .i2c_reg_len    = REGLEN_8bit,
 325                }, {
 326                        .id             = 0x07,
 327                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 328                        .name           = "CX24228/S5H1411-1 (TOP)",
 329                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 330                        .i2c_bus_addr   = 0x32 >> 1,
 331                        .i2c_reg_len    = REGLEN_8bit,
 332                }, {
 333                        .id             = 0x08,
 334                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 335                        .name           = "CX24228/S5H1411-1 (QAM)",
 336                        .i2c_bus_nr     = SAA7164_I2C_BUS_1,
 337                        .i2c_bus_addr   = 0x34 >> 1,
 338                        .i2c_reg_len    = REGLEN_8bit,
 339                }, {
 340                        .id             = 0x22,
 341                        .type           = SAA7164_UNIT_TUNER,
 342                        .name           = "TDA18271-2",
 343                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 344                        .i2c_bus_addr   = 0xc0 >> 1,
 345                        .i2c_reg_len    = REGLEN_8bit,
 346                }, {
 347                        .id             = 0x24,
 348                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 349                        .name           = "CX24228/S5H1411-2 (TOP)",
 350                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 351                        .i2c_bus_addr   = 0x32 >> 1,
 352                        .i2c_reg_len    = REGLEN_8bit,
 353                }, {
 354                        .id             = 0x27,
 355                        .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
 356                        .name           = "CX24228/S5H1411-2 (QAM)",
 357                        .i2c_bus_nr     = SAA7164_I2C_BUS_2,
 358                        .i2c_bus_addr   = 0x34 >> 1,
 359                        .i2c_reg_len    = REGLEN_8bit,
 360                } },
 361        },
 362};
 363const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
 364
 365/* ------------------------------------------------------------------ */
 366/* PCI subsystem IDs                                                  */
 367
 368struct saa7164_subid saa7164_subids[] = {
 369        {
 370                .subvendor = 0x0070,
 371                .subdevice = 0x8880,
 372                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
 373        }, {
 374                .subvendor = 0x0070,
 375                .subdevice = 0x8810,
 376                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
 377        }, {
 378                .subvendor = 0x0070,
 379                .subdevice = 0x8980,
 380                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200,
 381        }, {
 382                .subvendor = 0x0070,
 383                .subdevice = 0x8900,
 384                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
 385        }, {
 386                .subvendor = 0x0070,
 387                .subdevice = 0x8901,
 388                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
 389        }, {
 390                .subvendor = 0x0070,
 391                .subdevice = 0x88A1,
 392                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
 393        }, {
 394                .subvendor = 0x0070,
 395                .subdevice = 0x8891,
 396                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
 397        }, {
 398                .subvendor = 0x0070,
 399                .subdevice = 0x8851,
 400                .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
 401        },
 402};
 403const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
 404
 405void saa7164_card_list(struct saa7164_dev *dev)
 406{
 407        int i;
 408
 409        if (0 == dev->pci->subsystem_vendor &&
 410            0 == dev->pci->subsystem_device) {
 411                printk(KERN_ERR
 412                        "%s: Board has no valid PCIe Subsystem ID and can't\n"
 413                        "%s: be autodetected. Pass card=<n> insmod option to\n"
 414                        "%s: workaround that. Send complaints to the vendor\n"
 415                        "%s: of the TV card. Best regards,\n"
 416                        "%s:         -- tux\n",
 417                        dev->name, dev->name, dev->name, dev->name, dev->name);
 418        } else {
 419                printk(KERN_ERR
 420                        "%s: Your board isn't known (yet) to the driver.\n"
 421                        "%s: Try to pick one of the existing card configs via\n"
 422                        "%s: card=<n> insmod option.  Updating to the latest\n"
 423                        "%s: version might help as well.\n",
 424                        dev->name, dev->name, dev->name, dev->name);
 425        }
 426
 427        printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
 428                "option:\n", dev->name);
 429
 430        for (i = 0; i < saa7164_bcount; i++)
 431                printk(KERN_ERR "%s:    card=%d -> %s\n",
 432                       dev->name, i, saa7164_boards[i].name);
 433}
 434
 435/* TODO: clean this define up into the -cards.c structs */
 436#define PCIEBRIDGE_UNITID 2
 437
 438void saa7164_gpio_setup(struct saa7164_dev *dev)
 439{
 440
 441
 442        switch (dev->board) {
 443        case SAA7164_BOARD_HAUPPAUGE_HVR2200:
 444        case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
 445        case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
 446        case SAA7164_BOARD_HAUPPAUGE_HVR2250:
 447        case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
 448        case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
 449                /*
 450                GPIO 2: s5h1411 / tda10048-1 demod reset
 451                GPIO 3: s5h1411 / tda10048-2 demod reset
 452                GPIO 7: IRBlaster Zilog reset
 453                 */
 454
 455                /* Reset parts by going in and out of reset */
 456                saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
 457                saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
 458
 459                msleep(10);
 460
 461                saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
 462                saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
 463                break;
 464        }
 465
 466}
 467
 468static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
 469{
 470        struct tveeprom tv;
 471
 472        /* TODO: Assumption: eeprom on bus 0 */
 473        tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
 474                eeprom_data);
 475
 476        /* Make sure we support the board model */
 477        switch (tv.model) {
 478        case 88001:
 479                /* Development board - Limit circulation */
 480                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 481                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
 482        case 88021:
 483                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 484                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
 485                break;
 486        case 88041:
 487                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 488                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
 489                break;
 490        case 88061:
 491                /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
 492                 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
 493                break;
 494        case 89519:
 495        case 89609:
 496                /* WinTV-HVR2200 (PCIe, Retail, full-height)
 497                 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
 498                break;
 499        case 89619:
 500                /* WinTV-HVR2200 (PCIe, Retail, half-height)
 501                 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
 502                break;
 503        default:
 504                printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
 505                        dev->name, tv.model);
 506                break;
 507        }
 508
 509        printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
 510                tv.model);
 511}
 512
 513void saa7164_card_setup(struct saa7164_dev *dev)
 514{
 515        static u8 eeprom[256];
 516
 517        if (dev->i2c_bus[0].i2c_rc == 0) {
 518                if (saa7164_api_read_eeprom(dev, &eeprom[0],
 519                        sizeof(eeprom)) < 0)
 520                        return;
 521        }
 522
 523        switch (dev->board) {
 524        case SAA7164_BOARD_HAUPPAUGE_HVR2200:
 525        case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
 526        case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
 527        case SAA7164_BOARD_HAUPPAUGE_HVR2250:
 528        case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
 529        case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
 530                hauppauge_eeprom(dev, &eeprom[0]);
 531                break;
 532        }
 533}
 534
 535/* With most other drivers, the kernel expects to communicate with subdrivers
 536 * through i2c. This bridge does not allow that, it does not expose any direct
 537 * access to I2C. Instead we have to communicate through the device f/w for
 538 * register access to 'processing units'. Each unit has a unique
 539 * id, regardless of how the physical implementation occurs across
 540 * the three physical i2c busses. The being said if we want leverge of
 541 * the existing kernel drivers for tuners and demods we have to 'speak i2c',
 542 * to this bridge implements 3 virtual i2c buses. This is a helper function
 543 * for those.
 544 *
 545 * Description: Translate the kernels notion of an i2c address and bus into
 546 * the appropriate unitid.
 547 */
 548int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
 549{
 550        /* For a given bus and i2c device address, return the saa7164 unique
 551         * unitid. < 0 on error */
 552
 553        struct saa7164_dev *dev = bus->dev;
 554        struct saa7164_unit *unit;
 555        int i;
 556
 557        for (i = 0; i < SAA7164_MAX_UNITS; i++) {
 558                unit = &saa7164_boards[dev->board].unit[i];
 559
 560                if (unit->type == SAA7164_UNIT_UNDEFINED)
 561                        continue;
 562                if ((bus->nr == unit->i2c_bus_nr) &&
 563                        (addr == unit->i2c_bus_addr))
 564                        return unit->id;
 565        }
 566
 567        return -1;
 568}
 569
 570/* The 7164 API needs to know the i2c register length in advance.
 571 * this is a helper function. Based on a specific chip addr and bus return the
 572 * reg length.
 573 */
 574int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
 575{
 576        /* For a given bus and i2c device address, return the
 577         * saa7164 registry address width. < 0 on error
 578         */
 579
 580        struct saa7164_dev *dev = bus->dev;
 581        struct saa7164_unit *unit;
 582        int i;
 583
 584        for (i = 0; i < SAA7164_MAX_UNITS; i++) {
 585                unit = &saa7164_boards[dev->board].unit[i];
 586
 587                if (unit->type == SAA7164_UNIT_UNDEFINED)
 588                        continue;
 589
 590                if ((bus->nr == unit->i2c_bus_nr) &&
 591                        (addr == unit->i2c_bus_addr))
 592                        return unit->i2c_reg_len;
 593        }
 594
 595        return -1;
 596}
 597/* TODO: implement a 'findeeprom' functio like the above and fix any other
 598 * eeprom related todo's in -api.c.
 599 */
 600
 601/* Translate a unitid into a x readable device name, for display purposes.  */
 602char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
 603{
 604        char *undefed = "UNDEFINED";
 605        char *bridge = "BRIDGE";
 606        struct saa7164_unit *unit;
 607        int i;
 608
 609        if (unitid == 0)
 610                return bridge;
 611
 612        for (i = 0; i < SAA7164_MAX_UNITS; i++) {
 613                unit = &saa7164_boards[dev->board].unit[i];
 614
 615                if (unit->type == SAA7164_UNIT_UNDEFINED)
 616                        continue;
 617
 618                if (unitid == unit->id)
 619                                return unit->name;
 620        }
 621
 622        return undefed;
 623}
 624
 625