diff options
Diffstat (limited to 'drivers/media/video/saa7164/saa7164-cards.c')
-rw-r--r-- | drivers/media/video/saa7164/saa7164-cards.c | 624 |
1 files changed, 624 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 000000000000..a3c299405f46 --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-cards.c | |||
@@ -0,0 +1,624 @@ | |||
1 | /* | ||
2 | * Driver for the NXP SAA7164 PCIe bridge | ||
3 | * | ||
4 | * Copyright (c) 2009 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 | .chiprev = SAA7164_CHIP_REV3, | ||
59 | .unit = {{ | ||
60 | .id = 0x1d, | ||
61 | .type = SAA7164_UNIT_EEPROM, | ||
62 | .name = "4K EEPROM", | ||
63 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
64 | .i2c_bus_addr = 0xa0 >> 1, | ||
65 | .i2c_reg_len = REGLEN_8bit, | ||
66 | }, { | ||
67 | .id = 0x04, | ||
68 | .type = SAA7164_UNIT_TUNER, | ||
69 | .name = "TDA18271-1", | ||
70 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
71 | .i2c_bus_addr = 0xc0 >> 1, | ||
72 | .i2c_reg_len = REGLEN_8bit, | ||
73 | }, { | ||
74 | .id = 0x1b, | ||
75 | .type = SAA7164_UNIT_TUNER, | ||
76 | .name = "TDA18271-2", | ||
77 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
78 | .i2c_bus_addr = 0xc0 >> 1, | ||
79 | .i2c_reg_len = REGLEN_8bit, | ||
80 | }, { | ||
81 | .id = 0x1e, | ||
82 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
83 | .name = "TDA10048-1", | ||
84 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
85 | .i2c_bus_addr = 0x10 >> 1, | ||
86 | .i2c_reg_len = REGLEN_8bit, | ||
87 | }, { | ||
88 | .id = 0x1f, | ||
89 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
90 | .name = "TDA10048-2", | ||
91 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
92 | .i2c_bus_addr = 0x12 >> 1, | ||
93 | .i2c_reg_len = REGLEN_8bit, | ||
94 | } }, | ||
95 | }, | ||
96 | [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = { | ||
97 | .name = "Hauppauge WinTV-HVR2200", | ||
98 | .porta = SAA7164_MPEG_DVB, | ||
99 | .portb = SAA7164_MPEG_DVB, | ||
100 | .chiprev = SAA7164_CHIP_REV2, | ||
101 | .unit = {{ | ||
102 | .id = 0x06, | ||
103 | .type = SAA7164_UNIT_EEPROM, | ||
104 | .name = "4K EEPROM", | ||
105 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
106 | .i2c_bus_addr = 0xa0 >> 1, | ||
107 | .i2c_reg_len = REGLEN_8bit, | ||
108 | }, { | ||
109 | .id = 0x04, | ||
110 | .type = SAA7164_UNIT_TUNER, | ||
111 | .name = "TDA18271-1", | ||
112 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
113 | .i2c_bus_addr = 0xc0 >> 1, | ||
114 | .i2c_reg_len = REGLEN_8bit, | ||
115 | }, { | ||
116 | .id = 0x05, | ||
117 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
118 | .name = "TDA10048-1", | ||
119 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
120 | .i2c_bus_addr = 0x10 >> 1, | ||
121 | .i2c_reg_len = REGLEN_8bit, | ||
122 | }, { | ||
123 | .id = 0x1e, | ||
124 | .type = SAA7164_UNIT_TUNER, | ||
125 | .name = "TDA18271-2", | ||
126 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
127 | .i2c_bus_addr = 0xc0 >> 1, | ||
128 | .i2c_reg_len = REGLEN_8bit, | ||
129 | }, { | ||
130 | .id = 0x1f, | ||
131 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
132 | .name = "TDA10048-2", | ||
133 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
134 | .i2c_bus_addr = 0x12 >> 1, | ||
135 | .i2c_reg_len = REGLEN_8bit, | ||
136 | } }, | ||
137 | }, | ||
138 | [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = { | ||
139 | .name = "Hauppauge WinTV-HVR2200", | ||
140 | .porta = SAA7164_MPEG_DVB, | ||
141 | .portb = SAA7164_MPEG_DVB, | ||
142 | .chiprev = SAA7164_CHIP_REV2, | ||
143 | .unit = {{ | ||
144 | .id = 0x1d, | ||
145 | .type = SAA7164_UNIT_EEPROM, | ||
146 | .name = "4K EEPROM", | ||
147 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
148 | .i2c_bus_addr = 0xa0 >> 1, | ||
149 | .i2c_reg_len = REGLEN_8bit, | ||
150 | }, { | ||
151 | .id = 0x04, | ||
152 | .type = SAA7164_UNIT_TUNER, | ||
153 | .name = "TDA18271-1", | ||
154 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
155 | .i2c_bus_addr = 0xc0 >> 1, | ||
156 | .i2c_reg_len = REGLEN_8bit, | ||
157 | }, { | ||
158 | .id = 0x05, | ||
159 | .type = SAA7164_UNIT_ANALOG_DEMODULATOR, | ||
160 | .name = "TDA8290-1", | ||
161 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
162 | .i2c_bus_addr = 0x84 >> 1, | ||
163 | .i2c_reg_len = REGLEN_8bit, | ||
164 | }, { | ||
165 | .id = 0x1b, | ||
166 | .type = SAA7164_UNIT_TUNER, | ||
167 | .name = "TDA18271-2", | ||
168 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
169 | .i2c_bus_addr = 0xc0 >> 1, | ||
170 | .i2c_reg_len = REGLEN_8bit, | ||
171 | }, { | ||
172 | .id = 0x1c, | ||
173 | .type = SAA7164_UNIT_ANALOG_DEMODULATOR, | ||
174 | .name = "TDA8290-2", | ||
175 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
176 | .i2c_bus_addr = 0x84 >> 1, | ||
177 | .i2c_reg_len = REGLEN_8bit, | ||
178 | }, { | ||
179 | .id = 0x1e, | ||
180 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
181 | .name = "TDA10048-1", | ||
182 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
183 | .i2c_bus_addr = 0x10 >> 1, | ||
184 | .i2c_reg_len = REGLEN_8bit, | ||
185 | }, { | ||
186 | .id = 0x1f, | ||
187 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
188 | .name = "TDA10048-2", | ||
189 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
190 | .i2c_bus_addr = 0x12 >> 1, | ||
191 | .i2c_reg_len = REGLEN_8bit, | ||
192 | } }, | ||
193 | }, | ||
194 | [SAA7164_BOARD_HAUPPAUGE_HVR2250] = { | ||
195 | .name = "Hauppauge WinTV-HVR2250", | ||
196 | .porta = SAA7164_MPEG_DVB, | ||
197 | .portb = SAA7164_MPEG_DVB, | ||
198 | .chiprev = SAA7164_CHIP_REV3, | ||
199 | .unit = {{ | ||
200 | .id = 0x22, | ||
201 | .type = SAA7164_UNIT_EEPROM, | ||
202 | .name = "4K EEPROM", | ||
203 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
204 | .i2c_bus_addr = 0xa0 >> 1, | ||
205 | .i2c_reg_len = REGLEN_8bit, | ||
206 | }, { | ||
207 | .id = 0x04, | ||
208 | .type = SAA7164_UNIT_TUNER, | ||
209 | .name = "TDA18271-1", | ||
210 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
211 | .i2c_bus_addr = 0xc0 >> 1, | ||
212 | .i2c_reg_len = REGLEN_8bit, | ||
213 | }, { | ||
214 | .id = 0x07, | ||
215 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
216 | .name = "CX24228/S5H1411-1 (TOP)", | ||
217 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
218 | .i2c_bus_addr = 0x32 >> 1, | ||
219 | .i2c_reg_len = REGLEN_8bit, | ||
220 | }, { | ||
221 | .id = 0x08, | ||
222 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
223 | .name = "CX24228/S5H1411-1 (QAM)", | ||
224 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
225 | .i2c_bus_addr = 0x34 >> 1, | ||
226 | .i2c_reg_len = REGLEN_8bit, | ||
227 | }, { | ||
228 | .id = 0x1e, | ||
229 | .type = SAA7164_UNIT_TUNER, | ||
230 | .name = "TDA18271-2", | ||
231 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
232 | .i2c_bus_addr = 0xc0 >> 1, | ||
233 | .i2c_reg_len = REGLEN_8bit, | ||
234 | }, { | ||
235 | .id = 0x20, | ||
236 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
237 | .name = "CX24228/S5H1411-2 (TOP)", | ||
238 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
239 | .i2c_bus_addr = 0x32 >> 1, | ||
240 | .i2c_reg_len = REGLEN_8bit, | ||
241 | }, { | ||
242 | .id = 0x23, | ||
243 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
244 | .name = "CX24228/S5H1411-2 (QAM)", | ||
245 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
246 | .i2c_bus_addr = 0x34 >> 1, | ||
247 | .i2c_reg_len = REGLEN_8bit, | ||
248 | } }, | ||
249 | }, | ||
250 | [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = { | ||
251 | .name = "Hauppauge WinTV-HVR2250", | ||
252 | .porta = SAA7164_MPEG_DVB, | ||
253 | .portb = SAA7164_MPEG_DVB, | ||
254 | .chiprev = SAA7164_CHIP_REV3, | ||
255 | .unit = {{ | ||
256 | .id = 0x28, | ||
257 | .type = SAA7164_UNIT_EEPROM, | ||
258 | .name = "4K EEPROM", | ||
259 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
260 | .i2c_bus_addr = 0xa0 >> 1, | ||
261 | .i2c_reg_len = REGLEN_8bit, | ||
262 | }, { | ||
263 | .id = 0x04, | ||
264 | .type = SAA7164_UNIT_TUNER, | ||
265 | .name = "TDA18271-1", | ||
266 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
267 | .i2c_bus_addr = 0xc0 >> 1, | ||
268 | .i2c_reg_len = REGLEN_8bit, | ||
269 | }, { | ||
270 | .id = 0x07, | ||
271 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
272 | .name = "CX24228/S5H1411-1 (TOP)", | ||
273 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
274 | .i2c_bus_addr = 0x32 >> 1, | ||
275 | .i2c_reg_len = REGLEN_8bit, | ||
276 | }, { | ||
277 | .id = 0x08, | ||
278 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
279 | .name = "CX24228/S5H1411-1 (QAM)", | ||
280 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
281 | .i2c_bus_addr = 0x34 >> 1, | ||
282 | .i2c_reg_len = REGLEN_8bit, | ||
283 | }, { | ||
284 | .id = 0x24, | ||
285 | .type = SAA7164_UNIT_TUNER, | ||
286 | .name = "TDA18271-2", | ||
287 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
288 | .i2c_bus_addr = 0xc0 >> 1, | ||
289 | .i2c_reg_len = REGLEN_8bit, | ||
290 | }, { | ||
291 | .id = 0x26, | ||
292 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
293 | .name = "CX24228/S5H1411-2 (TOP)", | ||
294 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
295 | .i2c_bus_addr = 0x32 >> 1, | ||
296 | .i2c_reg_len = REGLEN_8bit, | ||
297 | }, { | ||
298 | .id = 0x29, | ||
299 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
300 | .name = "CX24228/S5H1411-2 (QAM)", | ||
301 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
302 | .i2c_bus_addr = 0x34 >> 1, | ||
303 | .i2c_reg_len = REGLEN_8bit, | ||
304 | } }, | ||
305 | }, | ||
306 | [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = { | ||
307 | .name = "Hauppauge WinTV-HVR2250", | ||
308 | .porta = SAA7164_MPEG_DVB, | ||
309 | .portb = SAA7164_MPEG_DVB, | ||
310 | .chiprev = SAA7164_CHIP_REV3, | ||
311 | .unit = {{ | ||
312 | .id = 0x26, | ||
313 | .type = SAA7164_UNIT_EEPROM, | ||
314 | .name = "4K EEPROM", | ||
315 | .i2c_bus_nr = SAA7164_I2C_BUS_0, | ||
316 | .i2c_bus_addr = 0xa0 >> 1, | ||
317 | .i2c_reg_len = REGLEN_8bit, | ||
318 | }, { | ||
319 | .id = 0x04, | ||
320 | .type = SAA7164_UNIT_TUNER, | ||
321 | .name = "TDA18271-1", | ||
322 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
323 | .i2c_bus_addr = 0xc0 >> 1, | ||
324 | .i2c_reg_len = REGLEN_8bit, | ||
325 | }, { | ||
326 | .id = 0x07, | ||
327 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
328 | .name = "CX24228/S5H1411-1 (TOP)", | ||
329 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
330 | .i2c_bus_addr = 0x32 >> 1, | ||
331 | .i2c_reg_len = REGLEN_8bit, | ||
332 | }, { | ||
333 | .id = 0x08, | ||
334 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
335 | .name = "CX24228/S5H1411-1 (QAM)", | ||
336 | .i2c_bus_nr = SAA7164_I2C_BUS_1, | ||
337 | .i2c_bus_addr = 0x34 >> 1, | ||
338 | .i2c_reg_len = REGLEN_8bit, | ||
339 | }, { | ||
340 | .id = 0x22, | ||
341 | .type = SAA7164_UNIT_TUNER, | ||
342 | .name = "TDA18271-2", | ||
343 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
344 | .i2c_bus_addr = 0xc0 >> 1, | ||
345 | .i2c_reg_len = REGLEN_8bit, | ||
346 | }, { | ||
347 | .id = 0x24, | ||
348 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
349 | .name = "CX24228/S5H1411-2 (TOP)", | ||
350 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
351 | .i2c_bus_addr = 0x32 >> 1, | ||
352 | .i2c_reg_len = REGLEN_8bit, | ||
353 | }, { | ||
354 | .id = 0x27, | ||
355 | .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, | ||
356 | .name = "CX24228/S5H1411-2 (QAM)", | ||
357 | .i2c_bus_nr = SAA7164_I2C_BUS_2, | ||
358 | .i2c_bus_addr = 0x34 >> 1, | ||
359 | .i2c_reg_len = REGLEN_8bit, | ||
360 | } }, | ||
361 | }, | ||
362 | }; | ||
363 | const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards); | ||
364 | |||
365 | /* ------------------------------------------------------------------ */ | ||
366 | /* PCI subsystem IDs */ | ||
367 | |||
368 | struct saa7164_subid saa7164_subids[] = { | ||
369 | { | ||
370 | .subvendor = 0x0070, | ||
371 | .subdevice = 0x8880, | ||
372 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, | ||
373 | }, { | ||
374 | .subvendor = 0x0070, | ||
375 | .subdevice = 0x8810, | ||
376 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, | ||
377 | }, { | ||
378 | .subvendor = 0x0070, | ||
379 | .subdevice = 0x8980, | ||
380 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200, | ||
381 | }, { | ||
382 | .subvendor = 0x0070, | ||
383 | .subdevice = 0x8900, | ||
384 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2, | ||
385 | }, { | ||
386 | .subvendor = 0x0070, | ||
387 | .subdevice = 0x8901, | ||
388 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3, | ||
389 | }, { | ||
390 | .subvendor = 0x0070, | ||
391 | .subdevice = 0x88A1, | ||
392 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3, | ||
393 | }, { | ||
394 | .subvendor = 0x0070, | ||
395 | .subdevice = 0x8891, | ||
396 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, | ||
397 | }, { | ||
398 | .subvendor = 0x0070, | ||
399 | .subdevice = 0x8851, | ||
400 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, | ||
401 | }, | ||
402 | }; | ||
403 | const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids); | ||
404 | |||
405 | void saa7164_card_list(struct saa7164_dev *dev) | ||
406 | { | ||
407 | int i; | ||
408 | |||
409 | if (0 == dev->pci->subsystem_vendor && | ||
410 | 0 == dev->pci->subsystem_device) { | ||
411 | printk(KERN_ERR | ||
412 | "%s: Board has no valid PCIe Subsystem ID and can't\n" | ||
413 | "%s: be autodetected. Pass card=<n> insmod option to\n" | ||
414 | "%s: workaround that. Send complaints to the vendor\n" | ||
415 | "%s: of the TV card. Best regards,\n" | ||
416 | "%s: -- tux\n", | ||
417 | dev->name, dev->name, dev->name, dev->name, dev->name); | ||
418 | } else { | ||
419 | printk(KERN_ERR | ||
420 | "%s: Your board isn't known (yet) to the driver.\n" | ||
421 | "%s: Try to pick one of the existing card configs via\n" | ||
422 | "%s: card=<n> insmod option. Updating to the latest\n" | ||
423 | "%s: version might help as well.\n", | ||
424 | dev->name, dev->name, dev->name, dev->name); | ||
425 | } | ||
426 | |||
427 | printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod " | ||
428 | "option:\n", dev->name); | ||
429 | |||
430 | for (i = 0; i < saa7164_bcount; i++) | ||
431 | printk(KERN_ERR "%s: card=%d -> %s\n", | ||
432 | dev->name, i, saa7164_boards[i].name); | ||
433 | } | ||
434 | |||
435 | /* TODO: clean this define up into the -cards.c structs */ | ||
436 | #define PCIEBRIDGE_UNITID 2 | ||
437 | |||
438 | void saa7164_gpio_setup(struct saa7164_dev *dev) | ||
439 | { | ||
440 | |||
441 | |||
442 | switch (dev->board) { | ||
443 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: | ||
444 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: | ||
445 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: | ||
446 | case SAA7164_BOARD_HAUPPAUGE_HVR2250: | ||
447 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: | ||
448 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: | ||
449 | /* | ||
450 | GPIO 2: s5h1411 / tda10048-1 demod reset | ||
451 | GPIO 3: s5h1411 / tda10048-2 demod reset | ||
452 | GPIO 7: IRBlaster Zilog reset | ||
453 | */ | ||
454 | |||
455 | /* Reset parts by going in and out of reset */ | ||
456 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | ||
457 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | ||
458 | |||
459 | msleep(10); | ||
460 | |||
461 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | ||
462 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | ||
463 | break; | ||
464 | } | ||
465 | |||
466 | } | ||
467 | |||
468 | static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data) | ||
469 | { | ||
470 | struct tveeprom tv; | ||
471 | |||
472 | /* TODO: Assumption: eeprom on bus 0 */ | ||
473 | tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, | ||
474 | eeprom_data); | ||
475 | |||
476 | /* Make sure we support the board model */ | ||
477 | switch (tv.model) { | ||
478 | case 88001: | ||
479 | /* Development board - Limit circulation */ | ||
480 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
481 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ | ||
482 | case 88021: | ||
483 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
484 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */ | ||
485 | break; | ||
486 | case 88041: | ||
487 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
488 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ | ||
489 | break; | ||
490 | case 88061: | ||
491 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
492 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */ | ||
493 | break; | ||
494 | case 89519: | ||
495 | case 89609: | ||
496 | /* WinTV-HVR2200 (PCIe, Retail, full-height) | ||
497 | * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ | ||
498 | break; | ||
499 | case 89619: | ||
500 | /* WinTV-HVR2200 (PCIe, Retail, half-height) | ||
501 | * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ | ||
502 | break; | ||
503 | default: | ||
504 | printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n", | ||
505 | dev->name, tv.model); | ||
506 | break; | ||
507 | } | ||
508 | |||
509 | printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name, | ||
510 | tv.model); | ||
511 | } | ||
512 | |||
513 | void saa7164_card_setup(struct saa7164_dev *dev) | ||
514 | { | ||
515 | static u8 eeprom[256]; | ||
516 | |||
517 | if (dev->i2c_bus[0].i2c_rc == 0) { | ||
518 | if (saa7164_api_read_eeprom(dev, &eeprom[0], | ||
519 | sizeof(eeprom)) < 0) | ||
520 | return; | ||
521 | } | ||
522 | |||
523 | switch (dev->board) { | ||
524 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: | ||
525 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: | ||
526 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: | ||
527 | case SAA7164_BOARD_HAUPPAUGE_HVR2250: | ||
528 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: | ||
529 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: | ||
530 | hauppauge_eeprom(dev, &eeprom[0]); | ||
531 | break; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | /* With most other drivers, the kernel expects to communicate with subdrivers | ||
536 | * through i2c. This bridge does not allow that, it does not expose any direct | ||
537 | * access to I2C. Instead we have to communicate through the device f/w for | ||
538 | * register access to 'processing units'. Each unit has a unique | ||
539 | * id, regardless of how the physical implementation occurs across | ||
540 | * the three physical i2c busses. The being said if we want leverge of | ||
541 | * the existing kernel drivers for tuners and demods we have to 'speak i2c', | ||
542 | * to this bridge implements 3 virtual i2c buses. This is a helper function | ||
543 | * for those. | ||
544 | * | ||
545 | * Description: Translate the kernels notion of an i2c address and bus into | ||
546 | * the appropriate unitid. | ||
547 | */ | ||
548 | int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr) | ||
549 | { | ||
550 | /* For a given bus and i2c device address, return the saa7164 unique | ||
551 | * unitid. < 0 on error */ | ||
552 | |||
553 | struct saa7164_dev *dev = bus->dev; | ||
554 | struct saa7164_unit *unit; | ||
555 | int i; | ||
556 | |||
557 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
558 | unit = &saa7164_boards[dev->board].unit[i]; | ||
559 | |||
560 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
561 | continue; | ||
562 | if ((bus->nr == unit->i2c_bus_nr) && | ||
563 | (addr == unit->i2c_bus_addr)) | ||
564 | return unit->id; | ||
565 | } | ||
566 | |||
567 | return -1; | ||
568 | } | ||
569 | |||
570 | /* The 7164 API needs to know the i2c register length in advance. | ||
571 | * this is a helper function. Based on a specific chip addr and bus return the | ||
572 | * reg length. | ||
573 | */ | ||
574 | int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr) | ||
575 | { | ||
576 | /* For a given bus and i2c device address, return the | ||
577 | * saa7164 registry address width. < 0 on error | ||
578 | */ | ||
579 | |||
580 | struct saa7164_dev *dev = bus->dev; | ||
581 | struct saa7164_unit *unit; | ||
582 | int i; | ||
583 | |||
584 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
585 | unit = &saa7164_boards[dev->board].unit[i]; | ||
586 | |||
587 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
588 | continue; | ||
589 | |||
590 | if ((bus->nr == unit->i2c_bus_nr) && | ||
591 | (addr == unit->i2c_bus_addr)) | ||
592 | return unit->i2c_reg_len; | ||
593 | } | ||
594 | |||
595 | return -1; | ||
596 | } | ||
597 | /* TODO: implement a 'findeeprom' functio like the above and fix any other | ||
598 | * eeprom related todo's in -api.c. | ||
599 | */ | ||
600 | |||
601 | /* Translate a unitid into a x readable device name, for display purposes. */ | ||
602 | char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid) | ||
603 | { | ||
604 | char *undefed = "UNDEFINED"; | ||
605 | char *bridge = "BRIDGE"; | ||
606 | struct saa7164_unit *unit; | ||
607 | int i; | ||
608 | |||
609 | if (unitid == 0) | ||
610 | return bridge; | ||
611 | |||
612 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
613 | unit = &saa7164_boards[dev->board].unit[i]; | ||
614 | |||
615 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
616 | continue; | ||
617 | |||
618 | if (unitid == unit->id) | ||
619 | return unit->name; | ||
620 | } | ||
621 | |||
622 | return undefed; | ||
623 | } | ||
624 | |||