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