2 * Driver for the NXP SAA7164 PCIe bridge
4 * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
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.
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
15 * GNU General Public License for more details.
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.
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <linux/pci.h>
25 #include <linux/delay.h>
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.
35 #define REGLEN_16bit 2
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. */
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,
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,
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,
66 .type = SAA7164_UNIT_EEPROM,
68 .i2c_bus_nr = SAA7164_I2C_BUS_0,
69 .i2c_bus_addr = 0xa0 >> 1,
70 .i2c_reg_len = REGLEN_8bit,
73 .type = SAA7164_UNIT_TUNER,
75 .i2c_bus_nr = SAA7164_I2C_BUS_1,
76 .i2c_bus_addr = 0xc0 >> 1,
77 .i2c_reg_len = REGLEN_8bit,
80 .type = SAA7164_UNIT_TUNER,
82 .i2c_bus_nr = SAA7164_I2C_BUS_2,
83 .i2c_bus_addr = 0xc0 >> 1,
84 .i2c_reg_len = REGLEN_8bit,
87 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
89 .i2c_bus_nr = SAA7164_I2C_BUS_1,
90 .i2c_bus_addr = 0x10 >> 1,
91 .i2c_reg_len = REGLEN_8bit,
94 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
96 .i2c_bus_nr = SAA7164_I2C_BUS_2,
97 .i2c_bus_addr = 0x12 >> 1,
98 .i2c_reg_len = REGLEN_8bit,
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,
112 .type = SAA7164_UNIT_EEPROM,
114 .i2c_bus_nr = SAA7164_I2C_BUS_0,
115 .i2c_bus_addr = 0xa0 >> 1,
116 .i2c_reg_len = REGLEN_8bit,
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,
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,
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,
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,
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,
158 .type = SAA7164_UNIT_EEPROM,
160 .i2c_bus_nr = SAA7164_I2C_BUS_0,
161 .i2c_bus_addr = 0xa0 >> 1,
162 .i2c_reg_len = REGLEN_8bit,
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,
172 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
174 .i2c_bus_nr = SAA7164_I2C_BUS_1,
175 .i2c_bus_addr = 0x84 >> 1,
176 .i2c_reg_len = REGLEN_8bit,
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,
186 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
188 .i2c_bus_nr = SAA7164_I2C_BUS_2,
189 .i2c_bus_addr = 0x84 >> 1,
190 .i2c_reg_len = REGLEN_8bit,
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,
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,
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,
218 .type = SAA7164_UNIT_EEPROM,
220 .i2c_bus_nr = SAA7164_I2C_BUS_0,
221 .i2c_bus_addr = 0xa0 >> 1,
222 .i2c_reg_len = REGLEN_8bit,
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,
232 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
234 .i2c_bus_nr = SAA7164_I2C_BUS_1,
235 .i2c_bus_addr = 0x84 >> 1,
236 .i2c_reg_len = REGLEN_8bit,
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,
246 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
248 .i2c_bus_nr = SAA7164_I2C_BUS_2,
249 .i2c_bus_addr = 0x84 >> 1,
250 .i2c_reg_len = REGLEN_8bit,
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,
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,
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,
278 .type = SAA7164_UNIT_EEPROM,
280 .i2c_bus_nr = SAA7164_I2C_BUS_0,
281 .i2c_bus_addr = 0xa0 >> 1,
282 .i2c_reg_len = REGLEN_8bit,
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,
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,
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,
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,
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,
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,
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,
338 .type = SAA7164_UNIT_EEPROM,
340 .i2c_bus_nr = SAA7164_I2C_BUS_0,
341 .i2c_bus_addr = 0xa0 >> 1,
342 .i2c_reg_len = REGLEN_8bit,
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,
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,
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,
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,
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,
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,
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,
398 .type = SAA7164_UNIT_EEPROM,
400 .i2c_bus_nr = SAA7164_I2C_BUS_0,
401 .i2c_bus_addr = 0xa0 >> 1,
402 .i2c_reg_len = REGLEN_8bit,
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,
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,
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,
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,
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,
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,
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,
454 .type = SAA7164_UNIT_EEPROM,
456 .i2c_bus_nr = SAA7164_I2C_BUS_0,
457 .i2c_bus_addr = 0xa0 >> 1,
458 .i2c_reg_len = REGLEN_8bit,
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,
468 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
470 .i2c_bus_nr = SAA7164_I2C_BUS_1,
471 .i2c_bus_addr = 0x84 >> 1,
472 .i2c_reg_len = REGLEN_8bit,
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,
482 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
484 .i2c_bus_nr = SAA7164_I2C_BUS_2,
485 .i2c_bus_addr = 0x84 >> 1,
486 .i2c_reg_len = REGLEN_8bit,
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,
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,
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,
514 .type = SAA7164_UNIT_EEPROM,
516 .i2c_bus_nr = SAA7164_I2C_BUS_0,
517 .i2c_bus_addr = 0xa0 >> 1,
518 .i2c_reg_len = REGLEN_8bit,
521 .type = SAA7164_UNIT_TUNER,
523 .i2c_bus_nr = SAA7164_I2C_BUS_0,
524 .i2c_bus_addr = 0xc0 >> 1,
525 .i2c_reg_len = REGLEN_0bit,
528 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
530 .i2c_bus_nr = SAA7164_I2C_BUS_2,
531 .i2c_bus_addr = 0xb2 >> 1,
532 .i2c_reg_len = REGLEN_8bit,
535 .type = SAA7164_UNIT_TUNER,
537 .i2c_bus_nr = SAA7164_I2C_BUS_1,
538 .i2c_bus_addr = 0xc0 >> 1,
539 .i2c_reg_len = REGLEN_0bit,
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,
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,
560 .type = SAA7164_UNIT_EEPROM,
562 .i2c_bus_nr = SAA7164_I2C_BUS_0,
563 .i2c_bus_addr = 0xa0 >> 1,
564 .i2c_reg_len = REGLEN_8bit,
567 .type = SAA7164_UNIT_TUNER,
569 .i2c_bus_nr = SAA7164_I2C_BUS_0,
570 .i2c_bus_addr = 0xc0 >> 1,
571 .i2c_reg_len = REGLEN_0bit,
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,
581 .type = SAA7164_UNIT_TUNER,
583 .i2c_bus_nr = SAA7164_I2C_BUS_1,
584 .i2c_bus_addr = 0xc0 >> 1,
585 .i2c_reg_len = REGLEN_0bit,
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,
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,
606 .type = SAA7164_UNIT_EEPROM,
608 .i2c_bus_nr = SAA7164_I2C_BUS_0,
609 .i2c_bus_addr = 0xa0 >> 1,
610 .i2c_reg_len = REGLEN_8bit,
613 .type = SAA7164_UNIT_TUNER,
615 .i2c_bus_nr = SAA7164_I2C_BUS_0,
616 .i2c_bus_addr = 0xc0 >> 1,
617 .i2c_reg_len = REGLEN_0bit,
620 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
622 .i2c_bus_nr = SAA7164_I2C_BUS_2,
623 .i2c_bus_addr = 0xc8 >> 1,
624 .i2c_reg_len = REGLEN_0bit,
627 .type = SAA7164_UNIT_TUNER,
629 .i2c_bus_nr = SAA7164_I2C_BUS_1,
630 .i2c_bus_addr = 0xc0 >> 1,
631 .i2c_reg_len = REGLEN_0bit,
634 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
636 .i2c_bus_nr = SAA7164_I2C_BUS_2,
637 .i2c_bus_addr = 0xcc >> 1,
638 .i2c_reg_len = REGLEN_0bit,
642 const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
644 /* ------------------------------------------------------------------ */
645 /* PCI subsystem IDs */
647 struct saa7164_subid saa7164_subids[] = {
651 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
655 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
659 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200,
663 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
667 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
671 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
675 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
679 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
683 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
687 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
691 .card = SAA7164_BOARD_HAUPPAUGE_HVR2255,
692 /* Prototype card left here for documenation purposes.
693 .card = SAA7164_BOARD_HAUPPAUGE_HVR2255proto,
698 .card = SAA7164_BOARD_HAUPPAUGE_HVR2205,
702 .card = SAA7164_BOARD_HAUPPAUGE_HVR2205,
705 const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
707 void saa7164_card_list(struct saa7164_dev *dev)
711 if (0 == dev->pci->subsystem_vendor &&
712 0 == dev->pci->subsystem_device) {
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"
719 dev->name, dev->name, dev->name, dev->name, dev->name);
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);
729 printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
730 "option:\n", dev->name);
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);
737 /* TODO: clean this define up into the -cards.c structs */
738 #define PCIEBRIDGE_UNITID 2
740 void saa7164_gpio_setup(struct saa7164_dev *dev)
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:
756 GPIO 2: s5h1411 / tda10048-1 demod reset
757 GPIO 3: s5h1411 / tda10048-2 demod reset
758 GPIO 7: IRBlaster Zilog reset
762 * GPIO 2: lgdg3306-1 demod reset
763 * GPIO 3: lgdt3306-2 demod reset
767 * GPIO 2: si2168-1 demod reset
768 * GPIO 3: si2168-2 demod reset
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);
777 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
778 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
783 static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
787 /* TODO: Assumption: eeprom on bus 0 */
788 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
791 /* Make sure we support the board model */
794 /* Development board - Limit circulation */
795 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
796 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
798 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
799 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
802 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
803 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
806 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
807 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
811 /* WinTV-HVR2200 (PCIe, Retail, full-height)
812 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
815 /* WinTV-HVR2200 (PCIe, Retail, half-height)
816 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
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 */
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 */
829 /* First production board rev B1I6 */
830 /* WinTV-HVR2255 (PCIe, Retail, full-height bracket)
831 * ATSC/QAM (SI2157/LGDT3306) and basic analog, FM */
834 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
835 dev->name, tv.model);
839 printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
843 void saa7164_card_setup(struct saa7164_dev *dev)
845 static u8 eeprom[256];
847 if (dev->i2c_bus[0].i2c_rc == 0) {
848 if (saa7164_api_read_eeprom(dev, &eeprom[0],
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]);
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
880 * Description: Translate the kernels notion of an i2c address and bus into
881 * the appropriate unitid.
883 int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
885 /* For a given bus and i2c device address, return the saa7164 unique
886 * unitid. < 0 on error */
888 struct saa7164_dev *dev = bus->dev;
889 struct saa7164_unit *unit;
892 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
893 unit = &saa7164_boards[dev->board].unit[i];
895 if (unit->type == SAA7164_UNIT_UNDEFINED)
897 if ((bus->nr == unit->i2c_bus_nr) &&
898 (addr == unit->i2c_bus_addr))
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
909 int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
911 /* For a given bus and i2c device address, return the
912 * saa7164 registry address width. < 0 on error
915 struct saa7164_dev *dev = bus->dev;
916 struct saa7164_unit *unit;
919 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
920 unit = &saa7164_boards[dev->board].unit[i];
922 if (unit->type == SAA7164_UNIT_UNDEFINED)
925 if ((bus->nr == unit->i2c_bus_nr) &&
926 (addr == unit->i2c_bus_addr))
927 return unit->i2c_reg_len;
932 /* TODO: implement a 'findeeprom' functio like the above and fix any other
933 * eeprom related todo's in -api.c.
936 /* Translate a unitid into a x readable device name, for display purposes. */
937 char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
939 char *undefed = "UNDEFINED";
940 char *bridge = "BRIDGE";
941 struct saa7164_unit *unit;
947 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
948 unit = &saa7164_boards[dev->board].unit[i];
950 if (unit->type == SAA7164_UNIT_UNDEFINED)
953 if (unitid == unit->id)