[PATCH] V4L: Fixed eeprom handling for cx88 and added Nova-T PCI model 90003
[GitHub/mt8127/android_kernel_alcatel_ttab.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>
1f6173ed 43#include <media/audiochip.h>
1da177e4
LT
44
45MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
46MODULE_AUTHOR("John Klar");
47MODULE_LICENSE("GPL");
48
49static int debug = 0;
50module_param(debug, int, 0644);
0f97a931 51MODULE_PARM_DESC(debug, "Debug level (0-1)");
1da177e4
LT
52
53#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
54
0f97a931
MCC
55#define tveeprom_info(fmt, arg...) do {\
56 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
4ac97914 57 c->adapter->nr, c->addr , ##arg); } while (0)
0f97a931
MCC
58#define tveeprom_warn(fmt, arg...) do {\
59 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
4ac97914 60 c->adapter->nr, c->addr , ##arg); } while (0)
0f97a931
MCC
61#define tveeprom_dbg(fmt, arg...) do {\
62 if (debug) \
4ac97914
MCC
63 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
64 c->adapter->nr, c->addr , ##arg); } while (0)
1da177e4 65
1da177e4
LT
66
67/* ----------------------------------------------------------------------- */
68/* some hauppauge specific stuff */
69
70static struct HAUPPAUGE_TUNER_FMT
71{
72 int id;
73 char *name;
74}
75hauppauge_tuner_fmt[] =
76{
0f97a931
MCC
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)" },
3ca0ea98 84 { 0x03000000, " ATSC/DVB Digital" },
1da177e4
LT
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. */
91static struct HAUPPAUGE_TUNER
92{
93 int id;
94 char *name;
95}
96hauppauge_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" },
90a7ed47
MCC
138 { TUNER_PHILIPS_NTSC, "Philips TD1536" },
139 { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
1da177e4
LT
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"},
272435dc 159 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"},
1da177e4
LT
160 { TUNER_ABSENT, "Philips FI1236 MK3"},
161 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
793cf9e6 162 { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
1da177e4
LT
163 { TUNER_ABSENT, "Philips FM1216MP MK3"},
164 /* 60-69 */
793cf9e6 165 { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
1da177e4
LT
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"},
272435dc 174 { TUNER_LG_NTSC_TAPE, "LG TAPE H701F MK3"},
1da177e4
LT
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"},
793cf9e6
MCC
190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
191 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
1da177e4 192 { TUNER_TCL_2002N, "TCL 2002N 6A"},
90a7ed47 193 { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
1da177e4
LT
194 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
195 { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
fd3113e8 196 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
1da177e4
LT
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"},
20f441f6
HV
204 { TUNER_ABSENT, "Samsung TCPG_6121P30A"},
205 { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
90a7ed47
MCC
206 { TUNER_ABSENT, "TCL 2002MI_3H"},
207 { TUNER_TCL_2002N, "TCL 2002N 5H"},
20f441f6
HV
208 /* 100-109 */
209 { TUNER_ABSENT, "Philips FMD1216ME"},
90a7ed47
MCC
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"},
3ca0ea98
ST
219 /* 110-119 */
220 { TUNER_ABSENT, "Thompson DTT75105"},
221 { TUNER_ABSENT, "Conexant_CX24109"},
222 { TUNER_ABSENT, "TCL M2523_5N_E"},
223 { TUNER_ABSENT, "TCL M2523_3DB_E"},
224 { TUNER_ABSENT, "Philips 8275A"},
225 { TUNER_ABSENT, "Microtune MT2060"},
226 { TUNER_ABSENT, "Philips FM1236 MK5"},
227 { TUNER_ABSENT, "Philips FM1216ME MK5"},
228 { TUNER_ABSENT, "TCL M2523_3DI_E"},
229 { TUNER_ABSENT, "Samsung THPD5222FG30A"},
230 /* 120-129 */
231 { TUNER_ABSENT, "Xceive XC3028"},
232 { TUNER_ABSENT, "Philips FQ1216LME MK5"},
1da177e4
LT
233};
234
90a7ed47
MCC
235static struct HAUPPAUGE_AUDIOIC
236{
237 enum audiochip id;
238 char *name;
239}
240audioIC[] =
241{
242 /* 0-4 */
243 {AUDIO_CHIP_NONE, "None"},
244 {AUDIO_CHIP_TEA6300, "TEA6300"},
245 {AUDIO_CHIP_TEA6300, "TEA6320"},
246 {AUDIO_CHIP_TDA985X, "TDA9850"},
247 {AUDIO_CHIP_MSP34XX, "MSP3400C"},
248 /* 5-9 */
249 {AUDIO_CHIP_MSP34XX, "MSP3410D"},
250 {AUDIO_CHIP_MSP34XX, "MSP3415"},
251 {AUDIO_CHIP_MSP34XX, "MSP3430"},
252 {AUDIO_CHIP_UNKNOWN, "MSP3438"},
253 {AUDIO_CHIP_UNKNOWN, "CS5331"},
254 /* 10-14 */
255 {AUDIO_CHIP_MSP34XX, "MSP3435"},
256 {AUDIO_CHIP_MSP34XX, "MSP3440"},
257 {AUDIO_CHIP_MSP34XX, "MSP3445"},
258 {AUDIO_CHIP_UNKNOWN, "MSP3411"},
259 {AUDIO_CHIP_UNKNOWN, "MSP3416"},
260 /* 15-19 */
261 {AUDIO_CHIP_MSP34XX, "MSP3425"},
262 {AUDIO_CHIP_UNKNOWN, "MSP3451"},
263 {AUDIO_CHIP_UNKNOWN, "MSP3418"},
264 {AUDIO_CHIP_UNKNOWN, "Type 0x12"},
265 {AUDIO_CHIP_UNKNOWN, "OKI7716"},
266 /* 20-24 */
267 {AUDIO_CHIP_UNKNOWN, "MSP4410"},
268 {AUDIO_CHIP_UNKNOWN, "MSP4420"},
269 {AUDIO_CHIP_UNKNOWN, "MSP4440"},
270 {AUDIO_CHIP_UNKNOWN, "MSP4450"},
271 {AUDIO_CHIP_UNKNOWN, "MSP4408"},
272 /* 25-29 */
273 {AUDIO_CHIP_UNKNOWN, "MSP4418"},
274 {AUDIO_CHIP_UNKNOWN, "MSP4428"},
275 {AUDIO_CHIP_UNKNOWN, "MSP4448"},
276 {AUDIO_CHIP_UNKNOWN, "MSP4458"},
277 {AUDIO_CHIP_UNKNOWN, "Type 0x1d"},
278 /* 30-34 */
279 {AUDIO_CHIP_INTERNAL, "CX880"},
280 {AUDIO_CHIP_INTERNAL, "CX881"},
281 {AUDIO_CHIP_INTERNAL, "CX883"},
282 {AUDIO_CHIP_INTERNAL, "CX882"},
283 {AUDIO_CHIP_INTERNAL, "CX25840"},
284 /* 35-38 */
285 {AUDIO_CHIP_INTERNAL, "CX25841"},
286 {AUDIO_CHIP_INTERNAL, "CX25842"},
287 {AUDIO_CHIP_INTERNAL, "CX25843"},
288 {AUDIO_CHIP_INTERNAL, "CX23418"},
0f97a931 289};
1da177e4 290
0f97a931
MCC
291/* This list is supplied by Hauppauge. Thanks! */
292static const char *decoderIC[] = {
90a7ed47
MCC
293 /* 0-4 */
294 "None", "BT815", "BT817", "BT819", "BT815A",
295 /* 5-9 */
296 "BT817A", "BT819A", "BT827", "BT829", "BT848",
297 /* 10-14 */
298 "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
299 /* 15-19 */
300 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
301 /* 20-24 */
302 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
303 /* 25-29 */
304 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
305 /* 30-31 */
306 "CX25843", "CX23418",
1da177e4
LT
307};
308
309static int hasRadioTuner(int tunerType)
310{
4ac97914 311 switch (tunerType) {
90a7ed47
MCC
312 case 18: //PNPEnv_TUNER_FR1236_MK2:
313 case 23: //PNPEnv_TUNER_FM1236:
314 case 38: //PNPEnv_TUNER_FMR1236:
315 case 16: //PNPEnv_TUNER_FR1216_MK2:
316 case 19: //PNPEnv_TUNER_FR1246_MK2:
317 case 21: //PNPEnv_TUNER_FM1216:
318 case 24: //PNPEnv_TUNER_FM1246:
319 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
320 case 22: //PNPEnv_TUNER_FM1216MF:
321 case 20: //PNPEnv_TUNER_FR1256_MK2:
322 case 25: //PNPEnv_TUNER_FM1256:
323 case 33: //PNPEnv_TUNER_4039FR5:
324 case 42: //PNPEnv_TUNER_4009FR5:
325 case 52: //PNPEnv_TUNER_4049FM5:
326 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
327 case 44: //PNPEnv_TUNER_4009FN5:
328 case 31: //PNPEnv_TUNER_TCPB9085P:
329 case 30: //PNPEnv_TUNER_TCPN9085D:
330 case 46: //PNPEnv_TUNER_TP18NSR01F:
331 case 47: //PNPEnv_TUNER_TP18PSB01D:
332 case 49: //PNPEnv_TUNER_TAPC_I001D:
333 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
334 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
335 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
336 case 58: //PNPEnv_TUNER_FM1236_MK3:
337 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
338 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
339 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
340 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
341 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
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 */
389 else if (((eeprom_data[0] & 0xf0) == 0x10) &&
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
599 tvee->tuner_formats = 0;
0f97a931
MCC
600 tvee->tuner2_formats = 0;
601 for (i = j = 0; i < 8; i++) {
602 if (t_format1 & (1 << i)) {
1da177e4 603 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
0f97a931 604 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
1da177e4 605 }
90a7ed47
MCC
606 if (t_format2 & (1 << i)) {
607 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
608 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
609 }
1da177e4
LT
610 }
611
0f97a931 612 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
90a7ed47 613 tvee->model, tvee->rev_str, tvee->serial_number);
3ca0ea98
ST
614 if (tvee->has_MAC_address == 1) {
615 tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n",
616 tvee->MAC_address[0], tvee->MAC_address[1],
617 tvee->MAC_address[2], tvee->MAC_address[3],
618 tvee->MAC_address[4], tvee->MAC_address[5]);
619 }
0f97a931 620 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
90a7ed47 621 t_name1, tuner1, tvee->tuner_type);
0f97a931 622 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
90a7ed47
MCC
623 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
624 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
625 t_format1);
626 if (tuner2) {
627 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
628 t_name2, tuner2, tvee->tuner2_type);
629 }
630 if (t_format2) {
631 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
632 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
633 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
634 t_format2);
635 }
636 if (audioic<0) {
637 tveeprom_info("audio processor is unknown (no idx)\n");
638 tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
639 } else {
640 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
641 tveeprom_info("audio processor is %s (idx %d)\n",
642 audioIC[audioic].name,audioic);
643 else
644 tveeprom_info("audio processor is unknown (idx %d)\n",
645 audioic);
646 }
647 if (tvee->decoder_processor) {
648 tveeprom_info("decoder processor is %s (idx %d)\n",
649 STRM(decoderIC, tvee->decoder_processor),
650 tvee->decoder_processor);
651 }
652 if (tvee->has_ir == 2)
653 tveeprom_info("has %sradio\n",
654 tvee->has_radio ? "" : "no ");
655 else
656 tveeprom_info("has %sradio, has %sIR remote\n",
657 tvee->has_radio ? "" : "no ",
658 tvee->has_ir ? "" : "no ");
1da177e4
LT
659}
660EXPORT_SYMBOL(tveeprom_hauppauge_analog);
661
662/* ----------------------------------------------------------------------- */
663/* generic helper functions */
664
665int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
666{
667 unsigned char buf;
668 int err;
669
1da177e4 670 buf = 0;
0f97a931
MCC
671 if (1 != (err = i2c_master_send(c, &buf, 1))) {
672 tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
1da177e4
LT
673 return -1;
674 }
0f97a931
MCC
675 if (len != (err = i2c_master_recv(c, eedata, len))) {
676 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
1da177e4
LT
677 return -1;
678 }
90a7ed47
MCC
679 if (debug) {
680 int i;
681
682 tveeprom_info("full 256-byte eeprom dump:\n");
683 for (i = 0; i < len; i++) {
684 if (0 == (i % 16))
685 tveeprom_info("%02x:", i);
686 printk(" %02x", eedata[i]);
687 if (15 == (i % 16))
688 printk("\n");
689 }
690 }
1da177e4
LT
691 return 0;
692}
693EXPORT_SYMBOL(tveeprom_read);
694
1da177e4
LT
695/* ----------------------------------------------------------------------- */
696/* needed for ivtv.sf.net at the moment. Should go away in the long */
697/* run, just call the exported tveeprom_* directly, there is no point in */
698/* using the indirect way via i2c_driver->command() */
699
1da177e4
LT
700static unsigned short normal_i2c[] = {
701 0xa0 >> 1,
702 I2C_CLIENT_END,
703};
833e9a1a 704
1da177e4
LT
705I2C_CLIENT_INSMOD;
706
82ee3e6f 707static struct i2c_driver i2c_driver_tveeprom;
1da177e4
LT
708
709static int
710tveeprom_command(struct i2c_client *client,
711 unsigned int cmd,
712 void *arg)
713{
714 struct tveeprom eeprom;
715 u32 *eeprom_props = arg;
716 u8 *buf;
717
718 switch (cmd) {
719 case 0:
720 buf = kmalloc(256,GFP_KERNEL);
721 memset(buf,0,256);
722 tveeprom_read(client,buf,256);
0f97a931 723 tveeprom_hauppauge_analog(client, &eeprom,buf);
1da177e4
LT
724 kfree(buf);
725 eeprom_props[0] = eeprom.tuner_type;
726 eeprom_props[1] = eeprom.tuner_formats;
727 eeprom_props[2] = eeprom.model;
728 eeprom_props[3] = eeprom.revision;
272435dc 729 eeprom_props[4] = eeprom.has_radio;
1da177e4
LT
730 break;
731 default:
732 return -EINVAL;
733 }
734 return 0;
735}
736
737static int
738tveeprom_detect_client(struct i2c_adapter *adapter,
739 int address,
740 int kind)
741{
742 struct i2c_client *client;
743
1da177e4
LT
744 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
745 if (NULL == client)
746 return -ENOMEM;
747 memset(client, 0, sizeof(struct i2c_client));
748 client->addr = address;
749 client->adapter = adapter;
750 client->driver = &i2c_driver_tveeprom;
751 client->flags = I2C_CLIENT_ALLOW_USE;
752 snprintf(client->name, sizeof(client->name), "tveeprom");
753 i2c_attach_client(client);
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 = {
1da177e4
LT
778 .owner = THIS_MODULE,
779 .name = "tveeprom",
780 .id = I2C_DRIVERID_TVEEPROM,
781 .flags = I2C_DF_NOTIFY,
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 */