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/v4l2-common.h>
44#include <media/audiochip.h>
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);
52MODULE_PARM_DESC(debug, "Debug level (0-1)");
53
54#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
55
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 { \
61	if (debug) \
62		v4l_printk(KERN_DEBUG, "tveeprom", c->adapter, c->addr, fmt , ## arg); \
63	} while (0)
64
65/*
66 * The Hauppauge eeprom uses an 8bit field to determine which
67 * tuner formats the tuner supports.
68 */
69static struct HAUPPAUGE_TUNER_FMT
70{
71	int	id;
72	char *name;
73}
74hauppauge_tuner_fmt[] =
75{
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" },
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" },
137	{ TUNER_PHILIPS_NTSC,        "Philips TD1536" },
138	{ TUNER_PHILIPS_NTSC,        "Philips TD1536D" },
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"},
158	{ TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"},
159	{ TUNER_ABSENT,        "Philips FI1236 MK3"},
160	{ TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
161	{ TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
162	{ TUNER_ABSENT,        "Philips FM1216MP MK3"},
163	/* 60-69 */
164	{ TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
165	{ TUNER_ABSENT,        "LG M001D MK3"},
166	{ TUNER_PHILIPS_FM1216ME_MK3, "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"},
173	{ TUNER_LG_NTSC_TAPE,  "LG TAPE H701F MK3"},
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_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
188	{ TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
189	{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
190	{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
191	{ TUNER_TCL_2002N,     "TCL 2002N 6A"},
192	{ TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
193	{ TUNER_SAMSUNG_TCPN_2121P30A, "Samsung TCPN 2121P30A"},
194	{ TUNER_ABSENT,        "Samsung TCPE 4121P30A"},
195	{ TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
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"},
203	{ TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"},
204	{ TUNER_TCL_2002MB,    "TCL 2002MB_3H"},
205	{ TUNER_ABSENT,        "TCL 2002MI_3H"},
206	{ TUNER_TCL_2002N,     "TCL 2002N 5H"},
207	/* 100-109 */
208	{ TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216ME"},
209	{ TUNER_TEA5767,       "Philips TEA5768HL FM Radio"},
210	{ TUNER_ABSENT,        "Panasonic ENV57H12D5"},
211	{ TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
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"},
218	/* 110-119 */
219	{ TUNER_ABSENT,        "Thompson DTT75105"},
220	{ TUNER_ABSENT,        "Conexant_CX24109"},
221	{ TUNER_TCL_2002N,     "TCL M2523_5N_E"},
222	{ TUNER_TCL_2002MB,    "TCL M2523_3DB_E"},
223	{ TUNER_ABSENT,        "Philips 8275A"},
224	{ TUNER_ABSENT,        "Microtune MT2060"},
225	{ TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK5"},
226	{ TUNER_PHILIPS_FM1216ME_MK3, "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"},
232	{ TUNER_ABSENT,        "Philips FQD1216LME"},
233	{ TUNER_ABSENT,        "Conexant CX24118A"},
234	{ TUNER_ABSENT,        "TCL DMF11WIP"},
235	{ TUNER_ABSENT,        "TCL MFNM05_4H_E"},
236	{ TUNER_ABSENT,        "TCL MNM05_4H_E"},
237	{ TUNER_ABSENT,        "TCL MPE05_2H_E"},
238	{ TUNER_ABSENT,        "TCL MQNM05_4_U"},
239	{ TUNER_ABSENT,        "TCL M2523_5NH_E"},
240	/* 130-139 */
241	{ TUNER_ABSENT,        "TCL M2523_3DBH_E"},
242	{ TUNER_ABSENT,        "TCL M2523_3DIH_E"},
243	{ TUNER_ABSENT,        "TCL MFPE05_2_U"},
244	{ TUNER_ABSENT,        "Philips FMD1216MEX"},
245	{ TUNER_ABSENT,        "Philips FRH2036B"},
246	{ TUNER_ABSENT,        "Panasonic ENGF75_01GF"},
247	{ TUNER_ABSENT,        "MaxLinear MXL5005"},
248	{ TUNER_ABSENT,        "MaxLinear MXL5003"},
249	{ TUNER_ABSENT,        "Xceive XC2028"},
250	{ TUNER_ABSENT,        "Microtune MT2131"},
251	/* 140-149 */
252	{ TUNER_ABSENT,        "Philips 8275A_8295"},
253	{ TUNER_ABSENT,        "TCL MF02GIP_5N_E"},
254	{ TUNER_ABSENT,        "TCL MF02GIP_3DB_E"},
255	{ TUNER_ABSENT,        "TCL MF02GIP_3DI_E"},
256	{ TUNER_ABSENT,        "Microtune MT2266"},
257	{ TUNER_ABSENT,        "TCL MF10WPP_4N_E"},
258	{ TUNER_ABSENT,        "LG TAPQ_H702F"},
259	{ TUNER_ABSENT,        "TCL M09WPP_4N_E"},
260	{ TUNER_ABSENT,        "MaxLinear MXL5005_v2"},
261	{ TUNER_ABSENT,        "Philips 18271_8295"},
262};
263
264static struct HAUPPAUGE_AUDIOIC
265{
266	enum audiochip  id;
267	char *name;
268}
269audioIC[] =
270{
271	/* 0-4 */
272	{AUDIO_CHIP_NONE,     "None"},
273	{AUDIO_CHIP_TEA6300,  "TEA6300"},
274	{AUDIO_CHIP_TEA6300,  "TEA6320"},
275	{AUDIO_CHIP_TDA985X,  "TDA9850"},
276	{AUDIO_CHIP_MSP34XX,  "MSP3400C"},
277	/* 5-9 */
278	{AUDIO_CHIP_MSP34XX,  "MSP3410D"},
279	{AUDIO_CHIP_MSP34XX,  "MSP3415"},
280	{AUDIO_CHIP_MSP34XX,  "MSP3430"},
281	{AUDIO_CHIP_MSP34XX,  "MSP3438"},
282	{AUDIO_CHIP_UNKNOWN,  "CS5331"},
283	/* 10-14 */
284	{AUDIO_CHIP_MSP34XX,  "MSP3435"},
285	{AUDIO_CHIP_MSP34XX,  "MSP3440"},
286	{AUDIO_CHIP_MSP34XX,  "MSP3445"},
287	{AUDIO_CHIP_MSP34XX,  "MSP3411"},
288	{AUDIO_CHIP_MSP34XX,  "MSP3416"},
289	/* 15-19 */
290	{AUDIO_CHIP_MSP34XX,  "MSP3425"},
291	{AUDIO_CHIP_MSP34XX,  "MSP3451"},
292	{AUDIO_CHIP_MSP34XX,  "MSP3418"},
293	{AUDIO_CHIP_UNKNOWN,  "Type 0x12"},
294	{AUDIO_CHIP_UNKNOWN,  "OKI7716"},
295	/* 20-24 */
296	{AUDIO_CHIP_MSP34XX,  "MSP4410"},
297	{AUDIO_CHIP_MSP34XX,  "MSP4420"},
298	{AUDIO_CHIP_MSP34XX,  "MSP4440"},
299	{AUDIO_CHIP_MSP34XX,  "MSP4450"},
300	{AUDIO_CHIP_MSP34XX,  "MSP4408"},
301	/* 25-29 */
302	{AUDIO_CHIP_MSP34XX,  "MSP4418"},
303	{AUDIO_CHIP_MSP34XX,  "MSP4428"},
304	{AUDIO_CHIP_MSP34XX,  "MSP4448"},
305	{AUDIO_CHIP_MSP34XX,  "MSP4458"},
306	{AUDIO_CHIP_MSP34XX,  "Type 0x1d"},
307	/* 30-34 */
308	{AUDIO_CHIP_INTERNAL, "CX880"},
309	{AUDIO_CHIP_INTERNAL, "CX881"},
310	{AUDIO_CHIP_INTERNAL, "CX883"},
311	{AUDIO_CHIP_INTERNAL, "CX882"},
312	{AUDIO_CHIP_INTERNAL, "CX25840"},
313	/* 35-39 */
314	{AUDIO_CHIP_INTERNAL, "CX25841"},
315	{AUDIO_CHIP_INTERNAL, "CX25842"},
316	{AUDIO_CHIP_INTERNAL, "CX25843"},
317	{AUDIO_CHIP_INTERNAL, "CX23418"},
318	{AUDIO_CHIP_INTERNAL, "CX23885"},
319	/* 40-42 */
320	{AUDIO_CHIP_INTERNAL, "CX23888"},
321	{AUDIO_CHIP_INTERNAL, "SAA7131"},
322	{AUDIO_CHIP_INTERNAL, "CX23887"},
323};
324
325/* This list is supplied by Hauppauge. Thanks! */
326static const char *decoderIC[] = {
327	/* 0-4 */
328	"None", "BT815", "BT817", "BT819", "BT815A",
329	/* 5-9 */
330	"BT817A", "BT819A", "BT827", "BT829", "BT848",
331	/* 10-14 */
332	"BT848A", "BT849A", "BT829A", "BT827A", "BT878",
333	/* 15-19 */
334	"BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
335	/* 20-24 */
336	"CX880", "CX881", "CX883", "SAA7111", "SAA7113",
337	/* 25-29 */
338	"CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
339	/* 30-34 */
340	"CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
341	/* 35-37 */
342	"SAA7131", "CX25837", "CX23887"
343};
344
345static int hasRadioTuner(int tunerType)
346{
347	switch (tunerType) {
348		case 18: //PNPEnv_TUNER_FR1236_MK2:
349		case 23: //PNPEnv_TUNER_FM1236:
350		case 38: //PNPEnv_TUNER_FMR1236:
351		case 16: //PNPEnv_TUNER_FR1216_MK2:
352		case 19: //PNPEnv_TUNER_FR1246_MK2:
353		case 21: //PNPEnv_TUNER_FM1216:
354		case 24: //PNPEnv_TUNER_FM1246:
355		case 17: //PNPEnv_TUNER_FR1216MF_MK2:
356		case 22: //PNPEnv_TUNER_FM1216MF:
357		case 20: //PNPEnv_TUNER_FR1256_MK2:
358		case 25: //PNPEnv_TUNER_FM1256:
359		case 33: //PNPEnv_TUNER_4039FR5:
360		case 42: //PNPEnv_TUNER_4009FR5:
361		case 52: //PNPEnv_TUNER_4049FM5:
362		case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
363		case 44: //PNPEnv_TUNER_4009FN5:
364		case 31: //PNPEnv_TUNER_TCPB9085P:
365		case 30: //PNPEnv_TUNER_TCPN9085D:
366		case 46: //PNPEnv_TUNER_TP18NSR01F:
367		case 47: //PNPEnv_TUNER_TP18PSB01D:
368		case 49: //PNPEnv_TUNER_TAPC_I001D:
369		case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
370		case 57: //PNPEnv_TUNER_FM1216ME_MK3:
371		case 59: //PNPEnv_TUNER_FM1216MP_MK3:
372		case 58: //PNPEnv_TUNER_FM1236_MK3:
373		case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
374		case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
375		case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
376		case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
377		case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
378		case 105:
379		return 1;
380	}
381	return 0;
382}
383
384void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
385				unsigned char *eeprom_data)
386{
387	/* ----------------------------------------------
388	** The hauppauge eeprom format is tagged
389	**
390	** if packet[0] == 0x84, then packet[0..1] == length
391	** else length = packet[0] & 3f;
392	** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
393	**
394	** In our (ivtv) case we're interested in the following:
395	** tuner type:   tag [00].05 or [0a].01 (index into hauppauge_tuner)
396	** tuner fmts:   tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt)
397	** radio:        tag [00].{last} or [0e].00  (bitmask.  bit2=FM)
398	** audio proc:   tag [02].01 or [05].00 (mask with 0x7f)
399	** decoder proc: tag [09].01)
400
401	** Fun info:
402	** model:      tag [00].07-08 or [06].00-01
403	** revision:   tag [00].09-0b or [06].04-06
404	** serial#:    tag [01].05-07 or [04].04-06
405
406	** # of inputs/outputs ???
407	*/
408
409	int i, j, len, done, beenhere, tag,start;
410
411	int tuner1 = 0, t_format1 = 0, audioic=-1;
412	char *t_name1 = NULL;
413	const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
414
415	int tuner2 = 0, t_format2 = 0;
416	char *t_name2 = NULL;
417	const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
418
419	memset(tvee, 0, sizeof(*tvee));
420	done = len = beenhere = 0;
421
422	/* Hack for processing eeprom for em28xx and cx 2388x*/
423	if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) &&
424			(eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95))
425		start=0xa0; /* Generic em28xx offset */
426	else if (((eeprom_data[0] & 0xe1) == 0x01) &&
427					(eeprom_data[1] == 0x00) &&
428					(eeprom_data[2] == 0x00) &&
429					(eeprom_data[8] == 0x84))
430		start=8; /* Generic cx2388x offset */
431	else
432		start=0;
433
434	for (i = start; !done && i < 256; i += len) {
435		if (eeprom_data[i] == 0x84) {
436			len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
437			i += 3;
438		} else if ((eeprom_data[i] & 0xf0) == 0x70) {
439			if (eeprom_data[i] & 0x08) {
440				/* verify checksum! */
441				done = 1;
442				break;
443			}
444			len = eeprom_data[i] & 0x07;
445			++i;
446		} else {
447			tveeprom_warn("Encountered bad packet header [%02x]. "
448				"Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
449			return;
450		}
451
452		if (debug) {
453			tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
454			for(j = 1; j < len; j++) {
455				printk(" %02x", eeprom_data[i + j]);
456			}
457			printk("\n");
458		}
459
460		/* process by tag */
461		tag = eeprom_data[i];
462		switch (tag) {
463		case 0x00:
464			/* tag: 'Comprehensive' */
465			tuner1 = eeprom_data[i+6];
466			t_format1 = eeprom_data[i+5];
467			tvee->has_radio = eeprom_data[i+len-1];
468			/* old style tag, don't know how to detect
469			IR presence, mark as unknown. */
470			tvee->has_ir = -1;
471			tvee->model =
472				eeprom_data[i+8] +
473				(eeprom_data[i+9] << 8);
474			tvee->revision = eeprom_data[i+10] +
475				(eeprom_data[i+11] << 8) +
476				(eeprom_data[i+12] << 16);
477			break;
478
479		case 0x01:
480			/* tag: 'SerialID' */
481			tvee->serial_number =
482				eeprom_data[i+6] +
483				(eeprom_data[i+7] << 8) +
484				(eeprom_data[i+8] << 16);
485			break;
486
487		case 0x02:
488			/* tag 'AudioInfo'
489			Note mask with 0x7F, high bit used on some older models
490			to indicate 4052 mux was removed in favor of using MSP
491			inputs directly. */
492			audioic = eeprom_data[i+2] & 0x7f;
493			if (audioic < sizeof(audioIC)/sizeof(*audioIC))
494				tvee->audio_processor = audioIC[audioic].id;
495			else
496				tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
497			break;
498
499		/* case 0x03: tag 'EEInfo' */
500
501		case 0x04:
502			/* tag 'SerialID2' */
503			tvee->serial_number =
504				eeprom_data[i+5] +
505				(eeprom_data[i+6] << 8) +
506				(eeprom_data[i+7] << 16);
507
508				if ( (eeprom_data[i + 8] & 0xf0) &&
509					(tvee->serial_number < 0xffffff) ) {
510					tvee->MAC_address[0] = 0x00;
511					tvee->MAC_address[1] = 0x0D;
512					tvee->MAC_address[2] = 0xFE;
513					tvee->MAC_address[3] = eeprom_data[i + 7];
514					tvee->MAC_address[4] = eeprom_data[i + 6];
515					tvee->MAC_address[5] = eeprom_data[i + 5];
516					tvee->has_MAC_address = 1;
517				}
518			break;
519
520		case 0x05:
521			/* tag 'Audio2'
522			Note mask with 0x7F, high bit used on some older models
523			to indicate 4052 mux was removed in favor of using MSP
524			inputs directly. */
525			audioic = eeprom_data[i+1] & 0x7f;
526			if (audioic < sizeof(audioIC)/sizeof(*audioIC))
527				tvee->audio_processor = audioIC[audioic].id;
528			else
529				tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
530
531			break;
532
533		case 0x06:
534			/* tag 'ModelRev' */
535			tvee->model =
536				eeprom_data[i + 1] +
537				(eeprom_data[i + 2] << 8) +
538				(eeprom_data[i + 3] << 16) +
539				(eeprom_data[i + 4] << 24);
540			tvee->revision =
541				eeprom_data[i +5 ] +
542				(eeprom_data[i + 6] << 8) +
543				(eeprom_data[i + 7] << 16);
544			break;
545
546		case 0x07:
547			/* tag 'Details': according to Hauppauge not interesting
548			on any PCI-era or later boards. */
549			break;
550
551		/* there is no tag 0x08 defined */
552
553		case 0x09:
554			/* tag 'Video' */
555			tvee->decoder_processor = eeprom_data[i + 1];
556			break;
557
558		case 0x0a:
559			/* tag 'Tuner' */
560			if (beenhere == 0) {
561				tuner1 = eeprom_data[i+2];
562				t_format1 = eeprom_data[i+1];
563				beenhere = 1;
564			} else {
565				/* a second (radio) tuner may be present */
566				tuner2 = eeprom_data[i+2];
567				t_format2 = eeprom_data[i+1];
568				if (t_format2 == 0) {  /* not a TV tuner? */
569					tvee->has_radio = 1; /* must be radio */
570				}
571			}
572			break;
573
574		case 0x0b:
575			/* tag 'Inputs': according to Hauppauge this is specific
576			to each driver family, so no good assumptions can be
577			made. */
578			break;
579
580		/* case 0x0c: tag 'Balun' */
581		/* case 0x0d: tag 'Teletext' */
582
583		case 0x0e:
584			/* tag: 'Radio' */
585			tvee->has_radio = eeprom_data[i+1];
586			break;
587
588		case 0x0f:
589			/* tag 'IRInfo' */
590			tvee->has_ir = eeprom_data[i+1];
591			break;
592
593		/* case 0x10: tag 'VBIInfo' */
594		/* case 0x11: tag 'QCInfo' */
595		/* case 0x12: tag 'InfoBits' */
596
597		default:
598			tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
599			/* dump the rest of the packet? */
600		}
601	}
602
603	if (!done) {
604		tveeprom_warn("Ran out of data!\n");
605		return;
606	}
607
608	if (tvee->revision != 0) {
609		tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
610		tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
611		tvee->rev_str[2] = 32 + ((tvee->revision >>  6) & 0x3f);
612		tvee->rev_str[3] = 32 + ( tvee->revision        & 0x3f);
613		tvee->rev_str[4] = 0;
614	}
615
616	if (hasRadioTuner(tuner1) && !tvee->has_radio) {
617		tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
618		tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
619		tvee->has_radio = 1;
620	}
621
622	if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
623		tvee->tuner_type = hauppauge_tuner[tuner1].id;
624		t_name1 = hauppauge_tuner[tuner1].name;
625	} else {
626		t_name1 = "unknown";
627	}
628
629	if (tuner2 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
630		tvee->tuner2_type = hauppauge_tuner[tuner2].id;
631		t_name2 = hauppauge_tuner[tuner2].name;
632	} else {
633		t_name2 = "unknown";
634	}
635
636	tvee->tuner_hauppauge_model = tuner1;
637	tvee->tuner2_hauppauge_model = tuner2;
638	tvee->tuner_formats = 0;
639	tvee->tuner2_formats = 0;
640	for (i = j = 0; i < 8; i++) {
641		if (t_format1 & (1 << i)) {
642			tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
643			t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
644		}
645	}
646	for (i = j = 0; i < 8; i++) {
647		if (t_format2 & (1 << i)) {
648			tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
649			t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
650		}
651	}
652
653	tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
654		tvee->model, tvee->rev_str, tvee->serial_number);
655	if (tvee->has_MAC_address == 1) {
656		tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n",
657			tvee->MAC_address[0], tvee->MAC_address[1],
658			tvee->MAC_address[2], tvee->MAC_address[3],
659			tvee->MAC_address[4], tvee->MAC_address[5]);
660	}
661	tveeprom_info("tuner model is %s (idx %d, type %d)\n",
662		t_name1, tuner1, tvee->tuner_type);
663	tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
664		t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
665		t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
666		t_format1);
667	if (tuner2) {
668		tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
669					t_name2, tuner2, tvee->tuner2_type);
670	}
671	if (t_format2) {
672		tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
673			t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
674			t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
675			t_format2);
676	}
677	if (audioic<0) {
678		tveeprom_info("audio processor is unknown (no idx)\n");
679		tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
680	} else {
681		if (audioic < sizeof(audioIC)/sizeof(*audioIC))
682			tveeprom_info("audio processor is %s (idx %d)\n",
683					audioIC[audioic].name,audioic);
684		else
685			tveeprom_info("audio processor is unknown (idx %d)\n",
686								audioic);
687	}
688	if (tvee->decoder_processor) {
689		tveeprom_info("decoder processor is %s (idx %d)\n",
690			STRM(decoderIC, tvee->decoder_processor),
691			tvee->decoder_processor);
692	}
693	if (tvee->has_ir == -1)
694		tveeprom_info("has %sradio\n",
695				tvee->has_radio ? "" : "no ");
696	else
697		tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
698				tvee->has_radio ? "" : "no ",
699				(tvee->has_ir & 1) ? "" : "no ",
700				(tvee->has_ir & 2) ? "" : "no ");
701}
702EXPORT_SYMBOL(tveeprom_hauppauge_analog);
703
704/* ----------------------------------------------------------------------- */
705/* generic helper functions                                                */
706
707int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
708{
709	unsigned char buf;
710	int err;
711
712	buf = 0;
713	if (1 != (err = i2c_master_send(c, &buf, 1))) {
714		tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
715		return -1;
716	}
717	if (len != (err = i2c_master_recv(c, eedata, len))) {
718		tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
719		return -1;
720	}
721	if (debug) {
722		int i;
723
724		tveeprom_info("full 256-byte eeprom dump:\n");
725		for (i = 0; i < len; i++) {
726			if (0 == (i % 16))
727				tveeprom_info("%02x:", i);
728			printk(" %02x", eedata[i]);
729			if (15 == (i % 16))
730				printk("\n");
731		}
732	}
733	return 0;
734}
735EXPORT_SYMBOL(tveeprom_read);
736
737/* ----------------------------------------------------------------------- */
738/* needed for ivtv.sf.net at the moment.  Should go away in the long       */
739/* run, just call the exported tveeprom_* directly, there is no point in   */
740/* using the indirect way via i2c_driver->command()                        */
741
742static unsigned short normal_i2c[] = {
743	0xa0 >> 1,
744	I2C_CLIENT_END,
745};
746
747I2C_CLIENT_INSMOD;
748
749static struct i2c_driver i2c_driver_tveeprom;
750
751static int
752tveeprom_command(struct i2c_client *client,
753		 unsigned int       cmd,
754		 void              *arg)
755{
756	struct tveeprom eeprom;
757	u32 *eeprom_props = arg;
758	u8 *buf;
759
760	switch (cmd) {
761	case 0:
762		buf = kzalloc(256,GFP_KERNEL);
763		tveeprom_read(client,buf,256);
764		tveeprom_hauppauge_analog(client, &eeprom,buf);
765		kfree(buf);
766		eeprom_props[0] = eeprom.tuner_type;
767		eeprom_props[1] = eeprom.tuner_formats;
768		eeprom_props[2] = eeprom.model;
769		eeprom_props[3] = eeprom.revision;
770		eeprom_props[4] = eeprom.has_radio;
771		break;
772	default:
773		return -EINVAL;
774	}
775	return 0;
776}
777
778static int
779tveeprom_detect_client(struct i2c_adapter *adapter,
780		       int                 address,
781		       int                 kind)
782{
783	struct i2c_client *client;
784
785	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
786	if (NULL == client)
787		return -ENOMEM;
788	client->addr = address;
789	client->adapter = adapter;
790	client->driver = &i2c_driver_tveeprom;
791	snprintf(client->name, sizeof(client->name), "tveeprom");
792	i2c_attach_client(client);
793
794	return 0;
795}
796
797static int
798tveeprom_attach_adapter (struct i2c_adapter *adapter)
799{
800	if (adapter->class & I2C_CLASS_TV_ANALOG)
801		return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
802	return 0;
803}
804
805static int
806tveeprom_detach_client (struct i2c_client *client)
807{
808	int err;
809
810	err = i2c_detach_client(client);
811	if (err < 0)
812		return err;
813	kfree(client);
814	return 0;
815}
816
817static struct i2c_driver i2c_driver_tveeprom = {
818	.driver = {
819		.name   = "tveeprom",
820	},
821	.id             = I2C_DRIVERID_TVEEPROM,
822	.attach_adapter = tveeprom_attach_adapter,
823	.detach_client  = tveeprom_detach_client,
824	.command        = tveeprom_command,
825};
826
827static int __init tveeprom_init(void)
828{
829	return i2c_add_driver(&i2c_driver_tveeprom);
830}
831
832static void __exit tveeprom_exit(void)
833{
834	i2c_del_driver(&i2c_driver_tveeprom);
835}
836
837module_init(tveeprom_init);
838module_exit(tveeprom_exit);
839
840/*
841 * Local variables:
842 * c-basic-offset: 8
843 * End:
844 */
845