Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux...
[linux/fpc-iii.git] / drivers / media / pci / saa7164 / saa7164-cards.c
blobc2b738227f5837044a6d9207c47a4c4e5393aeb7
1 /*
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>
27 #include "saa7164.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.
33 #define REGLEN_0bit 0
34 #define REGLEN_8bit 1
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. */
41 .name = "Unknown",
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,
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
642 const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
644 /* ------------------------------------------------------------------ */
645 /* PCI subsystem IDs */
647 struct saa7164_subid saa7164_subids[] = {
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,
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,
705 const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
707 void saa7164_card_list(struct saa7164_dev *dev)
709 int i;
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);
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:
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
761 /* HVR2255
762 * GPIO 2: lgdg3306-1 demod reset
763 * GPIO 3: lgdt3306-2 demod reset
766 /* HVR2205
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);
775 msleep(20);
777 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
778 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
779 break;
783 static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
785 struct tveeprom tv;
787 /* TODO: Assumption: eeprom on bus 0 */
788 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
789 eeprom_data);
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;
839 printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
840 tv.model);
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],
849 sizeof(eeprom)) < 0)
850 return;
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;
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.
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;
890 int i;
892 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
893 unit = &saa7164_boards[dev->board].unit[i];
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;
902 return -1;
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.
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;
917 int i;
919 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
920 unit = &saa7164_boards[dev->board].unit[i];
922 if (unit->type == SAA7164_UNIT_UNDEFINED)
923 continue;
925 if ((bus->nr == unit->i2c_bus_nr) &&
926 (addr == unit->i2c_bus_addr))
927 return unit->i2c_reg_len;
930 return -1;
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;
942 int i;
944 if (unitid == 0)
945 return bridge;
947 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
948 unit = &saa7164_boards[dev->board].unit[i];
950 if (unit->type == SAA7164_UNIT_UNDEFINED)
951 continue;
953 if (unitid == unit->id)
954 return unit->name;
957 return undefed;