Merge branches 'msm-fixes' and 'msm-video' of git://codeaurora.org/quic/kernel/dwalke...
[pandora-kernel.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_HVR2250] = {
207                 .name           = "Hauppauge WinTV-HVR2250",
208                 .porta          = SAA7164_MPEG_DVB,
209                 .portb          = SAA7164_MPEG_DVB,
210                 .portc          = SAA7164_MPEG_ENCODER,
211                 .portd          = SAA7164_MPEG_ENCODER,
212                 .portc          = SAA7164_MPEG_ENCODER,
213                 .portd          = SAA7164_MPEG_ENCODER,
214                 .porte          = SAA7164_MPEG_VBI,
215                 .portf          = SAA7164_MPEG_VBI,
216                 .chiprev        = SAA7164_CHIP_REV3,
217                 .unit           = {{
218                         .id             = 0x22,
219                         .type           = SAA7164_UNIT_EEPROM,
220                         .name           = "4K EEPROM",
221                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
222                         .i2c_bus_addr   = 0xa0 >> 1,
223                         .i2c_reg_len    = REGLEN_8bit,
224                 }, {
225                         .id             = 0x04,
226                         .type           = SAA7164_UNIT_TUNER,
227                         .name           = "TDA18271-1",
228                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
229                         .i2c_bus_addr   = 0xc0 >> 1,
230                         .i2c_reg_len    = REGLEN_8bit,
231                 }, {
232                         .id             = 0x07,
233                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
234                         .name           = "CX24228/S5H1411-1 (TOP)",
235                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
236                         .i2c_bus_addr   = 0x32 >> 1,
237                         .i2c_reg_len    = REGLEN_8bit,
238                 }, {
239                         .id             = 0x08,
240                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
241                         .name           = "CX24228/S5H1411-1 (QAM)",
242                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
243                         .i2c_bus_addr   = 0x34 >> 1,
244                         .i2c_reg_len    = REGLEN_8bit,
245                 }, {
246                         .id             = 0x1e,
247                         .type           = SAA7164_UNIT_TUNER,
248                         .name           = "TDA18271-2",
249                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
250                         .i2c_bus_addr   = 0xc0 >> 1,
251                         .i2c_reg_len    = REGLEN_8bit,
252                 }, {
253                         .id             = 0x20,
254                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
255                         .name           = "CX24228/S5H1411-2 (TOP)",
256                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
257                         .i2c_bus_addr   = 0x32 >> 1,
258                         .i2c_reg_len    = REGLEN_8bit,
259                 }, {
260                         .id             = 0x23,
261                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
262                         .name           = "CX24228/S5H1411-2 (QAM)",
263                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
264                         .i2c_bus_addr   = 0x34 >> 1,
265                         .i2c_reg_len    = REGLEN_8bit,
266                 } },
267         },
268         [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
269                 .name           = "Hauppauge WinTV-HVR2250",
270                 .porta          = SAA7164_MPEG_DVB,
271                 .portb          = SAA7164_MPEG_DVB,
272                 .portc          = SAA7164_MPEG_ENCODER,
273                 .portd          = SAA7164_MPEG_ENCODER,
274                 .porte          = SAA7164_MPEG_VBI,
275                 .portf          = SAA7164_MPEG_VBI,
276                 .porte          = SAA7164_MPEG_VBI,
277                 .portf          = SAA7164_MPEG_VBI,
278                 .chiprev        = SAA7164_CHIP_REV3,
279                 .unit           = {{
280                         .id             = 0x28,
281                         .type           = SAA7164_UNIT_EEPROM,
282                         .name           = "4K EEPROM",
283                         .i2c_bus_nr     = SAA7164_I2C_BUS_0,
284                         .i2c_bus_addr   = 0xa0 >> 1,
285                         .i2c_reg_len    = REGLEN_8bit,
286                 }, {
287                         .id             = 0x04,
288                         .type           = SAA7164_UNIT_TUNER,
289                         .name           = "TDA18271-1",
290                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
291                         .i2c_bus_addr   = 0xc0 >> 1,
292                         .i2c_reg_len    = REGLEN_8bit,
293                 }, {
294                         .id             = 0x07,
295                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
296                         .name           = "CX24228/S5H1411-1 (TOP)",
297                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
298                         .i2c_bus_addr   = 0x32 >> 1,
299                         .i2c_reg_len    = REGLEN_8bit,
300                 }, {
301                         .id             = 0x08,
302                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
303                         .name           = "CX24228/S5H1411-1 (QAM)",
304                         .i2c_bus_nr     = SAA7164_I2C_BUS_1,
305                         .i2c_bus_addr   = 0x34 >> 1,
306                         .i2c_reg_len    = REGLEN_8bit,
307                 }, {
308                         .id             = 0x24,
309                         .type           = SAA7164_UNIT_TUNER,
310                         .name           = "TDA18271-2",
311                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
312                         .i2c_bus_addr   = 0xc0 >> 1,
313                         .i2c_reg_len    = REGLEN_8bit,
314                 }, {
315                         .id             = 0x26,
316                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
317                         .name           = "CX24228/S5H1411-2 (TOP)",
318                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
319                         .i2c_bus_addr   = 0x32 >> 1,
320                         .i2c_reg_len    = REGLEN_8bit,
321                 }, {
322                         .id             = 0x29,
323                         .type           = SAA7164_UNIT_DIGITAL_DEMODULATOR,
324                         .name           = "CX24228/S5H1411-2 (QAM)",
325                         .i2c_bus_nr     = SAA7164_I2C_BUS_2,
326                         .i2c_bus_addr   = 0x34 >> 1,
327                         .i2c_reg_len    = REGLEN_8bit,
328                 } },
329         },
330         [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
331                 .name           = "Hauppauge WinTV-HVR2250",
332                 .porta          = SAA7164_MPEG_DVB,
333                 .portb          = SAA7164_MPEG_DVB,
334                 .portc          = SAA7164_MPEG_ENCODER,
335                 .portd          = SAA7164_MPEG_ENCODER,
336                 .porte          = SAA7164_MPEG_VBI,
337                 .portf          = SAA7164_MPEG_VBI,
338                 .chiprev        = SAA7164_CHIP_REV3,
339                 .unit           = {{
340                         .id             = 0x26,
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             = 0x22,
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             = 0x24,
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             = 0x27,
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 };
391 const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
392
393 /* ------------------------------------------------------------------ */
394 /* PCI subsystem IDs                                                  */
395
396 struct saa7164_subid saa7164_subids[] = {
397         {
398                 .subvendor = 0x0070,
399                 .subdevice = 0x8880,
400                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
401         }, {
402                 .subvendor = 0x0070,
403                 .subdevice = 0x8810,
404                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
405         }, {
406                 .subvendor = 0x0070,
407                 .subdevice = 0x8980,
408                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200,
409         }, {
410                 .subvendor = 0x0070,
411                 .subdevice = 0x8900,
412                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
413         }, {
414                 .subvendor = 0x0070,
415                 .subdevice = 0x8901,
416                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
417         }, {
418                 .subvendor = 0x0070,
419                 .subdevice = 0x88A1,
420                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
421         }, {
422                 .subvendor = 0x0070,
423                 .subdevice = 0x8891,
424                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
425         }, {
426                 .subvendor = 0x0070,
427                 .subdevice = 0x8851,
428                 .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
429         },
430 };
431 const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
432
433 void saa7164_card_list(struct saa7164_dev *dev)
434 {
435         int i;
436
437         if (0 == dev->pci->subsystem_vendor &&
438             0 == dev->pci->subsystem_device) {
439                 printk(KERN_ERR
440                         "%s: Board has no valid PCIe Subsystem ID and can't\n"
441                         "%s: be autodetected. Pass card=<n> insmod option to\n"
442                         "%s: workaround that. Send complaints to the vendor\n"
443                         "%s: of the TV card. Best regards,\n"
444                         "%s:         -- tux\n",
445                         dev->name, dev->name, dev->name, dev->name, dev->name);
446         } else {
447                 printk(KERN_ERR
448                         "%s: Your board isn't known (yet) to the driver.\n"
449                         "%s: Try to pick one of the existing card configs via\n"
450                         "%s: card=<n> insmod option.  Updating to the latest\n"
451                         "%s: version might help as well.\n",
452                         dev->name, dev->name, dev->name, dev->name);
453         }
454
455         printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
456                 "option:\n", dev->name);
457
458         for (i = 0; i < saa7164_bcount; i++)
459                 printk(KERN_ERR "%s:    card=%d -> %s\n",
460                        dev->name, i, saa7164_boards[i].name);
461 }
462
463 /* TODO: clean this define up into the -cards.c structs */
464 #define PCIEBRIDGE_UNITID 2
465
466 void saa7164_gpio_setup(struct saa7164_dev *dev)
467 {
468         switch (dev->board) {
469         case SAA7164_BOARD_HAUPPAUGE_HVR2200:
470         case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
471         case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
472         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
473         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
474         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
475                 /*
476                 GPIO 2: s5h1411 / tda10048-1 demod reset
477                 GPIO 3: s5h1411 / tda10048-2 demod reset
478                 GPIO 7: IRBlaster Zilog reset
479                  */
480
481                 /* Reset parts by going in and out of reset */
482                 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
483                 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
484
485                 msleep(10);
486
487                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
488                 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
489                 break;
490         }
491 }
492
493 static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
494 {
495         struct tveeprom tv;
496
497         /* TODO: Assumption: eeprom on bus 0 */
498         tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
499                 eeprom_data);
500
501         /* Make sure we support the board model */
502         switch (tv.model) {
503         case 88001:
504                 /* Development board - Limit circulation */
505                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
506                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
507         case 88021:
508                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
509                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
510                 break;
511         case 88041:
512                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
513                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
514                 break;
515         case 88061:
516                 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
517                  * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
518                 break;
519         case 89519:
520         case 89609:
521                 /* WinTV-HVR2200 (PCIe, Retail, full-height)
522                  * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
523                 break;
524         case 89619:
525                 /* WinTV-HVR2200 (PCIe, Retail, half-height)
526                  * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
527                 break;
528         default:
529                 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
530                         dev->name, tv.model);
531                 break;
532         }
533
534         printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
535                 tv.model);
536 }
537
538 void saa7164_card_setup(struct saa7164_dev *dev)
539 {
540         static u8 eeprom[256];
541
542         if (dev->i2c_bus[0].i2c_rc == 0) {
543                 if (saa7164_api_read_eeprom(dev, &eeprom[0],
544                         sizeof(eeprom)) < 0)
545                         return;
546         }
547
548         switch (dev->board) {
549         case SAA7164_BOARD_HAUPPAUGE_HVR2200:
550         case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
551         case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
552         case SAA7164_BOARD_HAUPPAUGE_HVR2250:
553         case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
554         case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
555                 hauppauge_eeprom(dev, &eeprom[0]);
556                 break;
557         }
558 }
559
560 /* With most other drivers, the kernel expects to communicate with subdrivers
561  * through i2c. This bridge does not allow that, it does not expose any direct
562  * access to I2C. Instead we have to communicate through the device f/w for
563  * register access to 'processing units'. Each unit has a unique
564  * id, regardless of how the physical implementation occurs across
565  * the three physical i2c busses. The being said if we want leverge of
566  * the existing kernel drivers for tuners and demods we have to 'speak i2c',
567  * to this bridge implements 3 virtual i2c buses. This is a helper function
568  * for those.
569  *
570  * Description: Translate the kernels notion of an i2c address and bus into
571  * the appropriate unitid.
572  */
573 int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
574 {
575         /* For a given bus and i2c device address, return the saa7164 unique
576          * unitid. < 0 on error */
577
578         struct saa7164_dev *dev = bus->dev;
579         struct saa7164_unit *unit;
580         int i;
581
582         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
583                 unit = &saa7164_boards[dev->board].unit[i];
584
585                 if (unit->type == SAA7164_UNIT_UNDEFINED)
586                         continue;
587                 if ((bus->nr == unit->i2c_bus_nr) &&
588                         (addr == unit->i2c_bus_addr))
589                         return unit->id;
590         }
591
592         return -1;
593 }
594
595 /* The 7164 API needs to know the i2c register length in advance.
596  * this is a helper function. Based on a specific chip addr and bus return the
597  * reg length.
598  */
599 int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
600 {
601         /* For a given bus and i2c device address, return the
602          * saa7164 registry address width. < 0 on error
603          */
604
605         struct saa7164_dev *dev = bus->dev;
606         struct saa7164_unit *unit;
607         int i;
608
609         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
610                 unit = &saa7164_boards[dev->board].unit[i];
611
612                 if (unit->type == SAA7164_UNIT_UNDEFINED)
613                         continue;
614
615                 if ((bus->nr == unit->i2c_bus_nr) &&
616                         (addr == unit->i2c_bus_addr))
617                         return unit->i2c_reg_len;
618         }
619
620         return -1;
621 }
622 /* TODO: implement a 'findeeprom' functio like the above and fix any other
623  * eeprom related todo's in -api.c.
624  */
625
626 /* Translate a unitid into a x readable device name, for display purposes.  */
627 char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
628 {
629         char *undefed = "UNDEFINED";
630         char *bridge = "BRIDGE";
631         struct saa7164_unit *unit;
632         int i;
633
634         if (unitid == 0)
635                 return bridge;
636
637         for (i = 0; i < SAA7164_MAX_UNITS; i++) {
638                 unit = &saa7164_boards[dev->board].unit[i];
639
640                 if (unit->type == SAA7164_UNIT_UNDEFINED)
641                         continue;
642
643                 if (unitid == unit->id)
644                                 return unit->name;
645         }
646
647         return undefed;
648 }
649