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