blob: 971591d6450fccc5a7164adb94cb40e3404fb635 [file] [log] [blame]
Steven Toth443c12282009-05-09 21:17:28 -03001/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
Steven Toth9b8b0192010-07-31 14:39:44 -03004 * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
Steven Toth443c12282009-05-09 21:17:28 -03005 *
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
36struct 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,
Steven Toth7615e432010-07-31 14:44:53 -030058 .portc = SAA7164_MPEG_ENCODER,
59 .portd = SAA7164_MPEG_ENCODER,
Steven Tothe8ce2f22010-07-31 16:06:06 -030060 .porte = SAA7164_MPEG_VBI,
61 .portf = SAA7164_MPEG_VBI,
Steven Toth443c12282009-05-09 21:17:28 -030062 .chiprev = SAA7164_CHIP_REV3,
63 .unit = {{
Steven Toth30015c12009-05-14 01:15:15 -030064 .id = 0x1d,
Steven Toth443c12282009-05-09 21:17:28 -030065 .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,
Steven Toth7615e432010-07-31 14:44:53 -0300104 .portc = SAA7164_MPEG_ENCODER,
105 .portd = SAA7164_MPEG_ENCODER,
Steven Tothe8ce2f22010-07-31 16:06:06 -0300106 .porte = SAA7164_MPEG_VBI,
107 .portf = SAA7164_MPEG_VBI,
Steven Toth443c12282009-05-09 21:17:28 -0300108 .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,
Steven Toth7615e432010-07-31 14:44:53 -0300150 .portc = SAA7164_MPEG_ENCODER,
151 .portd = SAA7164_MPEG_ENCODER,
Steven Tothe8ce2f22010-07-31 16:06:06 -0300152 .porte = SAA7164_MPEG_VBI,
153 .portf = SAA7164_MPEG_VBI,
Steven Toth443c12282009-05-09 21:17:28 -0300154 .chiprev = SAA7164_CHIP_REV2,
155 .unit = {{
Steven Toth30015c12009-05-14 01:15:15 -0300156 .id = 0x1d,
Steven Toth443c12282009-05-09 21:17:28 -0300157 .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 },
Tony Jago62dd28d2011-08-12 00:19:11 -0300206 [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 },
Steven Toth443c12282009-05-09 21:17:28 -0300266 [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
267 .name = "Hauppauge WinTV-HVR2250",
268 .porta = SAA7164_MPEG_DVB,
269 .portb = SAA7164_MPEG_DVB,
Steven Toth7615e432010-07-31 14:44:53 -0300270 .portc = SAA7164_MPEG_ENCODER,
271 .portd = SAA7164_MPEG_ENCODER,
272 .portc = SAA7164_MPEG_ENCODER,
273 .portd = SAA7164_MPEG_ENCODER,
Steven Tothe8ce2f22010-07-31 16:06:06 -0300274 .porte = SAA7164_MPEG_VBI,
275 .portf = SAA7164_MPEG_VBI,
Steven Toth443c12282009-05-09 21:17:28 -0300276 .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,
Steven Toth7615e432010-07-31 14:44:53 -0300332 .portc = SAA7164_MPEG_ENCODER,
333 .portd = SAA7164_MPEG_ENCODER,
Steven Tothe8ce2f22010-07-31 16:06:06 -0300334 .porte = SAA7164_MPEG_VBI,
335 .portf = SAA7164_MPEG_VBI,
336 .porte = SAA7164_MPEG_VBI,
337 .portf = SAA7164_MPEG_VBI,
Steven Toth443c12282009-05-09 21:17:28 -0300338 .chiprev = SAA7164_CHIP_REV3,
339 .unit = {{
Steven Toth30015c12009-05-14 01:15:15 -0300340 .id = 0x28,
Steven Toth443c12282009-05-09 21:17:28 -0300341 .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 },
Steven Tothe3335222009-05-11 22:03:07 -0300390 [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
391 .name = "Hauppauge WinTV-HVR2250",
392 .porta = SAA7164_MPEG_DVB,
393 .portb = SAA7164_MPEG_DVB,
Steven Toth7615e432010-07-31 14:44:53 -0300394 .portc = SAA7164_MPEG_ENCODER,
395 .portd = SAA7164_MPEG_ENCODER,
Steven Tothe8ce2f22010-07-31 16:06:06 -0300396 .porte = SAA7164_MPEG_VBI,
397 .portf = SAA7164_MPEG_VBI,
Steven Tothe3335222009-05-11 22:03:07 -0300398 .chiprev = SAA7164_CHIP_REV3,
399 .unit = {{
Steven Toth30015c12009-05-14 01:15:15 -0300400 .id = 0x26,
Steven Tothe3335222009-05-11 22:03:07 -0300401 .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 },
Steven Tothde2fb692011-09-09 15:35:20 -0300450 [SAA7164_BOARD_HAUPPAUGE_HVR2200_5] = {
451 .name = "Hauppauge WinTV-HVR2200",
452 .porta = SAA7164_MPEG_DVB,
453 .portb = SAA7164_MPEG_DVB,
454 .chiprev = SAA7164_CHIP_REV3,
455 .unit = {{
456 .id = 0x23,
457 .type = SAA7164_UNIT_EEPROM,
458 .name = "4K EEPROM",
459 .i2c_bus_nr = SAA7164_I2C_BUS_0,
460 .i2c_bus_addr = 0xa0 >> 1,
461 .i2c_reg_len = REGLEN_8bit,
462 }, {
463 .id = 0x04,
464 .type = SAA7164_UNIT_TUNER,
465 .name = "TDA18271-1",
466 .i2c_bus_nr = SAA7164_I2C_BUS_1,
467 .i2c_bus_addr = 0xc0 >> 1,
468 .i2c_reg_len = REGLEN_8bit,
469 }, {
470 .id = 0x05,
471 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
472 .name = "TDA8290-1",
473 .i2c_bus_nr = SAA7164_I2C_BUS_1,
474 .i2c_bus_addr = 0x84 >> 1,
475 .i2c_reg_len = REGLEN_8bit,
476 }, {
477 .id = 0x21,
478 .type = SAA7164_UNIT_TUNER,
479 .name = "TDA18271-2",
480 .i2c_bus_nr = SAA7164_I2C_BUS_2,
481 .i2c_bus_addr = 0xc0 >> 1,
482 .i2c_reg_len = REGLEN_8bit,
483 }, {
484 .id = 0x22,
485 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
486 .name = "TDA8290-2",
487 .i2c_bus_nr = SAA7164_I2C_BUS_2,
488 .i2c_bus_addr = 0x84 >> 1,
489 .i2c_reg_len = REGLEN_8bit,
490 }, {
491 .id = 0x24,
492 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
493 .name = "TDA10048-1",
494 .i2c_bus_nr = SAA7164_I2C_BUS_1,
495 .i2c_bus_addr = 0x10 >> 1,
496 .i2c_reg_len = REGLEN_8bit,
497 }, {
498 .id = 0x25,
499 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
500 .name = "TDA10048-2",
501 .i2c_bus_nr = SAA7164_I2C_BUS_2,
502 .i2c_bus_addr = 0x12 >> 1,
503 .i2c_reg_len = REGLEN_8bit,
504 } },
505 },
Steven Toth443c12282009-05-09 21:17:28 -0300506};
507const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
508
509/* ------------------------------------------------------------------ */
510/* PCI subsystem IDs */
511
512struct saa7164_subid saa7164_subids[] = {
513 {
514 .subvendor = 0x0070,
515 .subdevice = 0x8880,
516 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
517 }, {
518 .subvendor = 0x0070,
519 .subdevice = 0x8810,
520 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
521 }, {
522 .subvendor = 0x0070,
523 .subdevice = 0x8980,
524 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200,
525 }, {
526 .subvendor = 0x0070,
527 .subdevice = 0x8900,
528 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
529 }, {
530 .subvendor = 0x0070,
531 .subdevice = 0x8901,
532 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
533 }, {
534 .subvendor = 0x0070,
535 .subdevice = 0x88A1,
Steven Tothe3335222009-05-11 22:03:07 -0300536 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
Steven Toth443c12282009-05-09 21:17:28 -0300537 }, {
538 .subvendor = 0x0070,
539 .subdevice = 0x8891,
540 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
Steven Toth3a360ce2009-09-03 23:46:16 -0300541 }, {
542 .subvendor = 0x0070,
543 .subdevice = 0x8851,
544 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
Tony Jago62dd28d2011-08-12 00:19:11 -0300545 }, {
546 .subvendor = 0x0070,
547 .subdevice = 0x8940,
548 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
Steven Tothde2fb692011-09-09 15:35:20 -0300549 }, {
550 .subvendor = 0x0070,
551 .subdevice = 0x8953,
552 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
Steven Toth443c12282009-05-09 21:17:28 -0300553 },
554};
555const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
556
557void saa7164_card_list(struct saa7164_dev *dev)
558{
559 int i;
560
561 if (0 == dev->pci->subsystem_vendor &&
562 0 == dev->pci->subsystem_device) {
563 printk(KERN_ERR
564 "%s: Board has no valid PCIe Subsystem ID and can't\n"
565 "%s: be autodetected. Pass card=<n> insmod option to\n"
566 "%s: workaround that. Send complaints to the vendor\n"
567 "%s: of the TV card. Best regards,\n"
568 "%s: -- tux\n",
569 dev->name, dev->name, dev->name, dev->name, dev->name);
570 } else {
571 printk(KERN_ERR
572 "%s: Your board isn't known (yet) to the driver.\n"
573 "%s: Try to pick one of the existing card configs via\n"
574 "%s: card=<n> insmod option. Updating to the latest\n"
575 "%s: version might help as well.\n",
576 dev->name, dev->name, dev->name, dev->name);
577 }
578
579 printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
580 "option:\n", dev->name);
581
582 for (i = 0; i < saa7164_bcount; i++)
583 printk(KERN_ERR "%s: card=%d -> %s\n",
584 dev->name, i, saa7164_boards[i].name);
585}
586
587/* TODO: clean this define up into the -cards.c structs */
588#define PCIEBRIDGE_UNITID 2
589
590void saa7164_gpio_setup(struct saa7164_dev *dev)
591{
Steven Toth443c12282009-05-09 21:17:28 -0300592 switch (dev->board) {
593 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
594 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
595 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
Tony Jago62dd28d2011-08-12 00:19:11 -0300596 case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
Steven Tothde2fb692011-09-09 15:35:20 -0300597 case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
Steven Toth443c12282009-05-09 21:17:28 -0300598 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
599 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
Steven Tothe3335222009-05-11 22:03:07 -0300600 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
Steven Toth443c12282009-05-09 21:17:28 -0300601 /*
602 GPIO 2: s5h1411 / tda10048-1 demod reset
603 GPIO 3: s5h1411 / tda10048-2 demod reset
604 GPIO 7: IRBlaster Zilog reset
605 */
606
607 /* Reset parts by going in and out of reset */
608 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
609 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
610
Steven Tothbc250682010-11-12 18:32:36 -0300611 msleep(20);
Steven Toth443c12282009-05-09 21:17:28 -0300612
613 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
614 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
615 break;
616 }
Steven Toth443c12282009-05-09 21:17:28 -0300617}
618
619static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
620{
621 struct tveeprom tv;
622
623 /* TODO: Assumption: eeprom on bus 0 */
624 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
625 eeprom_data);
626
627 /* Make sure we support the board model */
628 switch (tv.model) {
629 case 88001:
630 /* Development board - Limit circulation */
631 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
632 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
633 case 88021:
634 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
635 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
636 break;
637 case 88041:
638 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
639 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
640 break;
641 case 88061:
642 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
643 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
644 break;
645 case 89519:
646 case 89609:
647 /* WinTV-HVR2200 (PCIe, Retail, full-height)
648 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
649 break;
650 case 89619:
651 /* WinTV-HVR2200 (PCIe, Retail, half-height)
652 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
653 break;
654 default:
655 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
656 dev->name, tv.model);
657 break;
658 }
659
660 printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
661 tv.model);
662}
663
664void saa7164_card_setup(struct saa7164_dev *dev)
665{
666 static u8 eeprom[256];
667
668 if (dev->i2c_bus[0].i2c_rc == 0) {
669 if (saa7164_api_read_eeprom(dev, &eeprom[0],
670 sizeof(eeprom)) < 0)
671 return;
672 }
673
674 switch (dev->board) {
675 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
676 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
677 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
Tony Jago62dd28d2011-08-12 00:19:11 -0300678 case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
Steven Tothde2fb692011-09-09 15:35:20 -0300679 case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
Steven Toth443c12282009-05-09 21:17:28 -0300680 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
Steven Tothc303e3e2009-05-12 16:20:37 -0300681 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
Steven Tothe3335222009-05-11 22:03:07 -0300682 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
Steven Toth443c12282009-05-09 21:17:28 -0300683 hauppauge_eeprom(dev, &eeprom[0]);
684 break;
685 }
686}
687
688/* With most other drivers, the kernel expects to communicate with subdrivers
689 * through i2c. This bridge does not allow that, it does not expose any direct
690 * access to I2C. Instead we have to communicate through the device f/w for
691 * register access to 'processing units'. Each unit has a unique
692 * id, regardless of how the physical implementation occurs across
693 * the three physical i2c busses. The being said if we want leverge of
694 * the existing kernel drivers for tuners and demods we have to 'speak i2c',
695 * to this bridge implements 3 virtual i2c buses. This is a helper function
696 * for those.
697 *
698 * Description: Translate the kernels notion of an i2c address and bus into
699 * the appropriate unitid.
700 */
701int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
702{
703 /* For a given bus and i2c device address, return the saa7164 unique
704 * unitid. < 0 on error */
705
706 struct saa7164_dev *dev = bus->dev;
707 struct saa7164_unit *unit;
708 int i;
709
710 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
711 unit = &saa7164_boards[dev->board].unit[i];
712
713 if (unit->type == SAA7164_UNIT_UNDEFINED)
714 continue;
715 if ((bus->nr == unit->i2c_bus_nr) &&
716 (addr == unit->i2c_bus_addr))
717 return unit->id;
718 }
719
720 return -1;
721}
722
723/* The 7164 API needs to know the i2c register length in advance.
724 * this is a helper function. Based on a specific chip addr and bus return the
725 * reg length.
726 */
727int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
728{
729 /* For a given bus and i2c device address, return the
730 * saa7164 registry address width. < 0 on error
731 */
732
733 struct saa7164_dev *dev = bus->dev;
734 struct saa7164_unit *unit;
735 int i;
736
737 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
738 unit = &saa7164_boards[dev->board].unit[i];
739
740 if (unit->type == SAA7164_UNIT_UNDEFINED)
741 continue;
742
743 if ((bus->nr == unit->i2c_bus_nr) &&
744 (addr == unit->i2c_bus_addr))
745 return unit->i2c_reg_len;
746 }
747
748 return -1;
749}
750/* TODO: implement a 'findeeprom' functio like the above and fix any other
751 * eeprom related todo's in -api.c.
752 */
753
754/* Translate a unitid into a x readable device name, for display purposes. */
755char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
756{
757 char *undefed = "UNDEFINED";
758 char *bridge = "BRIDGE";
759 struct saa7164_unit *unit;
760 int i;
761
762 if (unitid == 0)
763 return bridge;
764
765 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
766 unit = &saa7164_boards[dev->board].unit[i];
767
768 if (unit->type == SAA7164_UNIT_UNDEFINED)
769 continue;
770
771 if (unitid == unit->id)
772 return unit->name;
773 }
774
775 return undefed;
776}
777