Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / pci / saa7164 / saa7164-cards.c
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                 .porte          = SAA7164_MPEG_VBI,
273                 .portf          = SAA7164_MPEG_VBI,
274                 .chiprev        = SAA7164_CHIP_REV3,
275                 .unit           = {{
276                         .id             = 0x22,
277                         .type           = SAA7164_UNIT_EEPROM,
278                         .name           = "4K EEPROM",
279                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
280                         .i2c_bus_addr   = 0xa0 >> 1,
281                         .i2c_reg_len    = REGLEN_8bit,
282                 }, {
283                         .id             = 0x04,
284                         .type           = SAA7164_UNIT_TUNER,
285                         .name           = "TDA18271-1",
286                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
287                         .i2c_bus_addr   = 0xc0 >> 1,
288                         .i2c_reg_len    = REGLEN_8bit,
289                 }, {
290                         .id             = 0x07,
291                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
292                         .name           = "CX24228/S5H1411-1 (TOP)",
293                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
294                         .i2c_bus_addr   = 0x32 >> 1,
295                         .i2c_reg_len    = REGLEN_8bit,
296                 }, {
297                         .id             = 0x08,
298                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
299                         .name           = "CX24228/S5H1411-1 (QAM)",
300                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
301                         .i2c_bus_addr   = 0x34 >> 1,
302                         .i2c_reg_len    = REGLEN_8bit,
303                 }, {
304                         .id             = 0x1e,
305                         .type           = SAA7164_UNIT_TUNER,
306                         .name           = "TDA18271-2",
307                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
308                         .i2c_bus_addr   = 0xc0 >> 1,
309                         .i2c_reg_len    = REGLEN_8bit,
310                 }, {
311                         .id             = 0x20,
312                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
313                         .name           = "CX24228/S5H1411-2 (TOP)",
314                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
315                         .i2c_bus_addr   = 0x32 >> 1,
316                         .i2c_reg_len    = REGLEN_8bit,
317                 }, {
318                         .id             = 0x23,
319                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
320                         .name           = "CX24228/S5H1411-2 (QAM)",
321                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
322                         .i2c_bus_addr   = 0x34 >> 1,
323                         .i2c_reg_len    = REGLEN_8bit,
324                 } },
325         },
326         [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
327                 .name           = "Hauppauge WinTV-HVR2250",
328                 .porta          = SAA7164_MPEG_DVB,
329                 .portb          = SAA7164_MPEG_DVB,
330                 .portc          = SAA7164_MPEG_ENCODER,
331                 .portd          = SAA7164_MPEG_ENCODER,
332                 .porte          = SAA7164_MPEG_VBI,
333                 .portf          = SAA7164_MPEG_VBI,
334                 .chiprev        = SAA7164_CHIP_REV3,
335                 .unit           = {{
336                         .id             = 0x28,
337                         .type           = SAA7164_UNIT_EEPROM,
338                         .name           = "4K EEPROM",
339                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
340                         .i2c_bus_addr   = 0xa0 >> 1,
341                         .i2c_reg_len    = REGLEN_8bit,
342                 }, {
343                         .id             = 0x04,
344                         .type           = SAA7164_UNIT_TUNER,
345                         .name           = "TDA18271-1",
346                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
347                         .i2c_bus_addr   = 0xc0 >> 1,
348                         .i2c_reg_len    = REGLEN_8bit,
349                 }, {
350                         .id             = 0x07,
351                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
352                         .name           = "CX24228/S5H1411-1 (TOP)",
353                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
354                         .i2c_bus_addr   = 0x32 >> 1,
355                         .i2c_reg_len    = REGLEN_8bit,
356                 }, {
357                         .id             = 0x08,
358                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
359                         .name           = "CX24228/S5H1411-1 (QAM)",
360                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
361                         .i2c_bus_addr   = 0x34 >> 1,
362                         .i2c_reg_len    = REGLEN_8bit,
363                 }, {
364                         .id             = 0x24,
365                         .type           = SAA7164_UNIT_TUNER,
366                         .name           = "TDA18271-2",
367                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
368                         .i2c_bus_addr   = 0xc0 >> 1,
369                         .i2c_reg_len    = REGLEN_8bit,
370                 }, {
371                         .id             = 0x26,
372                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
373                         .name           = "CX24228/S5H1411-2 (TOP)",
374                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
375                         .i2c_bus_addr   = 0x32 >> 1,
376                         .i2c_reg_len    = REGLEN_8bit,
377                 }, {
378                         .id             = 0x29,
379                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
380                         .name           = "CX24228/S5H1411-2 (QAM)",
381                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
382                         .i2c_bus_addr   = 0x34 >> 1,
383                         .i2c_reg_len    = REGLEN_8bit,
384                 } },
385         },
386         [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
387                 .name           = "Hauppauge WinTV-HVR2250",
388                 .porta          = SAA7164_MPEG_DVB,
389                 .portb          = SAA7164_MPEG_DVB,
390                 .portc          = SAA7164_MPEG_ENCODER,
391                 .portd          = SAA7164_MPEG_ENCODER,
392                 .porte          = SAA7164_MPEG_VBI,
393                 .portf          = SAA7164_MPEG_VBI,
394                 .chiprev        = SAA7164_CHIP_REV3,
395                 .unit           = {{
396                         .id             = 0x26,
397                         .type           = SAA7164_UNIT_EEPROM,
398                         .name           = "4K EEPROM",
399                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
400                         .i2c_bus_addr   = 0xa0 >> 1,
401                         .i2c_reg_len    = REGLEN_8bit,
402                 }, {
403                         .id             = 0x04,
404                         .type           = SAA7164_UNIT_TUNER,
405                         .name           = "TDA18271-1",
406                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
407                         .i2c_bus_addr   = 0xc0 >> 1,
408                         .i2c_reg_len    = REGLEN_8bit,
409                 }, {
410                         .id             = 0x07,
411                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
412                         .name           = "CX24228/S5H1411-1 (TOP)",
413                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
414                         .i2c_bus_addr   = 0x32 >> 1,
415                         .i2c_reg_len    = REGLEN_8bit,
416                 }, {
417                         .id             = 0x08,
418                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
419                         .name           = "CX24228/S5H1411-1 (QAM)",
420                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
421                         .i2c_bus_addr   = 0x34 >> 1,
422                         .i2c_reg_len    = REGLEN_8bit,
423                 }, {
424                         .id             = 0x22,
425                         .type           = SAA7164_UNIT_TUNER,
426                         .name           = "TDA18271-2",
427                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
428                         .i2c_bus_addr   = 0xc0 >> 1,
429                         .i2c_reg_len    = REGLEN_8bit,
430                 }, {
431                         .id             = 0x24,
432                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
433                         .name           = "CX24228/S5H1411-2 (TOP)",
434                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
435                         .i2c_bus_addr   = 0x32 >> 1,
436                         .i2c_reg_len    = REGLEN_8bit,
437                 }, {
438                         .id             = 0x27,
439                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
440                         .name           = "CX24228/S5H1411-2 (QAM)",
441                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
442                         .i2c_bus_addr   = 0x34 >> 1,
443                         .i2c_reg_len    = REGLEN_8bit,
444                 } },
445         },
446         [SAA7164_BOARD_HAUPPAUGE_HVR2200_5] = {
447                 .name           = "Hauppauge WinTV-HVR2200",
448                 .porta          = SAA7164_MPEG_DVB,
449                 .portb          = SAA7164_MPEG_DVB,
450                 .chiprev        = SAA7164_CHIP_REV3,
451                 .unit           = {{
452                         .id             = 0x23,
453                         .type           = SAA7164_UNIT_EEPROM,
454                         .name           = "4K EEPROM",
455                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
456                         .i2c_bus_addr   = 0xa0 >> 1,
457                         .i2c_reg_len    = REGLEN_8bit,
458                 }, {
459                         .id             = 0x04,
460                         .type           = SAA7164_UNIT_TUNER,
461                         .name           = "TDA18271-1",
462                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
463                         .i2c_bus_addr   = 0xc0 >> 1,
464                         .i2c_reg_len    = REGLEN_8bit,
465                 }, {
466                         .id             = 0x05,
467                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
468                         .name           = "TDA8290-1",
469                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
470                         .i2c_bus_addr   = 0x84 >> 1,
471                         .i2c_reg_len    = REGLEN_8bit,
472                 }, {
473                         .id             = 0x21,
474                         .type           = SAA7164_UNIT_TUNER,
475                         .name           = "TDA18271-2",
476                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
477                         .i2c_bus_addr   = 0xc0 >> 1,
478                         .i2c_reg_len    = REGLEN_8bit,
479                 }, {
480                         .id             = 0x22,
481                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
482                         .name           = "TDA8290-2",
483                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
484                         .i2c_bus_addr   = 0x84 >> 1,
485                         .i2c_reg_len    = REGLEN_8bit,
486                 }, {
487                         .id             = 0x24,
488                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
489                         .name           = "TDA10048-1",
490                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
491                         .i2c_bus_addr   = 0x10 >> 1,
492                         .i2c_reg_len    = REGLEN_8bit,
493                 }, {
494                         .id             = 0x25,
495                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
496                         .name           = "TDA10048-2",
497                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
498                         .i2c_bus_addr   = 0x12 >> 1,
499                         .i2c_reg_len    = REGLEN_8bit,
500                 } },
501         },
502 };
503 const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
504
505 /* ------------------------------------------------------------------ */
506 /* PCI subsystem IDs                                                  */
507
508 struct saa7164_subid saa7164_subids[] = {
509         {
510                 .subvendor = 0x0070,
511                 .subdevice = 0x8880,
512                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
513         }, {
514                 .subvendor = 0x0070,
515                 .subdevice = 0x8810,
516                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
517         }, {
518                 .subvendor = 0x0070,
519                 .subdevice = 0x8980,
520                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200,
521         }, {
522                 .subvendor = 0x0070,
523                 .subdevice = 0x8900,
524                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
525         }, {
526                 .subvendor = 0x0070,
527                 .subdevice = 0x8901,
528                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
529         }, {
530                 .subvendor = 0x0070,
531                 .subdevice = 0x88A1,
532                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
533         }, {
534                 .subvendor = 0x0070,
535                 .subdevice = 0x8891,
536                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
537         }, {
538                 .subvendor = 0x0070,
539                 .subdevice = 0x8851,
540                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
541         }, {
542                 .subvendor = 0x0070,
543                 .subdevice = 0x8940,
544                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
545         }, {
546                 .subvendor = 0x0070,
547                 .subdevice = 0x8953,
548                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
549         },
550 };
551 const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
552
553 void saa7164_card_list(struct saa7164_dev *dev)
554 {
555         int i;
556
557         if (0 == dev->pci->subsystem_vendor &&
558             0 == dev->pci->subsystem_device) {
559                 printk(KERN_ERR
560                         "%s: Board has no valid PCIe Subsystem ID and can't\n"
561                         "%s: be autodetected. Pass card=<n> insmod option to\n"
562                         "%s: workaround that. Send complaints to the vendor\n"
563                         "%s: of the TV card. Best regards,\n"
564                         "%s:         -- tux\n",
565                         dev->name, dev->name, dev->name, dev->name, dev->name);
566         } else {
567                 printk(KERN_ERR
568                         "%s: Your board isn't known (yet) to the driver.\n"
569                         "%s: Try to pick one of the existing card configs via\n"
570                         "%s: card=<n> insmod option.  Updating to the latest\n"
571                         "%s: version might help as well.\n",
572                         dev->name, dev->name, dev->name, dev->name);
573         }
574
575         printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
576                 "option:\n", dev->name);
577
578         for (i = 0; i < saa7164_bcount; i++)
579                 printk(KERN_ERR "%s:    card=%d -> %s\n",
580                        dev->name, i, saa7164_boards[i].name);
581 }
582
583 /* TODO: clean this define up into the -cards.c structs */
584 #define PCIEBRIDGE_UNITID 2
585
586 void saa7164_gpio_setup(struct saa7164_dev *dev)
587 {
588         switch (dev->board) {
589         case SAA7164_BOARD_HAUPPAUGE_HVR2200:
590         case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
591         case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
592         case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
593         case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
594         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
595         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
596         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
597                 /*
598                 GPIO 2: s5h1411 / tda10048-1 demod reset
599                 GPIO 3: s5h1411 / tda10048-2 demod reset
600                 GPIO 7: IRBlaster Zilog reset
601                  */
602
603                 /* Reset parts by going in and out of reset */
604                 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
605                 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
606
607                 msleep(20);
608
609                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
610                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
611                 break;
612         }
613 }
614
615 static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
616 {
617         struct tveeprom tv;
618
619         /* TODO: Assumption: eeprom on bus 0 */
620         tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
621                 eeprom_data);
622
623         /* Make sure we support the board model */
624         switch (tv.model) {
625         case 88001:
626                 /* Development board - Limit circulation */
627                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
628                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
629         case 88021:
630                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
631                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
632                 break;
633         case 88041:
634                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
635                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
636                 break;
637         case 88061:
638                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
639                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
640                 break;
641         case 89519:
642         case 89609:
643                 /* WinTV-HVR2200 (PCIe, Retail, full-height)
644                  * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
645                 break;
646         case 89619:
647                 /* WinTV-HVR2200 (PCIe, Retail, half-height)
648                  * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
649                 break;
650         default:
651                 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
652                         dev->name, tv.model);
653                 break;
654         }
655
656         printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
657                 tv.model);
658 }
659
660 void saa7164_card_setup(struct saa7164_dev *dev)
661 {
662         static u8 eeprom[256];
663
664         if (dev->i2c_bus[0].i2c_rc == 0) {
665                 if (saa7164_api_read_eeprom(dev, &eeprom[0],
666                         sizeof(eeprom)) < 0)
667                         return;
668         }
669
670         switch (dev->board) {
671         case SAA7164_BOARD_HAUPPAUGE_HVR2200:
672         case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
673         case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
674         case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
675         case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
676         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
677         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
678         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
679                 hauppauge_eeprom(dev, &eeprom[0]);
680                 break;
681         }
682 }
683
684 /* With most other drivers, the kernel expects to communicate with subdrivers
685  * through i2c. This bridge does not allow that, it does not expose any direct
686  * access to I2C. Instead we have to communicate through the device f/w for
687  * register access to 'processing units'. Each unit has a unique
688  * id, regardless of how the physical implementation occurs across
689  * the three physical i2c busses. The being said if we want leverge of
690  * the existing kernel drivers for tuners and demods we have to 'speak i2c',
691  * to this bridge implements 3 virtual i2c buses. This is a helper function
692  * for those.
693  *
694  * Description: Translate the kernels notion of an i2c address and bus into
695  * the appropriate unitid.
696  */
697 int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
698 {
699         /* For a given bus and i2c device address, return the saa7164 unique
700          * unitid. < 0 on error */
701
702         struct saa7164_dev *dev = bus->dev;
703         struct saa7164_unit *unit;
704         int i;
705
706         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
707                 unit = &saa7164_boards[dev->board].unit[i];
708
709                 if (unit->type == SAA7164_UNIT_UNDEFINED)
710                         continue;
711                 if ((bus->nr == unit->i2c_bus_nr) &&
712                         (addr == unit->i2c_bus_addr))
713                         return unit->id;
714         }
715
716         return -1;
717 }
718
719 /* The 7164 API needs to know the i2c register length in advance.
720  * this is a helper function. Based on a specific chip addr and bus return the
721  * reg length.
722  */
723 int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
724 {
725         /* For a given bus and i2c device address, return the
726          * saa7164 registry address width. < 0 on error
727          */
728
729         struct saa7164_dev *dev = bus->dev;
730         struct saa7164_unit *unit;
731         int i;
732
733         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
734                 unit = &saa7164_boards[dev->board].unit[i];
735
736                 if (unit->type == SAA7164_UNIT_UNDEFINED)
737                         continue;
738
739                 if ((bus->nr == unit->i2c_bus_nr) &&
740                         (addr == unit->i2c_bus_addr))
741                         return unit->i2c_reg_len;
742         }
743
744         return -1;
745 }
746 /* TODO: implement a 'findeeprom' functio like the above and fix any other
747  * eeprom related todo's in -api.c.
748  */
749
750 /* Translate a unitid into a x readable device name, for display purposes.  */
751 char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
752 {
753         char *undefed = "UNDEFINED";
754         char *bridge = "BRIDGE";
755         struct saa7164_unit *unit;
756         int i;
757
758         if (unitid == 0)
759                 return bridge;
760
761         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
762                 unit = &saa7164_boards[dev->board].unit[i];
763
764                 if (unit->type == SAA7164_UNIT_UNDEFINED)
765                         continue;
766
767                 if (unitid == unit->id)
768                                 return unit->name;
769         }
770
771         return undefed;
772 }
773