]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/video/tveeprom.c
V4L/DVB (6435): tda8290: add support for NXP TDA18271 tuner and TDA8295 analog demod
[karo-tx-linux.git] / drivers / media / video / tveeprom.c
1 /*
2  * tveeprom - eeprom decoder for tvcard configuration eeproms
3  *
4  * Data and decoding routines shamelessly borrowed from bttv-cards.c
5  * eeprom access routine shamelessly borrowed from bttv-if.c
6  * which are:
7
8     Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
9                            & Marcus Metzler (mocm@thp.uni-koeln.de)
10     (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11
12  * Adjustments to fit a more general model and all bugs:
13
14         Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29  */
30
31
32 #include <linux/module.h>
33 #include <linux/errno.h>
34 #include <linux/kernel.h>
35 #include <linux/init.h>
36 #include <linux/types.h>
37 #include <linux/videodev.h>
38 #include <linux/i2c.h>
39
40 #include <media/tuner.h>
41 #include <media/tveeprom.h>
42 #include <media/v4l2-common.h>
43 #include <media/audiochip.h>
44
45 MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
46 MODULE_AUTHOR("John Klar");
47 MODULE_LICENSE("GPL");
48
49 static int debug = 0;
50 module_param(debug, int, 0644);
51 MODULE_PARM_DESC(debug, "Debug level (0-1)");
52
53 #define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
54
55 #define tveeprom_info(fmt, arg...) \
56         v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg)
57 #define tveeprom_warn(fmt, arg...) \
58         v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg)
59 #define tveeprom_dbg(fmt, arg...) do { \
60         if (debug) \
61                 v4l_printk(KERN_DEBUG, "tveeprom", c->adapter, c->addr, fmt , ## arg); \
62         } while (0)
63
64 /*
65  * The Hauppauge eeprom uses an 8bit field to determine which
66  * tuner formats the tuner supports.
67  */
68 static struct HAUPPAUGE_TUNER_FMT
69 {
70         int     id;
71         char *name;
72 }
73 hauppauge_tuner_fmt[] =
74 {
75         { V4L2_STD_UNKNOWN,                   " UNKNOWN" },
76         { V4L2_STD_UNKNOWN,                   " FM" },
77         { V4L2_STD_B|V4L2_STD_GH,             " PAL(B/G)" },
78         { V4L2_STD_MN,                        " NTSC(M)" },
79         { V4L2_STD_PAL_I,                     " PAL(I)" },
80         { V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, " SECAM(L/L')" },
81         { V4L2_STD_DK,                        " PAL(D/D1/K)" },
82         { V4L2_STD_ATSC,                      " ATSC/DVB Digital" },
83 };
84
85 /* This is the full list of possible tuners. Many thanks to Hauppauge for
86    supplying this information. Note that many tuners where only used for
87    testing and never made it to the outside world. So you will only see
88    a subset in actual produced cards. */
89 static struct HAUPPAUGE_TUNER
90 {
91         int  id;
92         char *name;
93 }
94 hauppauge_tuner[] =
95 {
96         /* 0-9 */
97         { TUNER_ABSENT,        "None" },
98         { TUNER_ABSENT,        "External" },
99         { TUNER_ABSENT,        "Unspecified" },
100         { TUNER_PHILIPS_PAL,   "Philips FI1216" },
101         { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
102         { TUNER_PHILIPS_NTSC,  "Philips FI1236" },
103         { TUNER_PHILIPS_PAL_I, "Philips FI1246" },
104         { TUNER_PHILIPS_PAL_DK,"Philips FI1256" },
105         { TUNER_PHILIPS_PAL,   "Philips FI1216 MK2" },
106         { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
107         /* 10-19 */
108         { TUNER_PHILIPS_NTSC,  "Philips FI1236 MK2" },
109         { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
110         { TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" },
111         { TUNER_TEMIC_NTSC,    "Temic 4032FY5" },
112         { TUNER_TEMIC_PAL,     "Temic 4002FH5" },
113         { TUNER_TEMIC_PAL_I,   "Temic 4062FY5" },
114         { TUNER_PHILIPS_PAL,   "Philips FR1216 MK2" },
115         { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
116         { TUNER_PHILIPS_NTSC,  "Philips FR1236 MK2" },
117         { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
118         /* 20-29 */
119         { TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" },
120         { TUNER_PHILIPS_PAL,   "Philips FM1216" },
121         { TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
122         { TUNER_PHILIPS_NTSC,  "Philips FM1236" },
123         { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
124         { TUNER_PHILIPS_PAL_DK,"Philips FM1256" },
125         { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
126         { TUNER_ABSENT,        "Samsung TCPN9082D" },
127         { TUNER_ABSENT,        "Samsung TCPM9092P" },
128         { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
129         /* 30-39 */
130         { TUNER_ABSENT,        "Samsung TCPN9085D" },
131         { TUNER_ABSENT,        "Samsung TCPB9085P" },
132         { TUNER_ABSENT,        "Samsung TCPL9091P" },
133         { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
134         { TUNER_PHILIPS_FQ1216ME,   "Philips FQ1216 ME" },
135         { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
136         { TUNER_PHILIPS_NTSC,        "Philips TD1536" },
137         { TUNER_PHILIPS_NTSC,        "Philips TD1536D" },
138         { TUNER_PHILIPS_NTSC,  "Philips FMR1236" }, /* mono radio */
139         { TUNER_ABSENT,        "Philips FI1256MP" },
140         /* 40-49 */
141         { TUNER_ABSENT,        "Samsung TCPQ9091P" },
142         { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
143         { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
144         { TUNER_TEMIC_4046FM5,     "Temic 4046FM5" },
145         { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
146         { TUNER_ABSENT,        "Philips TD1536D FH 44"},
147         { TUNER_LG_NTSC_FM,    "LG TP18NSR01F"},
148         { TUNER_LG_PAL_FM,     "LG TP18PSB01D"},
149         { TUNER_LG_PAL,        "LG TP18PSB11D"},
150         { TUNER_LG_PAL_I_FM,   "LG TAPC-I001D"},
151         /* 50-59 */
152         { TUNER_LG_PAL_I,      "LG TAPC-I701D"},
153         { TUNER_ABSENT,        "Temic 4042FI5"},
154         { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
155         { TUNER_ABSENT,        "LG TPI8NSR11F"},
156         { TUNER_ABSENT,        "Microtune 4049 FM5 Alt I2C"},
157         { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"},
158         { TUNER_ABSENT,        "Philips FI1236 MK3"},
159         { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
160         { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
161         { TUNER_ABSENT,        "Philips FM1216MP MK3"},
162         /* 60-69 */
163         { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
164         { TUNER_ABSENT,        "LG M001D MK3"},
165         { TUNER_PHILIPS_FM1216ME_MK3, "LG S701D MK3"},
166         { TUNER_ABSENT,        "LG M701D MK3"},
167         { TUNER_ABSENT,        "Temic 4146FM5"},
168         { TUNER_ABSENT,        "Temic 4136FY5"},
169         { TUNER_ABSENT,        "Temic 4106FH5"},
170         { TUNER_ABSENT,        "Philips FQ1216LMP MK3"},
171         { TUNER_LG_NTSC_TAPE,  "LG TAPE H001F MK3"},
172         { TUNER_LG_NTSC_TAPE,  "LG TAPE H701F MK3"},
173         /* 70-79 */
174         { TUNER_ABSENT,        "LG TALN H200T"},
175         { TUNER_ABSENT,        "LG TALN H250T"},
176         { TUNER_ABSENT,        "LG TALN M200T"},
177         { TUNER_ABSENT,        "LG TALN Z200T"},
178         { TUNER_ABSENT,        "LG TALN S200T"},
179         { TUNER_ABSENT,        "Thompson DTT7595"},
180         { TUNER_ABSENT,        "Thompson DTT7592"},
181         { TUNER_ABSENT,        "Silicon TDA8275C1 8290"},
182         { TUNER_ABSENT,        "Silicon TDA8275C1 8290 FM"},
183         { TUNER_ABSENT,        "Thompson DTT757"},
184         /* 80-89 */
185         { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216LME MK3"},
186         { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
187         { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
188         { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
189         { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
190         { TUNER_TCL_2002N,     "TCL 2002N 6A"},
191         { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
192         { TUNER_SAMSUNG_TCPN_2121P30A, "Samsung TCPN 2121P30A"},
193         { TUNER_ABSENT,        "Samsung TCPE 4121P30A"},
194         { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
195         /* 90-99 */
196         { TUNER_ABSENT,        "LG TALN H202T"},
197         { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"},
198         { TUNER_PHILIPS_FQ1236A_MK4, "Philips FQ1236A MK4"},
199         { TUNER_ABSENT,        "Philips FQ1286A MK4"},
200         { TUNER_ABSENT,        "Philips FQ1216ME MK5"},
201         { TUNER_ABSENT,        "Philips FQ1236 MK5"},
202         { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"},
203         { TUNER_TCL_2002MB,    "TCL 2002MB_3H"},
204         { TUNER_ABSENT,        "TCL 2002MI_3H"},
205         { TUNER_TCL_2002N,     "TCL 2002N 5H"},
206         /* 100-109 */
207         { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216ME"},
208         { TUNER_TEA5767,       "Philips TEA5768HL FM Radio"},
209         { TUNER_ABSENT,        "Panasonic ENV57H12D5"},
210         { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
211         { TUNER_ABSENT,        "TCL MNM05-4"},
212         { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
213         { TUNER_ABSENT,        "TCL MQNM05-4"},
214         { TUNER_ABSENT,        "LG TAPC-W701D"},
215         { TUNER_ABSENT,        "TCL 9886P-WM"},
216         { TUNER_ABSENT,        "TCL 1676NM-WM"},
217         /* 110-119 */
218         { TUNER_ABSENT,        "Thompson DTT75105"},
219         { TUNER_ABSENT,        "Conexant_CX24109"},
220         { TUNER_TCL_2002N,     "TCL M2523_5N_E"},
221         { TUNER_TCL_2002MB,    "TCL M2523_3DB_E"},
222         { TUNER_ABSENT,        "Philips 8275A"},
223         { TUNER_ABSENT,        "Microtune MT2060"},
224         { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK5"},
225         { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216ME MK5"},
226         { TUNER_ABSENT,        "TCL M2523_3DI_E"},
227         { TUNER_ABSENT,        "Samsung THPD5222FG30A"},
228         /* 120-129 */
229         { TUNER_ABSENT,        "Xceive XC3028"},
230         { TUNER_ABSENT,        "Philips FQ1216LME MK5"},
231         { TUNER_ABSENT,        "Philips FQD1216LME"},
232         { TUNER_ABSENT,        "Conexant CX24118A"},
233         { TUNER_ABSENT,        "TCL DMF11WIP"},
234         { TUNER_ABSENT,        "TCL MFNM05_4H_E"},
235         { TUNER_ABSENT,        "TCL MNM05_4H_E"},
236         { TUNER_ABSENT,        "TCL MPE05_2H_E"},
237         { TUNER_ABSENT,        "TCL MQNM05_4_U"},
238         { TUNER_ABSENT,        "TCL M2523_5NH_E"},
239         /* 130-139 */
240         { TUNER_ABSENT,        "TCL M2523_3DBH_E"},
241         { TUNER_ABSENT,        "TCL M2523_3DIH_E"},
242         { TUNER_ABSENT,        "TCL MFPE05_2_U"},
243         { TUNER_ABSENT,        "Philips FMD1216MEX"},
244         { TUNER_ABSENT,        "Philips FRH2036B"},
245         { TUNER_ABSENT,        "Panasonic ENGF75_01GF"},
246         { TUNER_ABSENT,        "MaxLinear MXL5005"},
247         { TUNER_ABSENT,        "MaxLinear MXL5003"},
248         { TUNER_ABSENT,        "Xceive XC2028"},
249         { TUNER_ABSENT,        "Microtune MT2131"},
250         /* 140-149 */
251         { TUNER_ABSENT,        "Philips 8275A_8295"},
252         { TUNER_ABSENT,        "TCL MF02GIP_5N_E"},
253         { TUNER_ABSENT,        "TCL MF02GIP_3DB_E"},
254         { TUNER_ABSENT,        "TCL MF02GIP_3DI_E"},
255         { TUNER_ABSENT,        "Microtune MT2266"},
256         { TUNER_ABSENT,        "TCL MF10WPP_4N_E"},
257         { TUNER_ABSENT,        "LG TAPQ_H702F"},
258         { TUNER_ABSENT,        "TCL M09WPP_4N_E"},
259         { TUNER_ABSENT,        "MaxLinear MXL5005_v2"},
260         { TUNER_PHILIPS_TDA8295, "Philips 18271_8295"},
261 };
262
263 static struct HAUPPAUGE_AUDIOIC
264 {
265         enum audiochip  id;
266         char *name;
267 }
268 audioIC[] =
269 {
270         /* 0-4 */
271         {AUDIO_CHIP_NONE,     "None"},
272         {AUDIO_CHIP_TEA6300,  "TEA6300"},
273         {AUDIO_CHIP_TEA6300,  "TEA6320"},
274         {AUDIO_CHIP_TDA985X,  "TDA9850"},
275         {AUDIO_CHIP_MSP34XX,  "MSP3400C"},
276         /* 5-9 */
277         {AUDIO_CHIP_MSP34XX,  "MSP3410D"},
278         {AUDIO_CHIP_MSP34XX,  "MSP3415"},
279         {AUDIO_CHIP_MSP34XX,  "MSP3430"},
280         {AUDIO_CHIP_MSP34XX,  "MSP3438"},
281         {AUDIO_CHIP_UNKNOWN,  "CS5331"},
282         /* 10-14 */
283         {AUDIO_CHIP_MSP34XX,  "MSP3435"},
284         {AUDIO_CHIP_MSP34XX,  "MSP3440"},
285         {AUDIO_CHIP_MSP34XX,  "MSP3445"},
286         {AUDIO_CHIP_MSP34XX,  "MSP3411"},
287         {AUDIO_CHIP_MSP34XX,  "MSP3416"},
288         /* 15-19 */
289         {AUDIO_CHIP_MSP34XX,  "MSP3425"},
290         {AUDIO_CHIP_MSP34XX,  "MSP3451"},
291         {AUDIO_CHIP_MSP34XX,  "MSP3418"},
292         {AUDIO_CHIP_UNKNOWN,  "Type 0x12"},
293         {AUDIO_CHIP_UNKNOWN,  "OKI7716"},
294         /* 20-24 */
295         {AUDIO_CHIP_MSP34XX,  "MSP4410"},
296         {AUDIO_CHIP_MSP34XX,  "MSP4420"},
297         {AUDIO_CHIP_MSP34XX,  "MSP4440"},
298         {AUDIO_CHIP_MSP34XX,  "MSP4450"},
299         {AUDIO_CHIP_MSP34XX,  "MSP4408"},
300         /* 25-29 */
301         {AUDIO_CHIP_MSP34XX,  "MSP4418"},
302         {AUDIO_CHIP_MSP34XX,  "MSP4428"},
303         {AUDIO_CHIP_MSP34XX,  "MSP4448"},
304         {AUDIO_CHIP_MSP34XX,  "MSP4458"},
305         {AUDIO_CHIP_MSP34XX,  "Type 0x1d"},
306         /* 30-34 */
307         {AUDIO_CHIP_INTERNAL, "CX880"},
308         {AUDIO_CHIP_INTERNAL, "CX881"},
309         {AUDIO_CHIP_INTERNAL, "CX883"},
310         {AUDIO_CHIP_INTERNAL, "CX882"},
311         {AUDIO_CHIP_INTERNAL, "CX25840"},
312         /* 35-39 */
313         {AUDIO_CHIP_INTERNAL, "CX25841"},
314         {AUDIO_CHIP_INTERNAL, "CX25842"},
315         {AUDIO_CHIP_INTERNAL, "CX25843"},
316         {AUDIO_CHIP_INTERNAL, "CX23418"},
317         {AUDIO_CHIP_INTERNAL, "CX23885"},
318         /* 40-42 */
319         {AUDIO_CHIP_INTERNAL, "CX23888"},
320         {AUDIO_CHIP_INTERNAL, "SAA7131"},
321         {AUDIO_CHIP_INTERNAL, "CX23887"},
322 };
323
324 /* This list is supplied by Hauppauge. Thanks! */
325 static const char *decoderIC[] = {
326         /* 0-4 */
327         "None", "BT815", "BT817", "BT819", "BT815A",
328         /* 5-9 */
329         "BT817A", "BT819A", "BT827", "BT829", "BT848",
330         /* 10-14 */
331         "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
332         /* 15-19 */
333         "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
334         /* 20-24 */
335         "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
336         /* 25-29 */
337         "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
338         /* 30-34 */
339         "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
340         /* 35-37 */
341         "SAA7131", "CX25837", "CX23887"
342 };
343
344 static int hasRadioTuner(int tunerType)
345 {
346         switch (tunerType) {
347                 case 18: //PNPEnv_TUNER_FR1236_MK2:
348                 case 23: //PNPEnv_TUNER_FM1236:
349                 case 38: //PNPEnv_TUNER_FMR1236:
350                 case 16: //PNPEnv_TUNER_FR1216_MK2:
351                 case 19: //PNPEnv_TUNER_FR1246_MK2:
352                 case 21: //PNPEnv_TUNER_FM1216:
353                 case 24: //PNPEnv_TUNER_FM1246:
354                 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
355                 case 22: //PNPEnv_TUNER_FM1216MF:
356                 case 20: //PNPEnv_TUNER_FR1256_MK2:
357                 case 25: //PNPEnv_TUNER_FM1256:
358                 case 33: //PNPEnv_TUNER_4039FR5:
359                 case 42: //PNPEnv_TUNER_4009FR5:
360                 case 52: //PNPEnv_TUNER_4049FM5:
361                 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
362                 case 44: //PNPEnv_TUNER_4009FN5:
363                 case 31: //PNPEnv_TUNER_TCPB9085P:
364                 case 30: //PNPEnv_TUNER_TCPN9085D:
365                 case 46: //PNPEnv_TUNER_TP18NSR01F:
366                 case 47: //PNPEnv_TUNER_TP18PSB01D:
367                 case 49: //PNPEnv_TUNER_TAPC_I001D:
368                 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
369                 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
370                 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
371                 case 58: //PNPEnv_TUNER_FM1236_MK3:
372                 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
373                 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
374                 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
375                 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
376                 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
377                 case 105:
378                 return 1;
379         }
380         return 0;
381 }
382
383 void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
384                                 unsigned char *eeprom_data)
385 {
386         /* ----------------------------------------------
387         ** The hauppauge eeprom format is tagged
388         **
389         ** if packet[0] == 0x84, then packet[0..1] == length
390         ** else length = packet[0] & 3f;
391         ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
392         **
393         ** In our (ivtv) case we're interested in the following:
394         ** tuner type:   tag [00].05 or [0a].01 (index into hauppauge_tuner)
395         ** tuner fmts:   tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt)
396         ** radio:        tag [00].{last} or [0e].00  (bitmask.  bit2=FM)
397         ** audio proc:   tag [02].01 or [05].00 (mask with 0x7f)
398         ** decoder proc: tag [09].01)
399
400         ** Fun info:
401         ** model:      tag [00].07-08 or [06].00-01
402         ** revision:   tag [00].09-0b or [06].04-06
403         ** serial#:    tag [01].05-07 or [04].04-06
404
405         ** # of inputs/outputs ???
406         */
407
408         int i, j, len, done, beenhere, tag,start;
409
410         int tuner1 = 0, t_format1 = 0, audioic=-1;
411         char *t_name1 = NULL;
412         const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
413
414         int tuner2 = 0, t_format2 = 0;
415         char *t_name2 = NULL;
416         const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
417
418         memset(tvee, 0, sizeof(*tvee));
419         done = len = beenhere = 0;
420
421         /* Hack for processing eeprom for em28xx and cx 2388x*/
422         if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) &&
423                         (eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95))
424                 start=0xa0; /* Generic em28xx offset */
425         else if (((eeprom_data[0] & 0xe1) == 0x01) &&
426                                         (eeprom_data[1] == 0x00) &&
427                                         (eeprom_data[2] == 0x00) &&
428                                         (eeprom_data[8] == 0x84))
429                 start=8; /* Generic cx2388x offset */
430         else
431                 start=0;
432
433         for (i = start; !done && i < 256; i += len) {
434                 if (eeprom_data[i] == 0x84) {
435                         len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
436                         i += 3;
437                 } else if ((eeprom_data[i] & 0xf0) == 0x70) {
438                         if (eeprom_data[i] & 0x08) {
439                                 /* verify checksum! */
440                                 done = 1;
441                                 break;
442                         }
443                         len = eeprom_data[i] & 0x07;
444                         ++i;
445                 } else {
446                         tveeprom_warn("Encountered bad packet header [%02x]. "
447                                 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
448                         return;
449                 }
450
451                 if (debug) {
452                         tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
453                         for(j = 1; j < len; j++) {
454                                 printk(" %02x", eeprom_data[i + j]);
455                         }
456                         printk("\n");
457                 }
458
459                 /* process by tag */
460                 tag = eeprom_data[i];
461                 switch (tag) {
462                 case 0x00:
463                         /* tag: 'Comprehensive' */
464                         tuner1 = eeprom_data[i+6];
465                         t_format1 = eeprom_data[i+5];
466                         tvee->has_radio = eeprom_data[i+len-1];
467                         /* old style tag, don't know how to detect
468                         IR presence, mark as unknown. */
469                         tvee->has_ir = -1;
470                         tvee->model =
471                                 eeprom_data[i+8] +
472                                 (eeprom_data[i+9] << 8);
473                         tvee->revision = eeprom_data[i+10] +
474                                 (eeprom_data[i+11] << 8) +
475                                 (eeprom_data[i+12] << 16);
476                         break;
477
478                 case 0x01:
479                         /* tag: 'SerialID' */
480                         tvee->serial_number =
481                                 eeprom_data[i+6] +
482                                 (eeprom_data[i+7] << 8) +
483                                 (eeprom_data[i+8] << 16);
484                         break;
485
486                 case 0x02:
487                         /* tag 'AudioInfo'
488                         Note mask with 0x7F, high bit used on some older models
489                         to indicate 4052 mux was removed in favor of using MSP
490                         inputs directly. */
491                         audioic = eeprom_data[i+2] & 0x7f;
492                         if (audioic < ARRAY_SIZE(audioIC))
493                                 tvee->audio_processor = audioIC[audioic].id;
494                         else
495                                 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
496                         break;
497
498                 /* case 0x03: tag 'EEInfo' */
499
500                 case 0x04:
501                         /* tag 'SerialID2' */
502                         tvee->serial_number =
503                                 eeprom_data[i+5] +
504                                 (eeprom_data[i+6] << 8) +
505                                 (eeprom_data[i+7] << 16);
506
507                                 if ( (eeprom_data[i + 8] & 0xf0) &&
508                                         (tvee->serial_number < 0xffffff) ) {
509                                         tvee->MAC_address[0] = 0x00;
510                                         tvee->MAC_address[1] = 0x0D;
511                                         tvee->MAC_address[2] = 0xFE;
512                                         tvee->MAC_address[3] = eeprom_data[i + 7];
513                                         tvee->MAC_address[4] = eeprom_data[i + 6];
514                                         tvee->MAC_address[5] = eeprom_data[i + 5];
515                                         tvee->has_MAC_address = 1;
516                                 }
517                         break;
518
519                 case 0x05:
520                         /* tag 'Audio2'
521                         Note mask with 0x7F, high bit used on some older models
522                         to indicate 4052 mux was removed in favor of using MSP
523                         inputs directly. */
524                         audioic = eeprom_data[i+1] & 0x7f;
525                         if (audioic < ARRAY_SIZE(audioIC))
526                                 tvee->audio_processor = audioIC[audioic].id;
527                         else
528                                 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
529
530                         break;
531
532                 case 0x06:
533                         /* tag 'ModelRev' */
534                         tvee->model =
535                                 eeprom_data[i + 1] +
536                                 (eeprom_data[i + 2] << 8) +
537                                 (eeprom_data[i + 3] << 16) +
538                                 (eeprom_data[i + 4] << 24);
539                         tvee->revision =
540                                 eeprom_data[i +5 ] +
541                                 (eeprom_data[i + 6] << 8) +
542                                 (eeprom_data[i + 7] << 16);
543                         break;
544
545                 case 0x07:
546                         /* tag 'Details': according to Hauppauge not interesting
547                         on any PCI-era or later boards. */
548                         break;
549
550                 /* there is no tag 0x08 defined */
551
552                 case 0x09:
553                         /* tag 'Video' */
554                         tvee->decoder_processor = eeprom_data[i + 1];
555                         break;
556
557                 case 0x0a:
558                         /* tag 'Tuner' */
559                         if (beenhere == 0) {
560                                 tuner1 = eeprom_data[i+2];
561                                 t_format1 = eeprom_data[i+1];
562                                 beenhere = 1;
563                         } else {
564                                 /* a second (radio) tuner may be present */
565                                 tuner2 = eeprom_data[i+2];
566                                 t_format2 = eeprom_data[i+1];
567                                 if (t_format2 == 0) {  /* not a TV tuner? */
568                                         tvee->has_radio = 1; /* must be radio */
569                                 }
570                         }
571                         break;
572
573                 case 0x0b:
574                         /* tag 'Inputs': according to Hauppauge this is specific
575                         to each driver family, so no good assumptions can be
576                         made. */
577                         break;
578
579                 /* case 0x0c: tag 'Balun' */
580                 /* case 0x0d: tag 'Teletext' */
581
582                 case 0x0e:
583                         /* tag: 'Radio' */
584                         tvee->has_radio = eeprom_data[i+1];
585                         break;
586
587                 case 0x0f:
588                         /* tag 'IRInfo' */
589                         tvee->has_ir = eeprom_data[i+1];
590                         break;
591
592                 /* case 0x10: tag 'VBIInfo' */
593                 /* case 0x11: tag 'QCInfo' */
594                 /* case 0x12: tag 'InfoBits' */
595
596                 default:
597                         tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
598                         /* dump the rest of the packet? */
599                 }
600         }
601
602         if (!done) {
603                 tveeprom_warn("Ran out of data!\n");
604                 return;
605         }
606
607         if (tvee->revision != 0) {
608                 tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
609                 tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
610                 tvee->rev_str[2] = 32 + ((tvee->revision >>  6) & 0x3f);
611                 tvee->rev_str[3] = 32 + ( tvee->revision        & 0x3f);
612                 tvee->rev_str[4] = 0;
613         }
614
615         if (hasRadioTuner(tuner1) && !tvee->has_radio) {
616                 tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
617                 tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
618                 tvee->has_radio = 1;
619         }
620
621         if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
622                 tvee->tuner_type = hauppauge_tuner[tuner1].id;
623                 t_name1 = hauppauge_tuner[tuner1].name;
624         } else {
625                 t_name1 = "unknown";
626         }
627
628         if (tuner2 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
629                 tvee->tuner2_type = hauppauge_tuner[tuner2].id;
630                 t_name2 = hauppauge_tuner[tuner2].name;
631         } else {
632                 t_name2 = "unknown";
633         }
634
635         tvee->tuner_hauppauge_model = tuner1;
636         tvee->tuner2_hauppauge_model = tuner2;
637         tvee->tuner_formats = 0;
638         tvee->tuner2_formats = 0;
639         for (i = j = 0; i < 8; i++) {
640                 if (t_format1 & (1 << i)) {
641                         tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
642                         t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
643                 }
644         }
645         for (i = j = 0; i < 8; i++) {
646                 if (t_format2 & (1 << i)) {
647                         tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
648                         t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
649                 }
650         }
651
652         tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
653                 tvee->model, tvee->rev_str, tvee->serial_number);
654         if (tvee->has_MAC_address == 1) {
655                 tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n",
656                         tvee->MAC_address[0], tvee->MAC_address[1],
657                         tvee->MAC_address[2], tvee->MAC_address[3],
658                         tvee->MAC_address[4], tvee->MAC_address[5]);
659         }
660         tveeprom_info("tuner model is %s (idx %d, type %d)\n",
661                 t_name1, tuner1, tvee->tuner_type);
662         tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
663                 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
664                 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
665                 t_format1);
666         if (tuner2) {
667                 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
668                                         t_name2, tuner2, tvee->tuner2_type);
669         }
670         if (t_format2) {
671                 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
672                         t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
673                         t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
674                         t_format2);
675         }
676         if (audioic<0) {
677                 tveeprom_info("audio processor is unknown (no idx)\n");
678                 tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
679         } else {
680                 if (audioic < ARRAY_SIZE(audioIC))
681                         tveeprom_info("audio processor is %s (idx %d)\n",
682                                         audioIC[audioic].name,audioic);
683                 else
684                         tveeprom_info("audio processor is unknown (idx %d)\n",
685                                                                 audioic);
686         }
687         if (tvee->decoder_processor) {
688                 tveeprom_info("decoder processor is %s (idx %d)\n",
689                         STRM(decoderIC, tvee->decoder_processor),
690                         tvee->decoder_processor);
691         }
692         if (tvee->has_ir == -1)
693                 tveeprom_info("has %sradio\n",
694                                 tvee->has_radio ? "" : "no ");
695         else
696                 tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
697                                 tvee->has_radio ? "" : "no ",
698                                 (tvee->has_ir & 1) ? "" : "no ",
699                                 (tvee->has_ir & 2) ? "" : "no ");
700 }
701 EXPORT_SYMBOL(tveeprom_hauppauge_analog);
702
703 /* ----------------------------------------------------------------------- */
704 /* generic helper functions                                                */
705
706 int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
707 {
708         unsigned char buf;
709         int err;
710
711         buf = 0;
712         if (1 != (err = i2c_master_send(c, &buf, 1))) {
713                 tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
714                 return -1;
715         }
716         if (len != (err = i2c_master_recv(c, eedata, len))) {
717                 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
718                 return -1;
719         }
720         if (debug) {
721                 int i;
722
723                 tveeprom_info("full 256-byte eeprom dump:\n");
724                 for (i = 0; i < len; i++) {
725                         if (0 == (i % 16))
726                                 tveeprom_info("%02x:", i);
727                         printk(" %02x", eedata[i]);
728                         if (15 == (i % 16))
729                                 printk("\n");
730                 }
731         }
732         return 0;
733 }
734 EXPORT_SYMBOL(tveeprom_read);
735
736 /* ----------------------------------------------------------------------- */
737 /* needed for ivtv.sf.net at the moment.  Should go away in the long       */
738 /* run, just call the exported tveeprom_* directly, there is no point in   */
739 /* using the indirect way via i2c_driver->command()                        */
740
741 static unsigned short normal_i2c[] = {
742         0xa0 >> 1,
743         I2C_CLIENT_END,
744 };
745
746 I2C_CLIENT_INSMOD;
747
748 static struct i2c_driver i2c_driver_tveeprom;
749
750 static int
751 tveeprom_command(struct i2c_client *client,
752                  unsigned int       cmd,
753                  void              *arg)
754 {
755         struct tveeprom eeprom;
756         u32 *eeprom_props = arg;
757         u8 *buf;
758
759         switch (cmd) {
760         case 0:
761                 buf = kzalloc(256,GFP_KERNEL);
762                 tveeprom_read(client,buf,256);
763                 tveeprom_hauppauge_analog(client, &eeprom,buf);
764                 kfree(buf);
765                 eeprom_props[0] = eeprom.tuner_type;
766                 eeprom_props[1] = eeprom.tuner_formats;
767                 eeprom_props[2] = eeprom.model;
768                 eeprom_props[3] = eeprom.revision;
769                 eeprom_props[4] = eeprom.has_radio;
770                 break;
771         default:
772                 return -EINVAL;
773         }
774         return 0;
775 }
776
777 static int
778 tveeprom_detect_client(struct i2c_adapter *adapter,
779                        int                 address,
780                        int                 kind)
781 {
782         struct i2c_client *client;
783
784         client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
785         if (NULL == client)
786                 return -ENOMEM;
787         client->addr = address;
788         client->adapter = adapter;
789         client->driver = &i2c_driver_tveeprom;
790         snprintf(client->name, sizeof(client->name), "tveeprom");
791         i2c_attach_client(client);
792
793         return 0;
794 }
795
796 static int
797 tveeprom_attach_adapter (struct i2c_adapter *adapter)
798 {
799         if (adapter->class & I2C_CLASS_TV_ANALOG)
800                 return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
801         return 0;
802 }
803
804 static int
805 tveeprom_detach_client (struct i2c_client *client)
806 {
807         int err;
808
809         err = i2c_detach_client(client);
810         if (err < 0)
811                 return err;
812         kfree(client);
813         return 0;
814 }
815
816 static struct i2c_driver i2c_driver_tveeprom = {
817         .driver = {
818                 .name   = "tveeprom",
819         },
820         .id             = I2C_DRIVERID_TVEEPROM,
821         .attach_adapter = tveeprom_attach_adapter,
822         .detach_client  = tveeprom_detach_client,
823         .command        = tveeprom_command,
824 };
825
826 static int __init tveeprom_init(void)
827 {
828         return i2c_add_driver(&i2c_driver_tveeprom);
829 }
830
831 static void __exit tveeprom_exit(void)
832 {
833         i2c_del_driver(&i2c_driver_tveeprom);
834 }
835
836 module_init(tveeprom_init);
837 module_exit(tveeprom_exit);
838
839 /*
840  * Local variables:
841  * c-basic-offset: 8
842  * End:
843  */