Bluetooth: Fix event sending with DISCOVERY_STOPPED state
[sfrench/cifs-2.6.git] / drivers / media / video / 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                 .portc          = SAA7164_MPEG_ENCODER,
273                 .portd          = SAA7164_MPEG_ENCODER,
274                 .porte          = SAA7164_MPEG_VBI,
275                 .portf          = SAA7164_MPEG_VBI,
276                 .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,
332                 .portc          = SAA7164_MPEG_ENCODER,
333                 .portd          = SAA7164_MPEG_ENCODER,
334                 .porte          = SAA7164_MPEG_VBI,
335                 .portf          = SAA7164_MPEG_VBI,
336                 .porte          = SAA7164_MPEG_VBI,
337                 .portf          = SAA7164_MPEG_VBI,
338                 .chiprev        = SAA7164_CHIP_REV3,
339                 .unit           = {{
340                         .id             = 0x28,
341                         .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         },
390         [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
391                 .name           = "Hauppauge WinTV-HVR2250",
392                 .porta          = SAA7164_MPEG_DVB,
393                 .portb          = SAA7164_MPEG_DVB,
394                 .portc          = SAA7164_MPEG_ENCODER,
395                 .portd          = SAA7164_MPEG_ENCODER,
396                 .porte          = SAA7164_MPEG_VBI,
397                 .portf          = SAA7164_MPEG_VBI,
398                 .chiprev        = SAA7164_CHIP_REV3,
399                 .unit           = {{
400                         .id             = 0x26,
401                         .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         },
450         [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         },
506 };
507 const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
508
509 /* ------------------------------------------------------------------ */
510 /* PCI subsystem IDs                                                  */
511
512 struct 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,
536                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
537         }, {
538                 .subvendor = 0x0070,
539                 .subdevice = 0x8891,
540                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
541         }, {
542                 .subvendor = 0x0070,
543                 .subdevice = 0x8851,
544                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
545         }, {
546                 .subvendor = 0x0070,
547                 .subdevice = 0x8940,
548                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
549         }, {
550                 .subvendor = 0x0070,
551                 .subdevice = 0x8953,
552                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
553         },
554 };
555 const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
556
557 void 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
590 void saa7164_gpio_setup(struct saa7164_dev *dev)
591 {
592         switch (dev->board) {
593         case SAA7164_BOARD_HAUPPAUGE_HVR2200:
594         case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
595         case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
596         case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
597         case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
598         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
599         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
600         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
601                 /*
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
611                 msleep(20);
612
613                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
614                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
615                 break;
616         }
617 }
618
619 static 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
664 void 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:
678         case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
679         case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
680         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
681         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
682         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
683                 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  */
701 int 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  */
727 int 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.  */
755 char *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