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