diff options
author | Steven Toth <stoth@kernellabs.com> | 2009-05-09 20:17:28 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-18 23:14:43 -0400 |
commit | 443c1228d50518f3c550e1fef490a2c9d9246ce7 (patch) | |
tree | cde68674e62a75b616906edcea835b2ea8b19588 /drivers/media/video/saa7164/saa7164-cards.c | |
parent | 9afef394308cf63ddb67b003a1c6036615456eb9 (diff) |
V4L/DVB (12923): SAA7164: Add support for the NXP SAA7164 silicon
This patch adds support for all of the known shipping Hauppauge HVR-2200
and HVR-2250 boards. Digital TV ATSC/QAM and DVB-T is enabled at this
time. Both tuners are supported.
Volatiles and typedefs need rework, the rest is coding style compliant.
Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7164/saa7164-cards.c')
-rw-r--r-- | drivers/media/video/saa7164/saa7164-cards.c | 562 |
1 files changed, 562 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..0678b5f31bdd --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-cards.c | |||
@@ -0,0 +1,562 @@ | |||
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 = 0x06, | ||
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 = 0x06, | ||
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 = 0x22, | ||
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 | }; | ||
307 | const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards); | ||
308 | |||
309 | /* ------------------------------------------------------------------ */ | ||
310 | /* PCI subsystem IDs */ | ||
311 | |||
312 | struct saa7164_subid saa7164_subids[] = { | ||
313 | { | ||
314 | .subvendor = 0x0070, | ||
315 | .subdevice = 0x8880, | ||
316 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, | ||
317 | }, { | ||
318 | .subvendor = 0x0070, | ||
319 | .subdevice = 0x8810, | ||
320 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250, | ||
321 | }, { | ||
322 | .subvendor = 0x0070, | ||
323 | .subdevice = 0x8980, | ||
324 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200, | ||
325 | }, { | ||
326 | .subvendor = 0x0070, | ||
327 | .subdevice = 0x8900, | ||
328 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2, | ||
329 | }, { | ||
330 | .subvendor = 0x0070, | ||
331 | .subdevice = 0x8901, | ||
332 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3, | ||
333 | }, { | ||
334 | .subvendor = 0x0070, | ||
335 | .subdevice = 0x88A1, | ||
336 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, | ||
337 | }, { | ||
338 | .subvendor = 0x0070, | ||
339 | .subdevice = 0x8891, | ||
340 | .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2, | ||
341 | }, | ||
342 | }; | ||
343 | const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids); | ||
344 | |||
345 | void saa7164_card_list(struct saa7164_dev *dev) | ||
346 | { | ||
347 | int i; | ||
348 | |||
349 | if (0 == dev->pci->subsystem_vendor && | ||
350 | 0 == dev->pci->subsystem_device) { | ||
351 | printk(KERN_ERR | ||
352 | "%s: Board has no valid PCIe Subsystem ID and can't\n" | ||
353 | "%s: be autodetected. Pass card=<n> insmod option to\n" | ||
354 | "%s: workaround that. Send complaints to the vendor\n" | ||
355 | "%s: of the TV card. Best regards,\n" | ||
356 | "%s: -- tux\n", | ||
357 | dev->name, dev->name, dev->name, dev->name, dev->name); | ||
358 | } else { | ||
359 | printk(KERN_ERR | ||
360 | "%s: Your board isn't known (yet) to the driver.\n" | ||
361 | "%s: Try to pick one of the existing card configs via\n" | ||
362 | "%s: card=<n> insmod option. Updating to the latest\n" | ||
363 | "%s: version might help as well.\n", | ||
364 | dev->name, dev->name, dev->name, dev->name); | ||
365 | } | ||
366 | |||
367 | printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod " | ||
368 | "option:\n", dev->name); | ||
369 | |||
370 | for (i = 0; i < saa7164_bcount; i++) | ||
371 | printk(KERN_ERR "%s: card=%d -> %s\n", | ||
372 | dev->name, i, saa7164_boards[i].name); | ||
373 | } | ||
374 | |||
375 | /* TODO: clean this define up into the -cards.c structs */ | ||
376 | #define PCIEBRIDGE_UNITID 2 | ||
377 | |||
378 | void saa7164_gpio_setup(struct saa7164_dev *dev) | ||
379 | { | ||
380 | |||
381 | |||
382 | switch (dev->board) { | ||
383 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: | ||
384 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: | ||
385 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: | ||
386 | case SAA7164_BOARD_HAUPPAUGE_HVR2250: | ||
387 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: | ||
388 | /* | ||
389 | GPIO 2: s5h1411 / tda10048-1 demod reset | ||
390 | GPIO 3: s5h1411 / tda10048-2 demod reset | ||
391 | GPIO 7: IRBlaster Zilog reset | ||
392 | */ | ||
393 | |||
394 | /* Reset parts by going in and out of reset */ | ||
395 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | ||
396 | saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | ||
397 | |||
398 | msleep(10); | ||
399 | |||
400 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2); | ||
401 | saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3); | ||
402 | break; | ||
403 | } | ||
404 | |||
405 | } | ||
406 | |||
407 | static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data) | ||
408 | { | ||
409 | struct tveeprom tv; | ||
410 | |||
411 | /* TODO: Assumption: eeprom on bus 0 */ | ||
412 | tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, | ||
413 | eeprom_data); | ||
414 | |||
415 | /* Make sure we support the board model */ | ||
416 | switch (tv.model) { | ||
417 | case 88001: | ||
418 | /* Development board - Limit circulation */ | ||
419 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
420 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ | ||
421 | case 88021: | ||
422 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
423 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */ | ||
424 | break; | ||
425 | case 88041: | ||
426 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
427 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */ | ||
428 | break; | ||
429 | case 88061: | ||
430 | /* WinTV-HVR2250 (PCIe, Retail, full-height bracket) | ||
431 | * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */ | ||
432 | break; | ||
433 | case 89519: | ||
434 | case 89609: | ||
435 | /* WinTV-HVR2200 (PCIe, Retail, full-height) | ||
436 | * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ | ||
437 | break; | ||
438 | case 89619: | ||
439 | /* WinTV-HVR2200 (PCIe, Retail, half-height) | ||
440 | * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ | ||
441 | break; | ||
442 | default: | ||
443 | printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n", | ||
444 | dev->name, tv.model); | ||
445 | break; | ||
446 | } | ||
447 | |||
448 | printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name, | ||
449 | tv.model); | ||
450 | } | ||
451 | |||
452 | void saa7164_card_setup(struct saa7164_dev *dev) | ||
453 | { | ||
454 | static u8 eeprom[256]; | ||
455 | |||
456 | if (dev->i2c_bus[0].i2c_rc == 0) { | ||
457 | if (saa7164_api_read_eeprom(dev, &eeprom[0], | ||
458 | sizeof(eeprom)) < 0) | ||
459 | return; | ||
460 | } | ||
461 | |||
462 | switch (dev->board) { | ||
463 | case SAA7164_BOARD_HAUPPAUGE_HVR2200: | ||
464 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: | ||
465 | case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: | ||
466 | case SAA7164_BOARD_HAUPPAUGE_HVR2250: | ||
467 | case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: | ||
468 | hauppauge_eeprom(dev, &eeprom[0]); | ||
469 | break; | ||
470 | } | ||
471 | } | ||
472 | |||
473 | /* With most other drivers, the kernel expects to communicate with subdrivers | ||
474 | * through i2c. This bridge does not allow that, it does not expose any direct | ||
475 | * access to I2C. Instead we have to communicate through the device f/w for | ||
476 | * register access to 'processing units'. Each unit has a unique | ||
477 | * id, regardless of how the physical implementation occurs across | ||
478 | * the three physical i2c busses. The being said if we want leverge of | ||
479 | * the existing kernel drivers for tuners and demods we have to 'speak i2c', | ||
480 | * to this bridge implements 3 virtual i2c buses. This is a helper function | ||
481 | * for those. | ||
482 | * | ||
483 | * Description: Translate the kernels notion of an i2c address and bus into | ||
484 | * the appropriate unitid. | ||
485 | */ | ||
486 | int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr) | ||
487 | { | ||
488 | /* For a given bus and i2c device address, return the saa7164 unique | ||
489 | * unitid. < 0 on error */ | ||
490 | |||
491 | struct saa7164_dev *dev = bus->dev; | ||
492 | struct saa7164_unit *unit; | ||
493 | int i; | ||
494 | |||
495 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
496 | unit = &saa7164_boards[dev->board].unit[i]; | ||
497 | |||
498 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
499 | continue; | ||
500 | if ((bus->nr == unit->i2c_bus_nr) && | ||
501 | (addr == unit->i2c_bus_addr)) | ||
502 | return unit->id; | ||
503 | } | ||
504 | |||
505 | return -1; | ||
506 | } | ||
507 | |||
508 | /* The 7164 API needs to know the i2c register length in advance. | ||
509 | * this is a helper function. Based on a specific chip addr and bus return the | ||
510 | * reg length. | ||
511 | */ | ||
512 | int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr) | ||
513 | { | ||
514 | /* For a given bus and i2c device address, return the | ||
515 | * saa7164 registry address width. < 0 on error | ||
516 | */ | ||
517 | |||
518 | struct saa7164_dev *dev = bus->dev; | ||
519 | struct saa7164_unit *unit; | ||
520 | int i; | ||
521 | |||
522 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
523 | unit = &saa7164_boards[dev->board].unit[i]; | ||
524 | |||
525 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
526 | continue; | ||
527 | |||
528 | if ((bus->nr == unit->i2c_bus_nr) && | ||
529 | (addr == unit->i2c_bus_addr)) | ||
530 | return unit->i2c_reg_len; | ||
531 | } | ||
532 | |||
533 | return -1; | ||
534 | } | ||
535 | /* TODO: implement a 'findeeprom' functio like the above and fix any other | ||
536 | * eeprom related todo's in -api.c. | ||
537 | */ | ||
538 | |||
539 | /* Translate a unitid into a x readable device name, for display purposes. */ | ||
540 | char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid) | ||
541 | { | ||
542 | char *undefed = "UNDEFINED"; | ||
543 | char *bridge = "BRIDGE"; | ||
544 | struct saa7164_unit *unit; | ||
545 | int i; | ||
546 | |||
547 | if (unitid == 0) | ||
548 | return bridge; | ||
549 | |||
550 | for (i = 0; i < SAA7164_MAX_UNITS; i++) { | ||
551 | unit = &saa7164_boards[dev->board].unit[i]; | ||
552 | |||
553 | if (unit->type == SAA7164_UNIT_UNDEFINED) | ||
554 | continue; | ||
555 | |||
556 | if (unitid == unit->id) | ||
557 | return unit->name; | ||
558 | } | ||
559 | |||
560 | return undefed; | ||
561 | } | ||
562 | |||