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
)