V4L/DVB (4816): Change tuner type for Avermedia A16AR
[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{
3407e387
MCC
76 { V4L2_STD_UNKNOWN, " UNKNOWN" },
77 { V4L2_STD_UNKNOWN, " FM" },
78 { V4L2_STD_B|V4L2_STD_GH, " PAL(B/G)" },
79 { V4L2_STD_MN, " NTSC(M)" },
80 { V4L2_STD_PAL_I, " PAL(I)" },
81 { V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, " SECAM(L/L')" },
82 { V4L2_STD_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"},
c344933a 203 { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"},
20f441f6 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"},
7157e2b6 221 { TUNER_TCL_2002N, "TCL M2523_5N_E"},
00819f87 222 { TUNER_TCL_2002MB, "TCL M2523_3DB_E"},
3ca0ea98
ST
223 { TUNER_ABSENT, "Philips 8275A"},
224 { TUNER_ABSENT, "Microtune MT2060"},
003138cf
HV
225 { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK5"},
226 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216ME MK5"},
3ca0ea98
ST
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 }
18795eb9
TP
608 }
609 for (i = j = 0; i < 8; i++) {
90a7ed47
MCC
610 if (t_format2 & (1 << i)) {
611 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
612 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
613 }
1da177e4
LT
614 }
615
0f97a931 616 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
90a7ed47 617 tvee->model, tvee->rev_str, tvee->serial_number);
3ca0ea98
ST
618 if (tvee->has_MAC_address == 1) {
619 tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n",
620 tvee->MAC_address[0], tvee->MAC_address[1],
621 tvee->MAC_address[2], tvee->MAC_address[3],
622 tvee->MAC_address[4], tvee->MAC_address[5]);
623 }
0f97a931 624 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
90a7ed47 625 t_name1, tuner1, tvee->tuner_type);
0f97a931 626 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
90a7ed47
MCC
627 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
628 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
629 t_format1);
630 if (tuner2) {
631 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
632 t_name2, tuner2, tvee->tuner2_type);
633 }
634 if (t_format2) {
635 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
636 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
637 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
638 t_format2);
639 }
640 if (audioic<0) {
641 tveeprom_info("audio processor is unknown (no idx)\n");
642 tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
643 } else {
644 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
645 tveeprom_info("audio processor is %s (idx %d)\n",
646 audioIC[audioic].name,audioic);
647 else
648 tveeprom_info("audio processor is unknown (idx %d)\n",
649 audioic);
650 }
651 if (tvee->decoder_processor) {
652 tveeprom_info("decoder processor is %s (idx %d)\n",
653 STRM(decoderIC, tvee->decoder_processor),
654 tvee->decoder_processor);
655 }
656 if (tvee->has_ir == 2)
657 tveeprom_info("has %sradio\n",
658 tvee->has_radio ? "" : "no ");
659 else
660 tveeprom_info("has %sradio, has %sIR remote\n",
661 tvee->has_radio ? "" : "no ",
662 tvee->has_ir ? "" : "no ");
1da177e4
LT
663}
664EXPORT_SYMBOL(tveeprom_hauppauge_analog);
665
666/* ----------------------------------------------------------------------- */
667/* generic helper functions */
668
669int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
670{
671 unsigned char buf;
672 int err;
673
1da177e4 674 buf = 0;
0f97a931
MCC
675 if (1 != (err = i2c_master_send(c, &buf, 1))) {
676 tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
1da177e4
LT
677 return -1;
678 }
0f97a931
MCC
679 if (len != (err = i2c_master_recv(c, eedata, len))) {
680 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
1da177e4
LT
681 return -1;
682 }
90a7ed47
MCC
683 if (debug) {
684 int i;
685
686 tveeprom_info("full 256-byte eeprom dump:\n");
687 for (i = 0; i < len; i++) {
688 if (0 == (i % 16))
689 tveeprom_info("%02x:", i);
690 printk(" %02x", eedata[i]);
691 if (15 == (i % 16))
692 printk("\n");
693 }
694 }
1da177e4
LT
695 return 0;
696}
697EXPORT_SYMBOL(tveeprom_read);
698
1da177e4
LT
699/* ----------------------------------------------------------------------- */
700/* needed for ivtv.sf.net at the moment. Should go away in the long */
701/* run, just call the exported tveeprom_* directly, there is no point in */
702/* using the indirect way via i2c_driver->command() */
703
1da177e4
LT
704static unsigned short normal_i2c[] = {
705 0xa0 >> 1,
706 I2C_CLIENT_END,
707};
833e9a1a 708
1da177e4
LT
709I2C_CLIENT_INSMOD;
710
82ee3e6f 711static struct i2c_driver i2c_driver_tveeprom;
1da177e4
LT
712
713static int
714tveeprom_command(struct i2c_client *client,
715 unsigned int cmd,
716 void *arg)
717{
718 struct tveeprom eeprom;
719 u32 *eeprom_props = arg;
720 u8 *buf;
721
722 switch (cmd) {
723 case 0:
7408187d 724 buf = kzalloc(256,GFP_KERNEL);
1da177e4 725 tveeprom_read(client,buf,256);
0f97a931 726 tveeprom_hauppauge_analog(client, &eeprom,buf);
1da177e4
LT
727 kfree(buf);
728 eeprom_props[0] = eeprom.tuner_type;
729 eeprom_props[1] = eeprom.tuner_formats;
730 eeprom_props[2] = eeprom.model;
731 eeprom_props[3] = eeprom.revision;
272435dc 732 eeprom_props[4] = eeprom.has_radio;
1da177e4
LT
733 break;
734 default:
735 return -EINVAL;
736 }
737 return 0;
738}
739
740static int
741tveeprom_detect_client(struct i2c_adapter *adapter,
742 int address,
743 int kind)
744{
745 struct i2c_client *client;
746
7408187d 747 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
1da177e4
LT
748 if (NULL == client)
749 return -ENOMEM;
1da177e4
LT
750 client->addr = address;
751 client->adapter = adapter;
752 client->driver = &i2c_driver_tveeprom;
1da177e4 753 snprintf(client->name, sizeof(client->name), "tveeprom");
afd1a0c9 754 i2c_attach_client(client);
674434c6 755
1da177e4
LT
756 return 0;
757}
758
759static int
760tveeprom_attach_adapter (struct i2c_adapter *adapter)
761{
51dab14e
HV
762 if (adapter->class & I2C_CLASS_TV_ANALOG)
763 return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
764 return 0;
1da177e4
LT
765}
766
767static int
768tveeprom_detach_client (struct i2c_client *client)
769{
770 int err;
771
772 err = i2c_detach_client(client);
773 if (err < 0)
774 return err;
775 kfree(client);
776 return 0;
777}
778
82ee3e6f 779static struct i2c_driver i2c_driver_tveeprom = {
604f28e2 780 .driver = {
604f28e2
LR
781 .name = "tveeprom",
782 },
1da177e4 783 .id = I2C_DRIVERID_TVEEPROM,
1da177e4
LT
784 .attach_adapter = tveeprom_attach_adapter,
785 .detach_client = tveeprom_detach_client,
786 .command = tveeprom_command,
787};
788
789static int __init tveeprom_init(void)
790{
791 return i2c_add_driver(&i2c_driver_tveeprom);
792}
793
794static void __exit tveeprom_exit(void)
795{
796 i2c_del_driver(&i2c_driver_tveeprom);
797}
798
799module_init(tveeprom_init);
800module_exit(tveeprom_exit);
801
802/*
803 * Local variables:
804 * c-basic-offset: 8
805 * End:
806 */