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