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