Merge tag 'jfs-5.2' of git://github.com/kleikamp/linux-shaggy
[sfrench/cifs-2.6.git] / drivers / media / pci / saa7164 / saa7164-cards.c
1 /*
2  *  Driver for the NXP SAA7164 PCIe bridge
3  *
4  *  Copyright (c) 2010-2015 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
18 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/pci.h>
21 #include <linux/delay.h>
22
23 #include "saa7164.h"
24
25 /* The Bridge API needs to understand register widths (in bytes) for the
26  * attached I2C devices, so we can simplify the virtual i2c mechansms
27  * and keep the -i2c.c implementation clean.
28  */
29 #define REGLEN_0bit     0
30 #define REGLEN_8bit     1
31 #define REGLEN_16bit    2
32
33 struct saa7164_board saa7164_boards[] = {
34         [SAA7164_BOARD_UNKNOWN] = {
35                 /* Bridge will not load any firmware, without knowing
36                  * the rev this would be fatal. */
37                 .name           = "Unknown",
38         },
39         [SAA7164_BOARD_UNKNOWN_REV2] = {
40                 /* Bridge will load the v2 f/w and dump descriptors */
41                 /* Required during new board bringup */
42                 .name           = "Generic Rev2",
43                 .chiprev        = SAA7164_CHIP_REV2,
44         },
45         [SAA7164_BOARD_UNKNOWN_REV3] = {
46                 /* Bridge will load the v2 f/w and dump descriptors */
47                 /* Required during new board bringup */
48                 .name           = "Generic Rev3",
49                 .chiprev        = SAA7164_CHIP_REV3,
50         },
51         [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
52                 .name           = "Hauppauge WinTV-HVR2200",
53                 .porta          = SAA7164_MPEG_DVB,
54                 .portb          = SAA7164_MPEG_DVB,
55                 .portc          = SAA7164_MPEG_ENCODER,
56                 .portd          = SAA7164_MPEG_ENCODER,
57                 .porte          = SAA7164_MPEG_VBI,
58                 .portf          = SAA7164_MPEG_VBI,
59                 .chiprev        = SAA7164_CHIP_REV3,
60                 .unit           = {{
61                         .id             = 0x1d,
62                         .type           = SAA7164_UNIT_EEPROM,
63                         .name           = "4K EEPROM",
64                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
65                         .i2c_bus_addr   = 0xa0 >> 1,
66                         .i2c_reg_len    = REGLEN_8bit,
67                 }, {
68                         .id             = 0x04,
69                         .type           = SAA7164_UNIT_TUNER,
70                         .name           = "TDA18271-1",
71                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
72                         .i2c_bus_addr   = 0xc0 >> 1,
73                         .i2c_reg_len    = REGLEN_8bit,
74                 }, {
75                         .id             = 0x1b,
76                         .type           = SAA7164_UNIT_TUNER,
77                         .name           = "TDA18271-2",
78                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
79                         .i2c_bus_addr   = 0xc0 >> 1,
80                         .i2c_reg_len    = REGLEN_8bit,
81                 }, {
82                         .id             = 0x1e,
83                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
84                         .name           = "TDA10048-1",
85                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
86                         .i2c_bus_addr   = 0x10 >> 1,
87                         .i2c_reg_len    = REGLEN_8bit,
88                 }, {
89                         .id             = 0x1f,
90                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
91                         .name           = "TDA10048-2",
92                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
93                         .i2c_bus_addr   = 0x12 >> 1,
94                         .i2c_reg_len    = REGLEN_8bit,
95                 } },
96         },
97         [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
98                 .name           = "Hauppauge WinTV-HVR2200",
99                 .porta          = SAA7164_MPEG_DVB,
100                 .portb          = SAA7164_MPEG_DVB,
101                 .portc          = SAA7164_MPEG_ENCODER,
102                 .portd          = SAA7164_MPEG_ENCODER,
103                 .porte          = SAA7164_MPEG_VBI,
104                 .portf          = SAA7164_MPEG_VBI,
105                 .chiprev        = SAA7164_CHIP_REV2,
106                 .unit           = {{
107                         .id             = 0x06,
108                         .type           = SAA7164_UNIT_EEPROM,
109                         .name           = "4K EEPROM",
110                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
111                         .i2c_bus_addr   = 0xa0 >> 1,
112                         .i2c_reg_len    = REGLEN_8bit,
113                 }, {
114                         .id             = 0x04,
115                         .type           = SAA7164_UNIT_TUNER,
116                         .name           = "TDA18271-1",
117                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
118                         .i2c_bus_addr   = 0xc0 >> 1,
119                         .i2c_reg_len    = REGLEN_8bit,
120                 }, {
121                         .id             = 0x05,
122                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
123                         .name           = "TDA10048-1",
124                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
125                         .i2c_bus_addr   = 0x10 >> 1,
126                         .i2c_reg_len    = REGLEN_8bit,
127                 }, {
128                         .id             = 0x1e,
129                         .type           = SAA7164_UNIT_TUNER,
130                         .name           = "TDA18271-2",
131                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
132                         .i2c_bus_addr   = 0xc0 >> 1,
133                         .i2c_reg_len    = REGLEN_8bit,
134                 }, {
135                         .id             = 0x1f,
136                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
137                         .name           = "TDA10048-2",
138                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
139                         .i2c_bus_addr   = 0x12 >> 1,
140                         .i2c_reg_len    = REGLEN_8bit,
141                 } },
142         },
143         [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
144                 .name           = "Hauppauge WinTV-HVR2200",
145                 .porta          = SAA7164_MPEG_DVB,
146                 .portb          = SAA7164_MPEG_DVB,
147                 .portc          = SAA7164_MPEG_ENCODER,
148                 .portd          = SAA7164_MPEG_ENCODER,
149                 .porte          = SAA7164_MPEG_VBI,
150                 .portf          = SAA7164_MPEG_VBI,
151                 .chiprev        = SAA7164_CHIP_REV2,
152                 .unit           = {{
153                         .id             = 0x1d,
154                         .type           = SAA7164_UNIT_EEPROM,
155                         .name           = "4K EEPROM",
156                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
157                         .i2c_bus_addr   = 0xa0 >> 1,
158                         .i2c_reg_len    = REGLEN_8bit,
159                 }, {
160                         .id             = 0x04,
161                         .type           = SAA7164_UNIT_TUNER,
162                         .name           = "TDA18271-1",
163                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
164                         .i2c_bus_addr   = 0xc0 >> 1,
165                         .i2c_reg_len    = REGLEN_8bit,
166                 }, {
167                         .id             = 0x05,
168                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
169                         .name           = "TDA8290-1",
170                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
171                         .i2c_bus_addr   = 0x84 >> 1,
172                         .i2c_reg_len    = REGLEN_8bit,
173                 }, {
174                         .id             = 0x1b,
175                         .type           = SAA7164_UNIT_TUNER,
176                         .name           = "TDA18271-2",
177                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
178                         .i2c_bus_addr   = 0xc0 >> 1,
179                         .i2c_reg_len    = REGLEN_8bit,
180                 }, {
181                         .id             = 0x1c,
182                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
183                         .name           = "TDA8290-2",
184                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
185                         .i2c_bus_addr   = 0x84 >> 1,
186                         .i2c_reg_len    = REGLEN_8bit,
187                 }, {
188                         .id             = 0x1e,
189                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
190                         .name           = "TDA10048-1",
191                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
192                         .i2c_bus_addr   = 0x10 >> 1,
193                         .i2c_reg_len    = REGLEN_8bit,
194                 }, {
195                         .id             = 0x1f,
196                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
197                         .name           = "TDA10048-2",
198                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
199                         .i2c_bus_addr   = 0x12 >> 1,
200                         .i2c_reg_len    = REGLEN_8bit,
201                 } },
202         },
203         [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = {
204                 .name           = "Hauppauge WinTV-HVR2200",
205                 .porta          = SAA7164_MPEG_DVB,
206                 .portb          = SAA7164_MPEG_DVB,
207                 .portc          = SAA7164_MPEG_ENCODER,
208                 .portd          = SAA7164_MPEG_ENCODER,
209                 .porte          = SAA7164_MPEG_VBI,
210                 .portf          = SAA7164_MPEG_VBI,
211                 .chiprev        = SAA7164_CHIP_REV3,
212                 .unit           = {{
213                         .id             = 0x1d,
214                         .type           = SAA7164_UNIT_EEPROM,
215                         .name           = "4K EEPROM",
216                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
217                         .i2c_bus_addr   = 0xa0 >> 1,
218                         .i2c_reg_len    = REGLEN_8bit,
219                 }, {
220                         .id             = 0x04,
221                         .type           = SAA7164_UNIT_TUNER,
222                         .name           = "TDA18271-1",
223                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
224                         .i2c_bus_addr   = 0xc0 >> 1,
225                         .i2c_reg_len    = REGLEN_8bit,
226                 }, {
227                         .id             = 0x05,
228                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
229                         .name           = "TDA8290-1",
230                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
231                         .i2c_bus_addr   = 0x84 >> 1,
232                         .i2c_reg_len    = REGLEN_8bit,
233                 }, {
234                         .id             = 0x1b,
235                         .type           = SAA7164_UNIT_TUNER,
236                         .name           = "TDA18271-2",
237                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
238                         .i2c_bus_addr   = 0xc0 >> 1,
239                         .i2c_reg_len    = REGLEN_8bit,
240                 }, {
241                         .id             = 0x1c,
242                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
243                         .name           = "TDA8290-2",
244                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
245                         .i2c_bus_addr   = 0x84 >> 1,
246                         .i2c_reg_len    = REGLEN_8bit,
247                 }, {
248                         .id             = 0x1e,
249                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
250                         .name           = "TDA10048-1",
251                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
252                         .i2c_bus_addr   = 0x10 >> 1,
253                         .i2c_reg_len    = REGLEN_8bit,
254                 }, {
255                         .id             = 0x1f,
256                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
257                         .name           = "TDA10048-2",
258                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
259                         .i2c_bus_addr   = 0x12 >> 1,
260                         .i2c_reg_len    = REGLEN_8bit,
261                 } },
262         },
263         [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
264                 .name           = "Hauppauge WinTV-HVR2250",
265                 .porta          = SAA7164_MPEG_DVB,
266                 .portb          = SAA7164_MPEG_DVB,
267                 .portc          = SAA7164_MPEG_ENCODER,
268                 .portd          = SAA7164_MPEG_ENCODER,
269                 .porte          = SAA7164_MPEG_VBI,
270                 .portf          = SAA7164_MPEG_VBI,
271                 .chiprev        = SAA7164_CHIP_REV3,
272                 .unit           = {{
273                         .id             = 0x22,
274                         .type           = SAA7164_UNIT_EEPROM,
275                         .name           = "4K EEPROM",
276                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
277                         .i2c_bus_addr   = 0xa0 >> 1,
278                         .i2c_reg_len    = REGLEN_8bit,
279                 }, {
280                         .id             = 0x04,
281                         .type           = SAA7164_UNIT_TUNER,
282                         .name           = "TDA18271-1",
283                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
284                         .i2c_bus_addr   = 0xc0 >> 1,
285                         .i2c_reg_len    = REGLEN_8bit,
286                 }, {
287                         .id             = 0x07,
288                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
289                         .name           = "CX24228/S5H1411-1 (TOP)",
290                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
291                         .i2c_bus_addr   = 0x32 >> 1,
292                         .i2c_reg_len    = REGLEN_8bit,
293                 }, {
294                         .id             = 0x08,
295                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
296                         .name           = "CX24228/S5H1411-1 (QAM)",
297                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
298                         .i2c_bus_addr   = 0x34 >> 1,
299                         .i2c_reg_len    = REGLEN_8bit,
300                 }, {
301                         .id             = 0x1e,
302                         .type           = SAA7164_UNIT_TUNER,
303                         .name           = "TDA18271-2",
304                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
305                         .i2c_bus_addr   = 0xc0 >> 1,
306                         .i2c_reg_len    = REGLEN_8bit,
307                 }, {
308                         .id             = 0x20,
309                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
310                         .name           = "CX24228/S5H1411-2 (TOP)",
311                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
312                         .i2c_bus_addr   = 0x32 >> 1,
313                         .i2c_reg_len    = REGLEN_8bit,
314                 }, {
315                         .id             = 0x23,
316                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
317                         .name           = "CX24228/S5H1411-2 (QAM)",
318                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
319                         .i2c_bus_addr   = 0x34 >> 1,
320                         .i2c_reg_len    = REGLEN_8bit,
321                 } },
322         },
323         [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
324                 .name           = "Hauppauge WinTV-HVR2250",
325                 .porta          = SAA7164_MPEG_DVB,
326                 .portb          = SAA7164_MPEG_DVB,
327                 .portc          = SAA7164_MPEG_ENCODER,
328                 .portd          = SAA7164_MPEG_ENCODER,
329                 .porte          = SAA7164_MPEG_VBI,
330                 .portf          = SAA7164_MPEG_VBI,
331                 .chiprev        = SAA7164_CHIP_REV3,
332                 .unit           = {{
333                         .id             = 0x28,
334                         .type           = SAA7164_UNIT_EEPROM,
335                         .name           = "4K EEPROM",
336                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
337                         .i2c_bus_addr   = 0xa0 >> 1,
338                         .i2c_reg_len    = REGLEN_8bit,
339                 }, {
340                         .id             = 0x04,
341                         .type           = SAA7164_UNIT_TUNER,
342                         .name           = "TDA18271-1",
343                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
344                         .i2c_bus_addr   = 0xc0 >> 1,
345                         .i2c_reg_len    = REGLEN_8bit,
346                 }, {
347                         .id             = 0x07,
348                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
349                         .name           = "CX24228/S5H1411-1 (TOP)",
350                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
351                         .i2c_bus_addr   = 0x32 >> 1,
352                         .i2c_reg_len    = REGLEN_8bit,
353                 }, {
354                         .id             = 0x08,
355                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
356                         .name           = "CX24228/S5H1411-1 (QAM)",
357                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
358                         .i2c_bus_addr   = 0x34 >> 1,
359                         .i2c_reg_len    = REGLEN_8bit,
360                 }, {
361                         .id             = 0x24,
362                         .type           = SAA7164_UNIT_TUNER,
363                         .name           = "TDA18271-2",
364                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
365                         .i2c_bus_addr   = 0xc0 >> 1,
366                         .i2c_reg_len    = REGLEN_8bit,
367                 }, {
368                         .id             = 0x26,
369                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
370                         .name           = "CX24228/S5H1411-2 (TOP)",
371                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
372                         .i2c_bus_addr   = 0x32 >> 1,
373                         .i2c_reg_len    = REGLEN_8bit,
374                 }, {
375                         .id             = 0x29,
376                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
377                         .name           = "CX24228/S5H1411-2 (QAM)",
378                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
379                         .i2c_bus_addr   = 0x34 >> 1,
380                         .i2c_reg_len    = REGLEN_8bit,
381                 } },
382         },
383         [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
384                 .name           = "Hauppauge WinTV-HVR2250",
385                 .porta          = SAA7164_MPEG_DVB,
386                 .portb          = SAA7164_MPEG_DVB,
387                 .portc          = SAA7164_MPEG_ENCODER,
388                 .portd          = SAA7164_MPEG_ENCODER,
389                 .porte          = SAA7164_MPEG_VBI,
390                 .portf          = SAA7164_MPEG_VBI,
391                 .chiprev        = SAA7164_CHIP_REV3,
392                 .unit           = {{
393                         .id             = 0x26,
394                         .type           = SAA7164_UNIT_EEPROM,
395                         .name           = "4K EEPROM",
396                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
397                         .i2c_bus_addr   = 0xa0 >> 1,
398                         .i2c_reg_len    = REGLEN_8bit,
399                 }, {
400                         .id             = 0x04,
401                         .type           = SAA7164_UNIT_TUNER,
402                         .name           = "TDA18271-1",
403                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
404                         .i2c_bus_addr   = 0xc0 >> 1,
405                         .i2c_reg_len    = REGLEN_8bit,
406                 }, {
407                         .id             = 0x07,
408                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
409                         .name           = "CX24228/S5H1411-1 (TOP)",
410                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
411                         .i2c_bus_addr   = 0x32 >> 1,
412                         .i2c_reg_len    = REGLEN_8bit,
413                 }, {
414                         .id             = 0x08,
415                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
416                         .name           = "CX24228/S5H1411-1 (QAM)",
417                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
418                         .i2c_bus_addr   = 0x34 >> 1,
419                         .i2c_reg_len    = REGLEN_8bit,
420                 }, {
421                         .id             = 0x22,
422                         .type           = SAA7164_UNIT_TUNER,
423                         .name           = "TDA18271-2",
424                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
425                         .i2c_bus_addr   = 0xc0 >> 1,
426                         .i2c_reg_len    = REGLEN_8bit,
427                 }, {
428                         .id             = 0x24,
429                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
430                         .name           = "CX24228/S5H1411-2 (TOP)",
431                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
432                         .i2c_bus_addr   = 0x32 >> 1,
433                         .i2c_reg_len    = REGLEN_8bit,
434                 }, {
435                         .id             = 0x27,
436                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
437                         .name           = "CX24228/S5H1411-2 (QAM)",
438                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
439                         .i2c_bus_addr   = 0x34 >> 1,
440                         .i2c_reg_len    = REGLEN_8bit,
441                 } },
442         },
443         [SAA7164_BOARD_HAUPPAUGE_HVR2200_5] = {
444                 .name           = "Hauppauge WinTV-HVR2200",
445                 .porta          = SAA7164_MPEG_DVB,
446                 .portb          = SAA7164_MPEG_DVB,
447                 .chiprev        = SAA7164_CHIP_REV3,
448                 .unit           = {{
449                         .id             = 0x23,
450                         .type           = SAA7164_UNIT_EEPROM,
451                         .name           = "4K EEPROM",
452                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
453                         .i2c_bus_addr   = 0xa0 >> 1,
454                         .i2c_reg_len    = REGLEN_8bit,
455                 }, {
456                         .id             = 0x04,
457                         .type           = SAA7164_UNIT_TUNER,
458                         .name           = "TDA18271-1",
459                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
460                         .i2c_bus_addr   = 0xc0 >> 1,
461                         .i2c_reg_len    = REGLEN_8bit,
462                 }, {
463                         .id             = 0x05,
464                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
465                         .name           = "TDA8290-1",
466                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
467                         .i2c_bus_addr   = 0x84 >> 1,
468                         .i2c_reg_len    = REGLEN_8bit,
469                 }, {
470                         .id             = 0x21,
471                         .type           = SAA7164_UNIT_TUNER,
472                         .name           = "TDA18271-2",
473                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
474                         .i2c_bus_addr   = 0xc0 >> 1,
475                         .i2c_reg_len    = REGLEN_8bit,
476                 }, {
477                         .id             = 0x22,
478                         .type           = SAA7164_UNIT_ANALOG_DEMODULATOR,
479                         .name           = "TDA8290-2",
480                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
481                         .i2c_bus_addr   = 0x84 >> 1,
482                         .i2c_reg_len    = REGLEN_8bit,
483                 }, {
484                         .id             = 0x24,
485                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
486                         .name           = "TDA10048-1",
487                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
488                         .i2c_bus_addr   = 0x10 >> 1,
489                         .i2c_reg_len    = REGLEN_8bit,
490                 }, {
491                         .id             = 0x25,
492                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
493                         .name           = "TDA10048-2",
494                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
495                         .i2c_bus_addr   = 0x12 >> 1,
496                         .i2c_reg_len    = REGLEN_8bit,
497                 } },
498         },
499         [SAA7164_BOARD_HAUPPAUGE_HVR2255proto] = {
500                 .name           = "Hauppauge WinTV-HVR2255(proto)",
501                 .porta          = SAA7164_MPEG_DVB,
502                 .portb          = SAA7164_MPEG_DVB,
503                 .portc          = SAA7164_MPEG_ENCODER,
504                 .portd          = SAA7164_MPEG_ENCODER,
505                 .porte          = SAA7164_MPEG_VBI,
506                 .portf          = SAA7164_MPEG_VBI,
507                 .chiprev        = SAA7164_CHIP_REV3,
508                 .unit           = {{
509                         .id             = 0x27,
510                         .type           = SAA7164_UNIT_EEPROM,
511                         .name           = "4K EEPROM",
512                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
513                         .i2c_bus_addr   = 0xa0 >> 1,
514                         .i2c_reg_len    = REGLEN_8bit,
515                 }, {
516                         .id             = 0x04,
517                         .type           = SAA7164_UNIT_TUNER,
518                         .name           = "SI2157-1",
519                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
520                         .i2c_bus_addr   = 0xc0 >> 1,
521                         .i2c_reg_len    = REGLEN_0bit,
522                 }, {
523                         .id             = 0x06,
524                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
525                         .name           = "LGDT3306",
526                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
527                         .i2c_bus_addr   = 0xb2 >> 1,
528                         .i2c_reg_len    = REGLEN_8bit,
529                 }, {
530                         .id             = 0x24,
531                         .type           = SAA7164_UNIT_TUNER,
532                         .name           = "SI2157-2",
533                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
534                         .i2c_bus_addr   = 0xc0 >> 1,
535                         .i2c_reg_len    = REGLEN_0bit,
536                 }, {
537                         .id             = 0x26,
538                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
539                         .name           = "LGDT3306-2",
540                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
541                         .i2c_bus_addr   = 0x1c >> 1,
542                         .i2c_reg_len    = REGLEN_8bit,
543                 } },
544         },
545         [SAA7164_BOARD_HAUPPAUGE_HVR2255] = {
546                 .name           = "Hauppauge WinTV-HVR2255",
547                 .porta          = SAA7164_MPEG_DVB,
548                 .portb          = SAA7164_MPEG_DVB,
549                 .portc          = SAA7164_MPEG_ENCODER,
550                 .portd          = SAA7164_MPEG_ENCODER,
551                 .porte          = SAA7164_MPEG_VBI,
552                 .portf          = SAA7164_MPEG_VBI,
553                 .chiprev        = SAA7164_CHIP_REV3,
554                 .unit           = {{
555                         .id             = 0x28,
556                         .type           = SAA7164_UNIT_EEPROM,
557                         .name           = "4K EEPROM",
558                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
559                         .i2c_bus_addr   = 0xa0 >> 1,
560                         .i2c_reg_len    = REGLEN_8bit,
561                 }, {
562                         .id             = 0x04,
563                         .type           = SAA7164_UNIT_TUNER,
564                         .name           = "SI2157-1",
565                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
566                         .i2c_bus_addr   = 0xc0 >> 1,
567                         .i2c_reg_len    = REGLEN_0bit,
568                 }, {
569                         .id             = 0x06,
570                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
571                         .name           = "LGDT3306-1",
572                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
573                         .i2c_bus_addr   = 0xb2 >> 1,
574                         .i2c_reg_len    = REGLEN_8bit,
575                 }, {
576                         .id             = 0x25,
577                         .type           = SAA7164_UNIT_TUNER,
578                         .name           = "SI2157-2",
579                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
580                         .i2c_bus_addr   = 0xc0 >> 1,
581                         .i2c_reg_len    = REGLEN_0bit,
582                 }, {
583                         .id             = 0x27,
584                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
585                         .name           = "LGDT3306-2",
586                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
587                         .i2c_bus_addr   = 0x1c >> 1,
588                         .i2c_reg_len    = REGLEN_8bit,
589                 } },
590         },
591         [SAA7164_BOARD_HAUPPAUGE_HVR2205] = {
592                 .name           = "Hauppauge WinTV-HVR2205",
593                 .porta          = SAA7164_MPEG_DVB,
594                 .portb          = SAA7164_MPEG_DVB,
595                 .portc          = SAA7164_MPEG_ENCODER,
596                 .portd          = SAA7164_MPEG_ENCODER,
597                 .porte          = SAA7164_MPEG_VBI,
598                 .portf          = SAA7164_MPEG_VBI,
599                 .chiprev        = SAA7164_CHIP_REV3,
600                 .unit           = {{
601                         .id             = 0x28,
602                         .type           = SAA7164_UNIT_EEPROM,
603                         .name           = "4K EEPROM",
604                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
605                         .i2c_bus_addr   = 0xa0 >> 1,
606                         .i2c_reg_len    = REGLEN_8bit,
607                 }, {
608                         .id             = 0x04,
609                         .type           = SAA7164_UNIT_TUNER,
610                         .name           = "SI2157-1",
611                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
612                         .i2c_bus_addr   = 0xc0 >> 1,
613                         .i2c_reg_len    = REGLEN_0bit,
614                 }, {
615                         .id             = 0x06,
616                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
617                         .name           = "SI2168-1",
618                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
619                         .i2c_bus_addr   = 0xc8 >> 1,
620                         .i2c_reg_len    = REGLEN_0bit,
621                 }, {
622                         .id             = 0x25,
623                         .type           = SAA7164_UNIT_TUNER,
624                         .name           = "SI2157-2",
625                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
626                         .i2c_bus_addr   = 0xc0 >> 1,
627                         .i2c_reg_len    = REGLEN_0bit,
628                 }, {
629                         .id             = 0x27,
630                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
631                         .name           = "SI2168-2",
632                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
633                         .i2c_bus_addr   = 0xcc >> 1,
634                         .i2c_reg_len    = REGLEN_0bit,
635                 } },
636         },
637 };
638 const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
639
640 /* ------------------------------------------------------------------ */
641 /* PCI subsystem IDs                                                  */
642
643 struct saa7164_subid saa7164_subids[] = {
644         {
645                 .subvendor = 0x0070,
646                 .subdevice = 0x8880,
647                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
648         }, {
649                 .subvendor = 0x0070,
650                 .subdevice = 0x8810,
651                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
652         }, {
653                 .subvendor = 0x0070,
654                 .subdevice = 0x8980,
655                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200,
656         }, {
657                 .subvendor = 0x0070,
658                 .subdevice = 0x8900,
659                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
660         }, {
661                 .subvendor = 0x0070,
662                 .subdevice = 0x8901,
663                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
664         }, {
665                 .subvendor = 0x0070,
666                 .subdevice = 0x88A1,
667                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
668         }, {
669                 .subvendor = 0x0070,
670                 .subdevice = 0x8891,
671                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
672         }, {
673                 .subvendor = 0x0070,
674                 .subdevice = 0x8851,
675                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
676         }, {
677                 .subvendor = 0x0070,
678                 .subdevice = 0x8940,
679                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
680         }, {
681                 .subvendor = 0x0070,
682                 .subdevice = 0x8953,
683                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
684         }, {
685                 .subvendor = 0x0070,
686                 .subdevice = 0xf111,
687                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2255,
688                 /* Prototype card left here for documentation purposes.
689                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2255proto,
690                 */
691         }, {
692                 .subvendor = 0x0070,
693                 .subdevice = 0xf123,
694                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2205,
695         }, {
696                 .subvendor = 0x0070,
697                 .subdevice = 0xf120,
698                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2205,
699         },
700 };
701 const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
702
703 void saa7164_card_list(struct saa7164_dev *dev)
704 {
705         int i;
706
707         if (0 == dev->pci->subsystem_vendor &&
708             0 == dev->pci->subsystem_device) {
709                 printk(KERN_ERR
710                         "%s: Board has no valid PCIe Subsystem ID and can't\n"
711                         "%s: be autodetected. Pass card=<n> insmod option to\n"
712                         "%s: workaround that. Send complaints to the vendor\n"
713                         "%s: of the TV card. Best regards,\n"
714                         "%s:         -- tux\n",
715                         dev->name, dev->name, dev->name, dev->name, dev->name);
716         } else {
717                 printk(KERN_ERR
718                         "%s: Your board isn't known (yet) to the driver.\n"
719                         "%s: Try to pick one of the existing card configs via\n"
720                         "%s: card=<n> insmod option.  Updating to the latest\n"
721                         "%s: version might help as well.\n",
722                         dev->name, dev->name, dev->name, dev->name);
723         }
724
725         printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod option:\n",
726                dev->name);
727
728         for (i = 0; i < saa7164_bcount; i++)
729                 printk(KERN_ERR "%s:    card=%d -> %s\n",
730                        dev->name, i, saa7164_boards[i].name);
731 }
732
733 /* TODO: clean this define up into the -cards.c structs */
734 #define PCIEBRIDGE_UNITID 2
735
736 void saa7164_gpio_setup(struct saa7164_dev *dev)
737 {
738         switch (dev->board) {
739         case SAA7164_BOARD_HAUPPAUGE_HVR2200:
740         case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
741         case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
742         case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
743         case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
744         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
745         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
746         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
747         case SAA7164_BOARD_HAUPPAUGE_HVR2255proto:
748         case SAA7164_BOARD_HAUPPAUGE_HVR2255:
749         case SAA7164_BOARD_HAUPPAUGE_HVR2205:
750                 /*
751                 HVR2200 / HVR2250
752                 GPIO 2: s5h1411 / tda10048-1 demod reset
753                 GPIO 3: s5h1411 / tda10048-2 demod reset
754                 GPIO 7: IRBlaster Zilog reset
755                  */
756
757                 /* HVR2255
758                  * GPIO 2: lgdg3306-1 demod reset
759                  * GPIO 3: lgdt3306-2 demod reset
760                  */
761
762                 /* HVR2205
763                  * GPIO 2: si2168-1 demod reset
764                  * GPIO 3: si2168-2 demod reset
765                  */
766
767                 /* Reset parts by going in and out of reset */
768                 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
769                 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
770
771                 msleep(20);
772
773                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
774                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
775                 break;
776         }
777 }
778
779 static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
780 {
781         struct tveeprom tv;
782
783         tveeprom_hauppauge_analog(&tv, eeprom_data);
784
785         /* Make sure we support the board model */
786         switch (tv.model) {
787         case 88001:
788                 /* Development board - Limit circulation */
789                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
790                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
791         case 88021:
792                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
793                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
794                 break;
795         case 88041:
796                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
797                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
798                 break;
799         case 88061:
800                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
801                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
802                 break;
803         case 89519:
804         case 89609:
805                 /* WinTV-HVR2200 (PCIe, Retail, full-height)
806                  * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
807                 break;
808         case 89619:
809                 /* WinTV-HVR2200 (PCIe, Retail, half-height)
810                  * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
811                 break;
812         case 151009:
813                 /* First production board rev B2I6 */
814                 /* WinTV-HVR2205 (PCIe, Retail, full-height bracket)
815                  * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */
816                 break;
817         case 151609:
818                 /* First production board rev B2I6 */
819                 /* WinTV-HVR2205 (PCIe, Retail, half-height bracket)
820                  * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */
821                 break;
822         case 151061:
823                 /* First production board rev B1I6 */
824                 /* WinTV-HVR2255 (PCIe, Retail, full-height bracket)
825                  * ATSC/QAM (SI2157/LGDT3306) and basic analog, FM */
826                 break;
827         default:
828                 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
829                         dev->name, tv.model);
830                 break;
831         }
832
833         printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
834                 tv.model);
835 }
836
837 void saa7164_card_setup(struct saa7164_dev *dev)
838 {
839         static u8 eeprom[256];
840
841         if (dev->i2c_bus[0].i2c_rc == 0) {
842                 if (saa7164_api_read_eeprom(dev, &eeprom[0],
843                         sizeof(eeprom)) < 0)
844                         return;
845         }
846
847         switch (dev->board) {
848         case SAA7164_BOARD_HAUPPAUGE_HVR2200:
849         case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
850         case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
851         case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
852         case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
853         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
854         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
855         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
856         case SAA7164_BOARD_HAUPPAUGE_HVR2255proto:
857         case SAA7164_BOARD_HAUPPAUGE_HVR2255:
858         case SAA7164_BOARD_HAUPPAUGE_HVR2205:
859                 hauppauge_eeprom(dev, &eeprom[0]);
860                 break;
861         }
862 }
863
864 /* With most other drivers, the kernel expects to communicate with subdrivers
865  * through i2c. This bridge does not allow that, it does not expose any direct
866  * access to I2C. Instead we have to communicate through the device f/w for
867  * register access to 'processing units'. Each unit has a unique
868  * id, regardless of how the physical implementation occurs across
869  * the three physical i2c buses. The being said if we want leverge of
870  * the existing kernel drivers for tuners and demods we have to 'speak i2c',
871  * to this bridge implements 3 virtual i2c buses. This is a helper function
872  * for those.
873  *
874  * Description: Translate the kernels notion of an i2c address and bus into
875  * the appropriate unitid.
876  */
877 int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
878 {
879         /* For a given bus and i2c device address, return the saa7164 unique
880          * unitid. < 0 on error */
881
882         struct saa7164_dev *dev = bus->dev;
883         struct saa7164_unit *unit;
884         int i;
885
886         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
887                 unit = &saa7164_boards[dev->board].unit[i];
888
889                 if (unit->type == SAA7164_UNIT_UNDEFINED)
890                         continue;
891                 if ((bus->nr == unit->i2c_bus_nr) &&
892                         (addr == unit->i2c_bus_addr))
893                         return unit->id;
894         }
895
896         return -1;
897 }
898
899 /* The 7164 API needs to know the i2c register length in advance.
900  * this is a helper function. Based on a specific chip addr and bus return the
901  * reg length.
902  */
903 int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
904 {
905         /* For a given bus and i2c device address, return the
906          * saa7164 registry address width. < 0 on error
907          */
908
909         struct saa7164_dev *dev = bus->dev;
910         struct saa7164_unit *unit;
911         int i;
912
913         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
914                 unit = &saa7164_boards[dev->board].unit[i];
915
916                 if (unit->type == SAA7164_UNIT_UNDEFINED)
917                         continue;
918
919                 if ((bus->nr == unit->i2c_bus_nr) &&
920                         (addr == unit->i2c_bus_addr))
921                         return unit->i2c_reg_len;
922         }
923
924         return -1;
925 }
926 /* TODO: implement a 'findeeprom' functio like the above and fix any other
927  * eeprom related todo's in -api.c.
928  */
929
930 /* Translate a unitid into a x readable device name, for display purposes.  */
931 char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
932 {
933         char *undefed = "UNDEFINED";
934         char *bridge = "BRIDGE";
935         struct saa7164_unit *unit;
936         int i;
937
938         if (unitid == 0)
939                 return bridge;
940
941         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
942                 unit = &saa7164_boards[dev->board].unit[i];
943
944                 if (unit->type == SAA7164_UNIT_UNDEFINED)
945                         continue;
946
947                 if (unitid == unit->id)
948                                 return unit->name;
949         }
950
951         return undefed;
952 }
953