diff options
Diffstat (limited to 'drivers/media/video/saa7164/saa7164-cards.c')
-rw-r--r-- | drivers/media/video/saa7164/saa7164-cards.c | 715 |
1 files changed, 715 insertions, 0 deletions
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c new file mode 100644 index 00000000000..c71369173fa --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-cards.c | |||
@@ -0,0 +1,715 @@ | |||
1 | /* | ||
2 | * Driver for the NXP SAA7164 PCIe bridge | ||
3 | * | ||
4 | * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/delay.h> | ||
26 | |||
27 | #include "saa7164.h" | ||
28 | |||
29 | /* The Bridge API needs to understand register widths (in bytes) for the | ||
30 | * attached I2C devices, so we can simplify the virtual i2c mechansms | ||
31 | * and keep the -i2c.c implementation clean. | ||
32 | */ | ||
33 | #define REGLEN_8bit 1 | ||
34 | #define REGLEN_16bit 2 | ||
35 | |||
36 | struct saa7164_board saa7164_boards[] = { | ||
37 | [SAA7164_BOARD_UNKNOWN] = { | ||
38 | /* Bridge will not load any firmware, without knowing | ||
39 | * the rev this would be fatal. */ | ||
40 | .name = "Unknown", | ||
41 | }, | ||
42 | [SAA7164_BOARD_UNKNOWN_REV2] = { | ||
43 | /* Bridge will load the v2 f/w and dump descriptors */ | ||
44 | /* Required during new board bringup */ | ||
45 | .name = "Generic Rev2", | ||
46 | .chiprev = SAA7164_CHIP_REV2, | ||
47 | }, | ||
48 | [SAA7164_BOARD_UNKNOWN_REV3] = { | ||
49 | /* Bridge will load the v2 f/w and dump descriptors */ | ||
50 | /* Required during new board bringup */ | ||
51 | .name = "Generic Rev3", | ||
52 | .chiprev = SAA7164_CHIP_REV3, | ||
53 | }, | ||
54 | [SAA7164_BOARD_HAUPPAUGE_HVR2200] = { | ||
55 | .name = "Hauppauge WinTV-HVR2200", | ||
56 | .porta = SAA7164_MPEG_DVB, | ||
57 | .portb = SAA7164_MPEG_DVB, | ||
58 | .portc = SAA7164_MPEG_ENCODER, | ||
59 | .portd = SAA7164_MPEG_ENCODER, | ||
60 | .porte = SAA7164_MPEG_VBI, | ||
61 | .portf = SAA7164_MPEG_VBI, | ||
62 | .chiprev = SAA7164_CHIP_REV3, | ||
63 | .unit = {{ | ||
64 | .id = 0x1d, | ||
65 | .type = SAA7164_UNIT_EEPROM, | ||
66 | .name = "4K EEPROM", | ||
67 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
68 | .i2c_bus_addr = 0xa0 >> 1, | ||
69 | .i2c_reg_len = REGLEN_8bit, | ||
70 | }, { | ||
71 | .id = 0x04, | ||
72 | .type = SAA7164_UNIT_TUNER, | ||
73 | .name = "TDA18271-1", | ||
74 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
75 | .i2c_bus_addr = 0xc0 >> 1, | ||
76 | .i2c_reg_len = REGLEN_8bit, | ||
77 | }, { | ||
78 | .id = 0x1b, | ||
79 | .type = SAA7164_UNIT_TUNER, | ||
80 | .name = "TDA18271-2", | ||
81 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
82 | .i2c_bus_addr = 0xc0 >> 1, | ||
83 | .i2c_reg_len = REGLEN_8bit, | ||
84 | }, { | ||
85 | .id = 0x1e, | ||
86 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
87 | .name = "TDA10048-1", | ||
88 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
89 | .i2c_bus_addr = 0x10 >> 1, | ||
90 | .i2c_reg_len = REGLEN_8bit, | ||
91 | }, { | ||
92 | .id = 0x1f, | ||
93 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
94 | .name = "TDA10048-2", | ||
95 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
96 | .i2c_bus_addr = 0x12 >> 1, | ||
97 | .i2c_reg_len = REGLEN_8bit, | ||
98 | } }, | ||
99 | }, | ||
100 | [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = { | ||
101 | .name = "Hauppauge WinTV-HVR2200", | ||
102 | .porta = SAA7164_MPEG_DVB, | ||
103 | .portb = SAA7164_MPEG_DVB, | ||
104 | .portc = SAA7164_MPEG_ENCODER, | ||
105 | .portd = SAA7164_MPEG_ENCODER, | ||
106 | .porte = SAA7164_MPEG_VBI, | ||
107 | .portf = SAA7164_MPEG_VBI, | ||
108 | .chiprev = SAA7164_CHIP_REV2, | ||
109 | .unit = {{ | ||
110 | .id = 0x06, | ||
111 | .type = SAA7164_UNIT_EEPROM, | ||
112 | .name = "4K EEPROM", | ||
113 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
114 | .i2c_bus_addr = 0xa0 >> 1, | ||
115 | .i2c_reg_len = REGLEN_8bit, | ||
116 | }, { | ||
117 | .id = 0x04, | ||
118 | .type = SAA7164_UNIT_TUNER, | ||
119 | .name = "TDA18271-1", | ||
120 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
121 | .i2c_bus_addr = 0xc0 >> 1, | ||
122 | .i2c_reg_len = REGLEN_8bit, | ||
123 | }, { | ||
124 | .id = 0x05, | ||
125 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
126 | .name = "TDA10048-1", | ||
127 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
128 | .i2c_bus_addr = 0x10 >> 1, | ||
129 | .i2c_reg_len = REGLEN_8bit, | ||
130 | }, { | ||
131 | .id = 0x1e, | ||
132 | .type = SAA7164_UNIT_TUNER, | ||
133 | .name = "TDA18271-2", | ||
134 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
135 | .i2c_bus_addr = 0xc0 >> 1, | ||
136 | .i2c_reg_len = REGLEN_8bit, | ||
137 | }, { | ||
138 | .id = 0x1f, | ||
139 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
140 | .name = "TDA10048-2", | ||
141 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
142 | .i2c_bus_addr = 0x12 >> 1, | ||
143 | .i2c_reg_len = REGLEN_8bit, | ||
144 | } }, | ||
145 | }, | ||
146 | [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = { | ||
147 | .name = "Hauppauge WinTV-HVR2200", | ||
148 | .porta = SAA7164_MPEG_DVB, | ||
149 | .portb = SAA7164_MPEG_DVB, | ||
150 | .portc = SAA7164_MPEG_ENCODER, | ||
151 | .portd = SAA7164_MPEG_ENCODER, | ||
152 | .porte = SAA7164_MPEG_VBI, | ||
153 | .portf = SAA7164_MPEG_VBI, | ||
154 | .chiprev = SAA7164_CHIP_REV2, | ||
155 | .unit = {{ | ||
156 | .id = 0x1d, | ||
157 | .type = SAA7164_UNIT_EEPROM, | ||
158 | .name = "4K EEPROM", | ||
159 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
160 | .i2c_bus_addr = 0xa0 >> 1, | ||
161 | .i2c_reg_len = REGLEN_8bit, | ||
162 | }, { | ||
163 | .id = 0x04, | ||
164 | .type = SAA7164_UNIT_TUNER, | ||
165 | .name = "TDA18271-1", | ||
166 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
167 | .i2c_bus_addr = 0xc0 >> 1, | ||
168 | .i2c_reg_len = REGLEN_8bit, | ||
169 | }, { | ||
170 | .id = 0x05, | ||
171 | .type = SAA7164_UNIT_ANALOG_DEMODULATOR, | ||
172 | .name = "TDA8290-1", | ||
173 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
174 | .i2c_bus_addr = 0x84 >> 1, | ||
175 | .i2c_reg_len = REGLEN_8bit, | ||
176 | }, { | ||
177 | .id = 0x1b, | ||
178 | .type = SAA7164_UNIT_TUNER, | ||
179 | .name = "TDA18271-2", | ||
180 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
181 | .i2c_bus_addr = 0xc0 >> 1, | ||
182 | .i2c_reg_len = REGLEN_8bit, | ||
183 | }, { | ||
184 | .id = 0x1c, | ||
185 | .type = SAA7164_UNIT_ANALOG_DEMODULATOR, | ||
186 | .name = "TDA8290-2", | ||
187 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
188 | .i2c_bus_addr = 0x84 >> 1, | ||
189 | .i2c_reg_len = REGLEN_8bit, | ||
190 | }, { | ||
191 | .id = 0x1e, | ||
192 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
193 | .name = "TDA10048-1", | ||
194 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
195 | .i2c_bus_addr = 0x10 >> 1, | ||
196 | .i2c_reg_len = REGLEN_8bit, | ||
197 | }, { | ||
198 | .id = 0x1f, | ||
199 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
200 | .name = "TDA10048-2", | ||
201 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
202 | .i2c_bus_addr = 0x12 >> 1, | ||
203 | .i2c_reg_len = REGLEN_8bit, | ||
204 | } }, | ||
205 | }, | ||
206 | [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = { | ||
207 | .name = "Hauppauge WinTV-HVR2200", | ||
208 | .porta = SAA7164_MPEG_DVB, | ||
209 | .portb = SAA7164_MPEG_DVB, | ||
210 | .portc = SAA7164_MPEG_ENCODER, | ||
211 | .portd = SAA7164_MPEG_ENCODER, | ||
212 | .porte = SAA7164_MPEG_VBI, | ||
213 | .portf = SAA7164_MPEG_VBI, | ||
214 | .chiprev = SAA7164_CHIP_REV3, | ||
215 | .unit = {{ | ||
216 | .id = 0x1d, | ||
217 | .type = SAA7164_UNIT_EEPROM, | ||
218 | .name = "4K EEPROM", | ||
219 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
220 | .i2c_bus_addr = 0xa0 >> 1, | ||
221 | .i2c_reg_len = REGLEN_8bit, | ||
222 | }, { | ||
223 | .id = 0x04, | ||
224 | .type = SAA7164_UNIT_TUNER, | ||
225 | .name = "TDA18271-1", | ||
226 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
227 | .i2c_bus_addr = 0xc0 >> 1, | ||
228 | .i2c_reg_len = REGLEN_8bit, | ||
229 | }, { | ||
230 | .id = 0x05, | ||
231 | .type = SAA7164_UNIT_ANALOG_DEMODULATOR, | ||
232 | .name = "TDA8290-1", | ||
233 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
234 | .i2c_bus_addr = 0x84 >> 1, | ||
235 | .i2c_reg_len = REGLEN_8bit, | ||
236 | }, { | ||
237 | .id = 0x1b, | ||
238 | .type = SAA7164_UNIT_TUNER, | ||
239 | .name = "TDA18271-2", | ||
240 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
241 | .i2c_bus_addr = 0xc0 >> 1, | ||
242 | .i2c_reg_len = REGLEN_8bit, | ||
243 | }, { | ||
244 | .id = 0x1c, | ||
245 | .type = SAA7164_UNIT_ANALOG_DEMODULATOR, | ||
246 | .name = "TDA8290-2", | ||
247 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
248 | .i2c_bus_addr = 0x84 >> 1, | ||
249 | .i2c_reg_len = REGLEN_8bit, | ||
250 | }, { | ||
251 | .id = 0x1e, | ||
252 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
253 | .name = "TDA10048-1", | ||
254 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
255 | .i2c_bus_addr = 0x10 >> 1, | ||
256 | .i2c_reg_len = REGLEN_8bit, | ||
257 | }, { | ||
258 | .id = 0x1f, | ||
259 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
260 | .name = "TDA10048-2", | ||
261 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
262 | .i2c_bus_addr = 0x12 >> 1, | ||
263 | .i2c_reg_len = REGLEN_8bit, | ||
264 | } }, | ||
265 | }, | ||
266 | [SAA7164_BOARD_HAUPPAUGE_HVR2250] = { | ||
267 | .name = "Hauppauge WinTV-HVR2250", | ||
268 | .porta = SAA7164_MPEG_DVB, | ||
269 | .portb = SAA7164_MPEG_DVB, | ||
270 | .portc = SAA7164_MPEG_ENCODER, | ||
271 | .portd = SAA7164_MPEG_ENCODER, | ||
272 | .portc = SAA7164_MPEG_ENCODER, | ||
273 | .portd = SAA7164_MPEG_ENCODER, | ||
274 | .porte = SAA7164_MPEG_VBI, | ||
275 | .portf = SAA7164_MPEG_VBI, | ||
276 | .chiprev = SAA7164_CHIP_REV3, | ||
277 | .unit = {{ | ||
278 | .id = 0x22, | ||
279 | .type = SAA7164_UNIT_EEPROM, | ||
280 | .name = "4K EEPROM", | ||
281 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
282 | .i2c_bus_addr = 0xa0 >> 1, | ||
283 | .i2c_reg_len = REGLEN_8bit, | ||
284 | }, { | ||
285 | .id = 0x04, | ||
286 | .type = SAA7164_UNIT_TUNER, | ||
287 | .name = "TDA18271-1", | ||
288 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
289 | .i2c_bus_addr = 0xc0 >> 1, | ||
290 | .i2c_reg_len = REGLEN_8bit, | ||
291 | }, { | ||
292 | .id = 0x07, | ||
293 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
294 | .name = "CX24228/S5H1411-1 (TOP)", | ||
295 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
296 | .i2c_bus_addr = 0x32 >> 1, | ||
297 | .i2c_reg_len = REGLEN_8bit, | ||
298 | }, { | ||
299 | .id = 0x08, | ||
300 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
301 | .name = "CX24228/S5H1411-1 (QAM)", | ||
302 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
303 | .i2c_bus_addr = 0x34 >> 1, | ||
304 | .i2c_reg_len = REGLEN_8bit, | ||
305 | }, { | ||
306 | .id = 0x1e, | ||
307 | .type = SAA7164_UNIT_TUNER, | ||
308 | .name = "TDA18271-2", | ||
309 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
310 | .i2c_bus_addr = 0xc0 >> 1, | ||
311 | .i2c_reg_len = REGLEN_8bit, | ||
312 | }, { | ||
313 | .id = 0x20, | ||
314 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
315 | .name = "CX24228/S5H1411-2 (TOP)", | ||
316 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
317 | .i2c_bus_addr = 0x32 >> 1, | ||
318 | .i2c_reg_len = REGLEN_8bit, | ||
319 | }, { | ||
320 | .id = 0x23, | ||
321 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
322 | .name = "CX24228/S5H1411-2 (QAM)", | ||
323 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
324 | .i2c_bus_addr = 0x34 >> 1, | ||
325 | .i2c_reg_len = REGLEN_8bit, | ||
326 | } }, | ||
327 | }, | ||
328 | [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = { | ||
329 | .name = "Hauppauge WinTV-HVR2250", | ||
330 | .porta = SAA7164_MPEG_DVB, | ||
331 | .portb = SAA7164_MPEG_DVB, | ||
332 | .portc = SAA7164_MPEG_ENCODER, | ||
333 | .portd = SAA7164_MPEG_ENCODER, | ||
334 | .porte = SAA7164_MPEG_VBI, | ||
335 | .portf = SAA7164_MPEG_VBI, | ||
336 | .porte = SAA7164_MPEG_VBI, | ||
337 | .portf = SAA7164_MPEG_VBI, | ||
338 | .chiprev = SAA7164_CHIP_REV3, | ||
339 | .unit = {{ | ||
340 | .id = 0x28, | ||
341 | .type = SAA7164_UNIT_EEPROM, | ||
342 | .name = "4K EEPROM", | ||
343 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
344 | .i2c_bus_addr = 0xa0 >> 1, | ||
345 | .i2c_reg_len = REGLEN_8bit, | ||
346 | }, { | ||
347 | .id = 0x04, | ||
348 | .type = SAA7164_UNIT_TUNER, | ||
349 | .name = "TDA18271-1", | ||
350 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
351 | .i2c_bus_addr = 0xc0 >> 1, | ||
352 | .i2c_reg_len = REGLEN_8bit, | ||
353 | }, { | ||
354 | .id = 0x07, | ||
355 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
356 | .name = "CX24228/S5H1411-1 (TOP)", | ||
357 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
358 | .i2c_bus_addr = 0x32 >> 1, | ||
359 | .i2c_reg_len = REGLEN_8bit, | ||
360 | }, { | ||
361 | .id = 0x08, | ||
362 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
363 | .name = "CX24228/S5H1411-1 (QAM)", | ||
364 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
365 | .i2c_bus_addr = 0x34 >> 1, | ||
366 | .i2c_reg_len = REGLEN_8bit, | ||
367 | }, { | ||
368 | .id = 0x24, | ||
369 | .type = SAA7164_UNIT_TUNER, | ||
370 | .name = "TDA18271-2", | ||
371 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
372 | .i2c_bus_addr = 0xc0 >> 1, | ||
373 | .i2c_reg_len = REGLEN_8bit, | ||
374 | }, { | ||
375 | .id = 0x26, | ||
376 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
377 | .name = "CX24228/S5H1411-2 (TOP)", | ||
378 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
379 | .i2c_bus_addr = 0x32 >> 1, | ||
380 | .i2c_reg_len = REGLEN_8bit, | ||
381 | }, { | ||
382 | .id = 0x29, | ||
383 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
384 | .name = "CX24228/S5H1411-2 (QAM)", | ||
385 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
386 | .i2c_bus_addr = 0x34 >> 1, | ||
387 | .i2c_reg_len = REGLEN_8bit, | ||
388 | } }, | ||
389 | }, | ||
390 | [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = { | ||
391 | .name = "Hauppauge WinTV-HVR2250", | ||
392 | .porta = SAA7164_MPEG_DVB, | ||
393 | .portb = SAA7164_MPEG_DVB, | ||
394 | .portc = SAA7164_MPEG_ENCODER, | ||
395 | .portd = SAA7164_MPEG_ENCODER, | ||
396 | .porte = SAA7164_MPEG_VBI, | ||
397 | .portf = SAA7164_MPEG_VBI, | ||
398 | .chiprev = SAA7164_CHIP_REV3, | ||
399 | .unit = {{ | ||
400 | .id = 0x26, | ||
401 | .type = SAA7164_UNIT_EEPROM, | ||
402 | .name = "4K EEPROM", | ||
403 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
404 | .i2c_bus_addr = 0xa0 >> 1, | ||
405 | .i2c_reg_len = REGLEN_8bit, | ||
406 | }, { | ||
407 | .id = 0x04, | ||
408 | .type = SAA7164_UNIT_TUNER, | ||
409 | .name = "TDA18271-1", | ||
410 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
411 | .i2c_bus_addr = 0xc0 >> 1, | ||
412 | .i2c_reg_len = REGLEN_8bit, | ||
413 | }, { | ||
414 | .id = 0x07, | ||
415 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
416 | .name = "CX24228/S5H1411-1 (TOP)", | ||
417 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
418 | .i2c_bus_addr = 0x32 >> 1, | ||
419 | .i2c_reg_len = REGLEN_8bit, | ||
420 | }, { | ||
421 | .id = 0x08, | ||
422 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
423 | .name = "CX24228/S5H1411-1 (QAM)", | ||
424 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
425 | .i2c_bus_addr = 0x34 >> 1, | ||
426 | .i2c_reg_len = REGLEN_8bit, | ||
427 | }, { | ||
428 | .id = 0x22, | ||
429 | .type = SAA7164_UNIT_TUNER, | ||
430 | .name = "TDA18271-2", | ||
431 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
432 | .i2c_bus_addr = 0xc0 >> 1, | ||
433 | .i2c_reg_len = REGLEN_8bit, | ||
434 | }, { | ||
435 | .id = 0x24, | ||
436 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
437 | .name = "CX24228/S5H1411-2 (TOP)", | ||
438 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
439 | .i2c_bus_addr = 0x32 >> 1, | ||
440 | .i2c_reg_len = REGLEN_8bit, | ||
441 | }, { | ||
442 | .id = 0x27, | ||
443 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
444 | .name = "CX24228/S5H1411-2 (QAM)", | ||
445 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
446 | .i2c_bus_addr = 0x34 >> 1, | ||
447 | .i2c_reg_len = REGLEN_8bit, | ||
448 | } }, | ||
449 | }, | ||
450 | }; | ||
451 | const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards); | ||
452 | |||
453 | /* ------------------------------------------------------------------ */ | ||
454 | /* PCI subsystem IDs */ | ||
455 | |||
456 | struct saa7164_subid saa7164_subids[] = { | ||
457 | { | ||
458 | .subvendor = 0x0070, | ||
459 | .subdevice = 0x8880, | ||
460 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, | ||
461 | }, { | ||
462 | .subvendor = 0x0070, | ||
463 | .subdevice = 0x8810, | ||
464 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, | ||
465 | }, { | ||
466 | .subvendor = 0x0070, | ||
467 | .subdevice = 0x8980, | ||
468 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200, | ||
469 | }, { | ||
470 | .subvendor = 0x0070, | ||
471 | .subdevice = 0x8900, | ||
472 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2, | ||
473 | }, { | ||
474 | .subvendor = 0x0070, | ||
475 | .subdevice = 0x8901, | ||
476 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3, | ||
477 | }, { | ||
478 | .subvendor = 0x0070, | ||
479 | .subdevice = 0x88A1, | ||
480 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3, | ||
481 | }, { | ||
482 | .subvendor = 0x0070, | ||
483 | .subdevice = 0x8891, | ||
484 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, | ||
485 | }, { | ||
486 | .subvendor = 0x0070, | ||
487 | .subdevice = 0x8851, | ||
488 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, | ||
489 | }, { | ||
490 | .subvendor = 0x0070, | ||
491 | .subdevice = 0x8940, | ||
492 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_4, | ||
493 | }, | ||
494 | }; | ||
495 | const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids); | ||
496 | |||
497 | void saa7164_card_list(struct saa7164_dev *dev) | ||
498 | { | ||
499 | int i; | ||
500 | |||
501 | if (0 == dev->pci->subsystem_vendor && | ||
502 | 0 == dev->pci->subsystem_device) { | ||
503 | printk(KERN_ERR | ||
504 | "%s: Board has no valid PCIe Subsystem ID and can't\n" | ||
505 | "%s: be autodetected. Pass card=<n> insmod option to\n" | ||
506 | "%s: workaround that. Send complaints to the vendor\n" | ||
507 | "%s: of the TV card. Best regards,\n" | ||
508 | "%s: -- tux\n", | ||
509 | dev->name, dev->name, dev->name, dev->name, dev->name); | ||
510 | } else { | ||
511 | printk(KERN_ERR | ||
512 | "%s: Your board isn't known (yet) to the driver.\n" | ||
513 | "%s: Try to pick one of the existing card configs via\n" | ||
514 | "%s: card=<n> insmod option. Updating to the latest\n" | ||
515 | "%s: version might help as well.\n", | ||
516 | dev->name, dev->name, dev->name, dev->name); | ||
517 | } | ||
518 | |||
519 | printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod " | ||
520 | "option:\n", dev->name); | ||
521 | |||
522 | for (i = 0; i < saa7164_bcount; i++) | ||
523 | printk(KERN_ERR "%s: card=%d -> %s\n", | ||
524 | dev->name, i, saa7164_boards[i].name); | ||
525 | } | ||
526 | |||
527 | /* TODO: clean this define up into the -cards.c structs */ | ||
528 | #define PCIEBRIDGE_UNITID 2 | ||
529 | |||
530 | void saa7164_gpio_setup(struct saa7164_dev *dev) | ||
531 | { | ||
532 | switch (dev->board) { | ||
533 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: | ||
534 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: | ||
535 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: | ||
536 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: | ||
537 | case SAA7164_BOARD_HAUPPAUGE_HVR2250: | ||
538 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: | ||
539 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: | ||
540 | /* | ||
541 | GPIO 2: s5h1411 / tda10048-1 demod reset | ||
542 | GPIO 3: s5h1411 / tda10048-2 demod reset | ||
543 | GPIO 7: IRBlaster Zilog reset | ||
544 | */ | ||
545 | |||
546 | /* Reset parts by going in and out of reset */ | ||
547 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | ||
548 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | ||
549 | |||
550 | msleep(20); | ||
551 | |||
552 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | ||
553 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data) | ||
559 | { | ||
560 | struct tveeprom tv; | ||
561 | |||
562 | /* TODO: Assumption: eeprom on bus 0 */ | ||
563 | tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, | ||
564 | eeprom_data); | ||
565 | |||
566 | /* Make sure we support the board model */ | ||
567 | switch (tv.model) { | ||
568 | case 88001: | ||
569 | /* Development board - Limit circulation */ | ||
570 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
571 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ | ||
572 | case 88021: | ||
573 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
574 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */ | ||
575 | break; | ||
576 | case 88041: | ||
577 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
578 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ | ||
579 | break; | ||
580 | case 88061: | ||
581 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
582 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */ | ||
583 | break; | ||
584 | case 89519: | ||
585 | case 89609: | ||
586 | /* WinTV-HVR2200 (PCIe, Retail, full-height) | ||
587 | * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ | ||
588 | break; | ||
589 | case 89619: | ||
590 | /* WinTV-HVR2200 (PCIe, Retail, half-height) | ||
591 | * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ | ||
592 | break; | ||
593 | default: | ||
594 | printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n", | ||
595 | dev->name, tv.model); | ||
596 | break; | ||
597 | } | ||
598 | |||
599 | printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name, | ||
600 | tv.model); | ||
601 | } | ||
602 | |||
603 | void saa7164_card_setup(struct saa7164_dev *dev) | ||
604 | { | ||
605 | static u8 eeprom[256]; | ||
606 | |||
607 | if (dev->i2c_bus[0].i2c_rc == 0) { | ||
608 | if (saa7164_api_read_eeprom(dev, &eeprom[0], | ||
609 | sizeof(eeprom)) < 0) | ||
610 | return; | ||
611 | } | ||
612 | |||
613 | switch (dev->board) { | ||
614 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: | ||
615 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: | ||
616 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: | ||
617 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: | ||
618 | case SAA7164_BOARD_HAUPPAUGE_HVR2250: | ||
619 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: | ||
620 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: | ||
621 | hauppauge_eeprom(dev, &eeprom[0]); | ||
622 | break; | ||
623 | } | ||
624 | } | ||
625 | |||
626 | /* With most other drivers, the kernel expects to communicate with subdrivers | ||
627 | * through i2c. This bridge does not allow that, it does not expose any direct | ||
628 | * access to I2C. Instead we have to communicate through the device f/w for | ||
629 | * register access to 'processing units'. Each unit has a unique | ||
630 | * id, regardless of how the physical implementation occurs across | ||
631 | * the three physical i2c busses. The being said if we want leverge of | ||
632 | * the existing kernel drivers for tuners and demods we have to 'speak i2c', | ||
633 | * to this bridge implements 3 virtual i2c buses. This is a helper function | ||
634 | * for those. | ||
635 | * | ||
636 | * Description: Translate the kernels notion of an i2c address and bus into | ||
637 | * the appropriate unitid. | ||
638 | */ | ||
639 | int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr) | ||
640 | { | ||
641 | /* For a given bus and i2c device address, return the saa7164 unique | ||
642 | * unitid. < 0 on error */ | ||
643 | |||
644 | struct saa7164_dev *dev = bus->dev; | ||
645 | struct saa7164_unit *unit; | ||
646 | int i; | ||
647 | |||
648 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
649 | unit = &saa7164_boards[dev->board].unit[i]; | ||
650 | |||
651 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
652 | continue; | ||
653 | if ((bus->nr == unit->i2c_bus_nr) && | ||
654 | (addr == unit->i2c_bus_addr)) | ||
655 | return unit->id; | ||
656 | } | ||
657 | |||
658 | return -1; | ||
659 | } | ||
660 | |||
661 | /* The 7164 API needs to know the i2c register length in advance. | ||
662 | * this is a helper function. Based on a specific chip addr and bus return the | ||
663 | * reg length. | ||
664 | */ | ||
665 | int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr) | ||
666 | { | ||
667 | /* For a given bus and i2c device address, return the | ||
668 | * saa7164 registry address width. < 0 on error | ||
669 | */ | ||
670 | |||
671 | struct saa7164_dev *dev = bus->dev; | ||
672 | struct saa7164_unit *unit; | ||
673 | int i; | ||
674 | |||
675 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
676 | unit = &saa7164_boards[dev->board].unit[i]; | ||
677 | |||
678 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
679 | continue; | ||
680 | |||
681 | if ((bus->nr == unit->i2c_bus_nr) && | ||
682 | (addr == unit->i2c_bus_addr)) | ||
683 | return unit->i2c_reg_len; | ||
684 | } | ||
685 | |||
686 | return -1; | ||
687 | } | ||
688 | /* TODO: implement a 'findeeprom' functio like the above and fix any other | ||
689 | * eeprom related todo's in -api.c. | ||
690 | */ | ||
691 | |||
692 | /* Translate a unitid into a x readable device name, for display purposes. */ | ||
693 | char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid) | ||
694 | { | ||
695 | char *undefed = "UNDEFINED"; | ||
696 | char *bridge = "BRIDGE"; | ||
697 | struct saa7164_unit *unit; | ||
698 | int i; | ||
699 | |||
700 | if (unitid == 0) | ||
701 | return bridge; | ||
702 | |||
703 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
704 | unit = &saa7164_boards[dev->board].unit[i]; | ||
705 | |||
706 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
707 | continue; | ||
708 | |||
709 | if (unitid == unit->id) | ||
710 | return unit->name; | ||
711 | } | ||
712 | |||
713 | return undefed; | ||
714 | } | ||
715 | |||