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