[PATCH] v4l: 800: whitespace cleanups
[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 #ifndef I2C_DRIVERID_TVEEPROM
662 # define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
663 #endif
664
665 static unsigned short normal_i2c[] = {
666         0xa0 >> 1,
667         I2C_CLIENT_END,
668 };
669
670 I2C_CLIENT_INSMOD;
671
672 static struct i2c_driver i2c_driver_tveeprom;
673
674 static int
675 tveeprom_command(struct i2c_client *client,
676                  unsigned int       cmd,
677                  void              *arg)
678 {
679         struct tveeprom eeprom;
680         u32 *eeprom_props = arg;
681         u8 *buf;
682
683         switch (cmd) {
684         case 0:
685                 buf = kmalloc(256,GFP_KERNEL);
686                 memset(buf,0,256);
687                 tveeprom_read(client,buf,256);
688                 tveeprom_hauppauge_analog(client, &eeprom,buf);
689                 kfree(buf);
690                 eeprom_props[0] = eeprom.tuner_type;
691                 eeprom_props[1] = eeprom.tuner_formats;
692                 eeprom_props[2] = eeprom.model;
693                 eeprom_props[3] = eeprom.revision;
694                 eeprom_props[4] = eeprom.has_radio;
695                 break;
696         default:
697                 return -EINVAL;
698         }
699         return 0;
700 }
701
702 static int
703 tveeprom_detect_client(struct i2c_adapter *adapter,
704                        int                 address,
705                        int                 kind)
706 {
707         struct i2c_client *client;
708
709         client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
710         if (NULL == client)
711                 return -ENOMEM;
712         memset(client, 0, sizeof(struct i2c_client));
713         client->addr = address;
714         client->adapter = adapter;
715         client->driver = &i2c_driver_tveeprom;
716         client->flags = I2C_CLIENT_ALLOW_USE;
717         snprintf(client->name, sizeof(client->name), "tveeprom");
718         i2c_attach_client(client);
719         return 0;
720 }
721
722 static int
723 tveeprom_attach_adapter (struct i2c_adapter *adapter)
724 {
725         if (adapter->id != I2C_HW_B_BT848)
726                 return 0;
727         return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
728 }
729
730 static int
731 tveeprom_detach_client (struct i2c_client *client)
732 {
733         int err;
734
735         err = i2c_detach_client(client);
736         if (err < 0)
737                 return err;
738         kfree(client);
739         return 0;
740 }
741
742 static struct i2c_driver i2c_driver_tveeprom = {
743         .owner          = THIS_MODULE,
744         .name           = "tveeprom",
745         .id             = I2C_DRIVERID_TVEEPROM,
746         .flags          = I2C_DF_NOTIFY,
747         .attach_adapter = tveeprom_attach_adapter,
748         .detach_client  = tveeprom_detach_client,
749         .command        = tveeprom_command,
750 };
751
752 static int __init tveeprom_init(void)
753 {
754         return i2c_add_driver(&i2c_driver_tveeprom);
755 }
756
757 static void __exit tveeprom_exit(void)
758 {
759         i2c_del_driver(&i2c_driver_tveeprom);
760 }
761
762 module_init(tveeprom_init);
763 module_exit(tveeprom_exit);
764
765 /*
766  * Local variables:
767  * c-basic-offset: 8
768  * End:
769  */