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