]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/video/tveeprom.c
V4L/DVB (11752): cx18: Add missing newline to tuner detection error message
[net-next-2.6.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>
1da177e4
LT
33#include <linux/errno.h>
34#include <linux/kernel.h>
35#include <linux/init.h>
36#include <linux/types.h>
33b687cf 37#include <linux/videodev2.h>
1da177e4
LT
38#include <linux/i2c.h>
39
40#include <media/tuner.h>
41#include <media/tveeprom.h>
fac9e899 42#include <media/v4l2-common.h>
38f9d308 43#include <media/v4l2-chip-ident.h>
1da177e4
LT
44
45MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
46MODULE_AUTHOR("John Klar");
47MODULE_LICENSE("GPL");
48
f19a73d6 49static int debug;
1da177e4 50module_param(debug, int, 0644);
0f97a931 51MODULE_PARM_DESC(debug, "Debug level (0-1)");
1da177e4 52
f19a73d6
HV
53#define STRM(array, i) \
54 (i < sizeof(array) / sizeof(char *) ? array[i] : "unknown")
1da177e4 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) \
f19a73d6
HV
62 v4l_printk(KERN_DEBUG, "tveeprom", \
63 c->adapter, c->addr, fmt , ## arg); \
fac9e899 64 } while (0)
1da177e4 65
e64a86ee
ST
66/*
67 * The Hauppauge eeprom uses an 8bit field to determine which
68 * tuner formats the tuner supports.
69 */
1da177e4
LT
70static struct HAUPPAUGE_TUNER_FMT
71{
72 int id;
73 char *name;
74}
75hauppauge_tuner_fmt[] =
76{
3407e387
MCC
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" },
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 */
f19a73d6
HV
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" },
1da177e4 109 /* 10-19 */
f19a73d6
HV
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" },
1da177e4 120 /* 20-29 */
f19a73d6
HV
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" },
1da177e4 131 /* 30-39 */
f19a73d6
HV
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" },
1da177e4 142 /* 40-49 */
f19a73d6 143 { TUNER_ABSENT, "Samsung TCPQ9091P" },
1da177e4 144 { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
f19a73d6
HV
145 { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
146 { TUNER_TEMIC_4046FM5, "Temic 4046FM5" },
1da177e4 147 { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
f19a73d6
HV
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"},
1da177e4 153 /* 50-59 */
f19a73d6
HV
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"},
1da177e4 164 /* 60-69 */
f19a73d6
HV
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"},
1da177e4 175 /* 70-79 */
f19a73d6
HV
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"},
1da177e4 186 /* 80-89 */
f19a73d6
HV
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"},
1da177e4 197 /* 90-99 */
f19a73d6
HV
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"},
20f441f6 208 /* 100-109 */
f19a73d6
HV
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"},
3ca0ea98 219 /* 110-119 */
f19a73d6
HV
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"},
3ca0ea98 230 /* 120-129 */
f19a73d6
HV
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"},
ddc285c7 241 /* 130-139 */
f19a73d6
HV
242 { TUNER_ABSENT, "TCL M2523_3DBH_E"},
243 { TUNER_ABSENT, "TCL M2523_3DIH_E"},
244 { TUNER_ABSENT, "TCL MFPE05_2_U"},
953cafc0 245 { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"},
f19a73d6
HV
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"},
ddc285c7 252 /* 140-149 */
f19a73d6
HV
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"},
2800b439 263 /* 150-159 */
e2bff45c 264 { TUNER_XC5000, "Xceive XC5000"},
f6070767
MK
265 { TUNER_ABSENT, "Xceive XC3028L"},
266 { TUNER_ABSENT, "NXP 18271C2_716x"},
267 { TUNER_ABSENT, "Xceive XC4000"},
268 { TUNER_ABSENT, "Dibcom 7070"},
269 { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
1da177e4
LT
270};
271
38f9d308
HV
272/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
273 * internal to a video chip, i.e. not a separate audio chip. */
90a7ed47
MCC
274static struct HAUPPAUGE_AUDIOIC
275{
38f9d308 276 u32 id;
90a7ed47
MCC
277 char *name;
278}
279audioIC[] =
280{
281 /* 0-4 */
38f9d308
HV
282 { V4L2_IDENT_NONE, "None" },
283 { V4L2_IDENT_UNKNOWN, "TEA6300" },
284 { V4L2_IDENT_UNKNOWN, "TEA6320" },
285 { V4L2_IDENT_UNKNOWN, "TDA9850" },
286 { V4L2_IDENT_MSPX4XX, "MSP3400C" },
90a7ed47 287 /* 5-9 */
38f9d308
HV
288 { V4L2_IDENT_MSPX4XX, "MSP3410D" },
289 { V4L2_IDENT_MSPX4XX, "MSP3415" },
290 { V4L2_IDENT_MSPX4XX, "MSP3430" },
291 { V4L2_IDENT_MSPX4XX, "MSP3438" },
292 { V4L2_IDENT_UNKNOWN, "CS5331" },
90a7ed47 293 /* 10-14 */
38f9d308
HV
294 { V4L2_IDENT_MSPX4XX, "MSP3435" },
295 { V4L2_IDENT_MSPX4XX, "MSP3440" },
296 { V4L2_IDENT_MSPX4XX, "MSP3445" },
297 { V4L2_IDENT_MSPX4XX, "MSP3411" },
298 { V4L2_IDENT_MSPX4XX, "MSP3416" },
90a7ed47 299 /* 15-19 */
38f9d308
HV
300 { V4L2_IDENT_MSPX4XX, "MSP3425" },
301 { V4L2_IDENT_MSPX4XX, "MSP3451" },
302 { V4L2_IDENT_MSPX4XX, "MSP3418" },
303 { V4L2_IDENT_UNKNOWN, "Type 0x12" },
304 { V4L2_IDENT_UNKNOWN, "OKI7716" },
90a7ed47 305 /* 20-24 */
38f9d308
HV
306 { V4L2_IDENT_MSPX4XX, "MSP4410" },
307 { V4L2_IDENT_MSPX4XX, "MSP4420" },
308 { V4L2_IDENT_MSPX4XX, "MSP4440" },
309 { V4L2_IDENT_MSPX4XX, "MSP4450" },
310 { V4L2_IDENT_MSPX4XX, "MSP4408" },
90a7ed47 311 /* 25-29 */
38f9d308
HV
312 { V4L2_IDENT_MSPX4XX, "MSP4418" },
313 { V4L2_IDENT_MSPX4XX, "MSP4428" },
314 { V4L2_IDENT_MSPX4XX, "MSP4448" },
315 { V4L2_IDENT_MSPX4XX, "MSP4458" },
316 { V4L2_IDENT_MSPX4XX, "Type 0x1d" },
90a7ed47 317 /* 30-34 */
38f9d308
HV
318 { V4L2_IDENT_AMBIGUOUS, "CX880" },
319 { V4L2_IDENT_AMBIGUOUS, "CX881" },
320 { V4L2_IDENT_AMBIGUOUS, "CX883" },
321 { V4L2_IDENT_AMBIGUOUS, "CX882" },
322 { V4L2_IDENT_AMBIGUOUS, "CX25840" },
ddc285c7 323 /* 35-39 */
38f9d308
HV
324 { V4L2_IDENT_AMBIGUOUS, "CX25841" },
325 { V4L2_IDENT_AMBIGUOUS, "CX25842" },
326 { V4L2_IDENT_AMBIGUOUS, "CX25843" },
327 { V4L2_IDENT_AMBIGUOUS, "CX23418" },
328 { V4L2_IDENT_AMBIGUOUS, "CX23885" },
ee04e0fa 329 /* 40-44 */
38f9d308
HV
330 { V4L2_IDENT_AMBIGUOUS, "CX23888" },
331 { V4L2_IDENT_AMBIGUOUS, "SAA7131" },
332 { V4L2_IDENT_AMBIGUOUS, "CX23887" },
333 { V4L2_IDENT_AMBIGUOUS, "SAA7164" },
334 { V4L2_IDENT_AMBIGUOUS, "AU8522" },
0f97a931 335};
1da177e4 336
0f97a931
MCC
337/* This list is supplied by Hauppauge. Thanks! */
338static const char *decoderIC[] = {
90a7ed47
MCC
339 /* 0-4 */
340 "None", "BT815", "BT817", "BT819", "BT815A",
341 /* 5-9 */
342 "BT817A", "BT819A", "BT827", "BT829", "BT848",
343 /* 10-14 */
344 "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
345 /* 15-19 */
346 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
347 /* 20-24 */
348 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
349 /* 25-29 */
350 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
ddc285c7
ST
351 /* 30-34 */
352 "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
ee04e0fa
MK
353 /* 35-39 */
354 "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
355 /* 40-42 */
356 "SAA7164", "CX23885B", "AU8522"
1da177e4
LT
357};
358
359static int hasRadioTuner(int tunerType)
360{
4ac97914 361 switch (tunerType) {
f19a73d6
HV
362 case 18: /* PNPEnv_TUNER_FR1236_MK2 */
363 case 23: /* PNPEnv_TUNER_FM1236 */
364 case 38: /* PNPEnv_TUNER_FMR1236 */
365 case 16: /* PNPEnv_TUNER_FR1216_MK2 */
366 case 19: /* PNPEnv_TUNER_FR1246_MK2 */
367 case 21: /* PNPEnv_TUNER_FM1216 */
368 case 24: /* PNPEnv_TUNER_FM1246 */
369 case 17: /* PNPEnv_TUNER_FR1216MF_MK2 */
370 case 22: /* PNPEnv_TUNER_FM1216MF */
371 case 20: /* PNPEnv_TUNER_FR1256_MK2 */
372 case 25: /* PNPEnv_TUNER_FM1256 */
373 case 33: /* PNPEnv_TUNER_4039FR5 */
374 case 42: /* PNPEnv_TUNER_4009FR5 */
375 case 52: /* PNPEnv_TUNER_4049FM5 */
376 case 54: /* PNPEnv_TUNER_4049FM5_AltI2C */
377 case 44: /* PNPEnv_TUNER_4009FN5 */
378 case 31: /* PNPEnv_TUNER_TCPB9085P */
379 case 30: /* PNPEnv_TUNER_TCPN9085D */
380 case 46: /* PNPEnv_TUNER_TP18NSR01F */
381 case 47: /* PNPEnv_TUNER_TP18PSB01D */
382 case 49: /* PNPEnv_TUNER_TAPC_I001D */
383 case 60: /* PNPEnv_TUNER_TAPE_S001D_MK3 */
384 case 57: /* PNPEnv_TUNER_FM1216ME_MK3 */
385 case 59: /* PNPEnv_TUNER_FM1216MP_MK3 */
386 case 58: /* PNPEnv_TUNER_FM1236_MK3 */
387 case 68: /* PNPEnv_TUNER_TAPE_H001F_MK3 */
388 case 61: /* PNPEnv_TUNER_TAPE_M001D_MK3 */
389 case 78: /* PNPEnv_TUNER_TDA8275C1_8290_FM */
390 case 89: /* PNPEnv_TUNER_TCL_MFPE05_2 */
391 case 92: /* PNPEnv_TUNER_PHILIPS_FQ1236A_MK4 */
392 case 105:
90a7ed47 393 return 1;
4ac97914
MCC
394 }
395 return 0;
1da177e4
LT
396}
397
0f97a931 398void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
f2421ca3 399 unsigned char *eeprom_data)
1da177e4
LT
400{
401 /* ----------------------------------------------
402 ** The hauppauge eeprom format is tagged
403 **
404 ** if packet[0] == 0x84, then packet[0..1] == length
405 ** else length = packet[0] & 3f;
406 ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
407 **
408 ** In our (ivtv) case we're interested in the following:
0f97a931 409 ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
f19a73d6
HV
410 ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into
411 ** hauppauge_tuner_fmt)
0f97a931
MCC
412 ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
413 ** audio proc: tag [02].01 or [05].00 (mask with 0x7f)
414 ** decoder proc: tag [09].01)
1da177e4
LT
415
416 ** Fun info:
417 ** model: tag [00].07-08 or [06].00-01
418 ** revision: tag [00].09-0b or [06].04-06
419 ** serial#: tag [01].05-07 or [04].04-06
420
421 ** # of inputs/outputs ???
422 */
423
5412c820 424 int i, j, len, done, beenhere, tag, start;
1da177e4 425
5412c820 426 int tuner1 = 0, t_format1 = 0, audioic = -1;
0f97a931 427 char *t_name1 = NULL;
90a7ed47 428 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
1da177e4 429
90a7ed47 430 int tuner2 = 0, t_format2 = 0;
0f97a931 431 char *t_name2 = NULL;
90a7ed47 432 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
0f97a931 433
90a7ed47 434 memset(tvee, 0, sizeof(*tvee));
3e478c06
MCC
435 tvee->tuner_type = TUNER_ABSENT;
436 tvee->tuner2_type = TUNER_ABSENT;
437
0f97a931 438 done = len = beenhere = 0;
90a7ed47 439
5412c820
HV
440 /* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
441 if (eeprom_data[0] == 0x1a &&
442 eeprom_data[1] == 0xeb &&
443 eeprom_data[2] == 0x67 &&
444 eeprom_data[3] == 0x95)
445 start = 0xa0; /* Generic em28xx offset */
446 else if ((eeprom_data[0] & 0xe1) == 0x01 &&
447 eeprom_data[1] == 0x00 &&
448 eeprom_data[2] == 0x00 &&
449 eeprom_data[8] == 0x84)
450 start = 8; /* Generic cx2388x offset */
451 else if (eeprom_data[1] == 0x70 &&
452 eeprom_data[2] == 0x00 &&
453 eeprom_data[4] == 0x74 &&
454 eeprom_data[8] == 0x84)
455 start = 8; /* Generic cx23418 offset (models 74xxx) */
90a7ed47 456 else
5412c820 457 start = 0;
90a7ed47
MCC
458
459 for (i = start; !done && i < 256; i += len) {
1da177e4
LT
460 if (eeprom_data[i] == 0x84) {
461 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
0f97a931 462 i += 3;
1da177e4 463 } else if ((eeprom_data[i] & 0xf0) == 0x70) {
0f97a931 464 if (eeprom_data[i] & 0x08) {
1da177e4
LT
465 /* verify checksum! */
466 done = 1;
467 break;
468 }
469 len = eeprom_data[i] & 0x07;
470 ++i;
471 } else {
0f97a931 472 tveeprom_warn("Encountered bad packet header [%02x]. "
f19a73d6
HV
473 "Corrupt or not a Hauppauge eeprom.\n",
474 eeprom_data[i]);
1da177e4
LT
475 return;
476 }
477
90a7ed47 478 if (debug) {
f19a73d6
HV
479 tveeprom_info("Tag [%02x] + %d bytes:",
480 eeprom_data[i], len - 1);
481 for (j = 1; j < len; j++)
482 printk(KERN_CONT " %02x", eeprom_data[i + j]);
483 printk(KERN_CONT "\n");
90a7ed47 484 }
1da177e4
LT
485
486 /* process by tag */
487 tag = eeprom_data[i];
488 switch (tag) {
489 case 0x00:
90a7ed47 490 /* tag: 'Comprehensive' */
0f97a931
MCC
491 tuner1 = eeprom_data[i+6];
492 t_format1 = eeprom_data[i+5];
1da177e4 493 tvee->has_radio = eeprom_data[i+len-1];
90a7ed47
MCC
494 /* old style tag, don't know how to detect
495 IR presence, mark as unknown. */
b654fcdc 496 tvee->has_ir = 0;
1da177e4
LT
497 tvee->model =
498 eeprom_data[i+8] +
499 (eeprom_data[i+9] << 8);
500 tvee->revision = eeprom_data[i+10] +
501 (eeprom_data[i+11] << 8) +
502 (eeprom_data[i+12] << 16);
503 break;
0f97a931 504
1da177e4 505 case 0x01:
90a7ed47 506 /* tag: 'SerialID' */
1da177e4
LT
507 tvee->serial_number =
508 eeprom_data[i+6] +
509 (eeprom_data[i+7] << 8) +
510 (eeprom_data[i+8] << 16);
511 break;
0f97a931 512
1da177e4 513 case 0x02:
90a7ed47
MCC
514 /* tag 'AudioInfo'
515 Note mask with 0x7F, high bit used on some older models
516 to indicate 4052 mux was removed in favor of using MSP
517 inputs directly. */
518 audioic = eeprom_data[i+2] & 0x7f;
0c71bf1c 519 if (audioic < ARRAY_SIZE(audioIC))
90a7ed47
MCC
520 tvee->audio_processor = audioIC[audioic].id;
521 else
38f9d308 522 tvee->audio_processor = V4L2_IDENT_UNKNOWN;
1da177e4 523 break;
0f97a931 524
90a7ed47 525 /* case 0x03: tag 'EEInfo' */
0f97a931 526
1da177e4 527 case 0x04:
90a7ed47 528 /* tag 'SerialID2' */
1da177e4
LT
529 tvee->serial_number =
530 eeprom_data[i+5] +
531 (eeprom_data[i+6] << 8) +
532 (eeprom_data[i+7] << 16);
3ca0ea98 533
f19a73d6
HV
534 if ((eeprom_data[i + 8] & 0xf0) &&
535 (tvee->serial_number < 0xffffff)) {
536 tvee->MAC_address[0] = 0x00;
537 tvee->MAC_address[1] = 0x0D;
538 tvee->MAC_address[2] = 0xFE;
539 tvee->MAC_address[3] = eeprom_data[i + 7];
540 tvee->MAC_address[4] = eeprom_data[i + 6];
541 tvee->MAC_address[5] = eeprom_data[i + 5];
542 tvee->has_MAC_address = 1;
543 }
1da177e4 544 break;
0f97a931 545
1da177e4 546 case 0x05:
90a7ed47
MCC
547 /* tag 'Audio2'
548 Note mask with 0x7F, high bit used on some older models
549 to indicate 4052 mux was removed in favor of using MSP
550 inputs directly. */
551 audioic = eeprom_data[i+1] & 0x7f;
0c71bf1c 552 if (audioic < ARRAY_SIZE(audioIC))
90a7ed47
MCC
553 tvee->audio_processor = audioIC[audioic].id;
554 else
38f9d308 555 tvee->audio_processor = V4L2_IDENT_UNKNOWN;
90a7ed47 556
1da177e4 557 break;
0f97a931 558
1da177e4 559 case 0x06:
90a7ed47 560 /* tag 'ModelRev' */
1da177e4 561 tvee->model =
3ca0ea98
ST
562 eeprom_data[i + 1] +
563 (eeprom_data[i + 2] << 8) +
564 (eeprom_data[i + 3] << 16) +
565 (eeprom_data[i + 4] << 24);
566 tvee->revision =
f19a73d6 567 eeprom_data[i + 5] +
3ca0ea98
ST
568 (eeprom_data[i + 6] << 8) +
569 (eeprom_data[i + 7] << 16);
1da177e4 570 break;
0f97a931
MCC
571
572 case 0x07:
90a7ed47
MCC
573 /* tag 'Details': according to Hauppauge not interesting
574 on any PCI-era or later boards. */
0f97a931
MCC
575 break;
576
90a7ed47 577 /* there is no tag 0x08 defined */
0f97a931
MCC
578
579 case 0x09:
90a7ed47 580 /* tag 'Video' */
0f97a931
MCC
581 tvee->decoder_processor = eeprom_data[i + 1];
582 break;
583
1da177e4 584 case 0x0a:
90a7ed47 585 /* tag 'Tuner' */
0f97a931 586 if (beenhere == 0) {
f19a73d6
HV
587 tuner1 = eeprom_data[i + 2];
588 t_format1 = eeprom_data[i + 1];
1da177e4 589 beenhere = 1;
1da177e4 590 } else {
90a7ed47 591 /* a second (radio) tuner may be present */
f19a73d6
HV
592 tuner2 = eeprom_data[i + 2];
593 t_format2 = eeprom_data[i + 1];
594 /* not a TV tuner? */
595 if (t_format2 == 0)
90a7ed47 596 tvee->has_radio = 1; /* must be radio */
90a7ed47 597 }
0f97a931
MCC
598 break;
599
90a7ed47
MCC
600 case 0x0b:
601 /* tag 'Inputs': according to Hauppauge this is specific
602 to each driver family, so no good assumptions can be
603 made. */
604 break;
0f97a931 605
90a7ed47
MCC
606 /* case 0x0c: tag 'Balun' */
607 /* case 0x0d: tag 'Teletext' */
0f97a931 608
1da177e4 609 case 0x0e:
90a7ed47 610 /* tag: 'Radio' */
1da177e4
LT
611 tvee->has_radio = eeprom_data[i+1];
612 break;
0f97a931 613
90a7ed47
MCC
614 case 0x0f:
615 /* tag 'IRInfo' */
b654fcdc 616 tvee->has_ir = 1 | (eeprom_data[i+1] << 1);
90a7ed47 617 break;
0f97a931 618
90a7ed47
MCC
619 /* case 0x10: tag 'VBIInfo' */
620 /* case 0x11: tag 'QCInfo' */
621 /* case 0x12: tag 'InfoBits' */
0f97a931 622
1da177e4 623 default:
f19a73d6
HV
624 tveeprom_dbg("Not sure what to do with tag [%02x]\n",
625 tag);
1da177e4
LT
626 /* dump the rest of the packet? */
627 }
1da177e4
LT
628 }
629
630 if (!done) {
0f97a931 631 tveeprom_warn("Ran out of data!\n");
1da177e4
LT
632 return;
633 }
634
635 if (tvee->revision != 0) {
636 tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
637 tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
638 tvee->rev_str[2] = 32 + ((tvee->revision >> 6) & 0x3f);
f19a73d6 639 tvee->rev_str[3] = 32 + (tvee->revision & 0x3f);
1da177e4
LT
640 tvee->rev_str[4] = 0;
641 }
642
90a7ed47
MCC
643 if (hasRadioTuner(tuner1) && !tvee->has_radio) {
644 tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
645 tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
646 tvee->has_radio = 1;
647 }
1da177e4 648
0f97a931
MCC
649 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
650 tvee->tuner_type = hauppauge_tuner[tuner1].id;
651 t_name1 = hauppauge_tuner[tuner1].name;
1da177e4 652 } else {
0f97a931
MCC
653 t_name1 = "unknown";
654 }
655
656 if (tuner2 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
657 tvee->tuner2_type = hauppauge_tuner[tuner2].id;
658 t_name2 = hauppauge_tuner[tuner2].name;
659 } else {
660 t_name2 = "unknown";
1da177e4
LT
661 }
662
f95006f8
HV
663 tvee->tuner_hauppauge_model = tuner1;
664 tvee->tuner2_hauppauge_model = tuner2;
1da177e4 665 tvee->tuner_formats = 0;
0f97a931
MCC
666 tvee->tuner2_formats = 0;
667 for (i = j = 0; i < 8; i++) {
668 if (t_format1 & (1 << i)) {
1da177e4 669 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
0f97a931 670 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
1da177e4 671 }
18795eb9
TP
672 }
673 for (i = j = 0; i < 8; i++) {
90a7ed47
MCC
674 if (t_format2 & (1 << i)) {
675 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
676 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
677 }
1da177e4
LT
678 }
679
0f97a931 680 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
90a7ed47 681 tvee->model, tvee->rev_str, tvee->serial_number);
f19a73d6 682 if (tvee->has_MAC_address == 1)
3ca0ea98
ST
683 tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n",
684 tvee->MAC_address[0], tvee->MAC_address[1],
685 tvee->MAC_address[2], tvee->MAC_address[3],
686 tvee->MAC_address[4], tvee->MAC_address[5]);
0f97a931 687 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
90a7ed47 688 t_name1, tuner1, tvee->tuner_type);
0f97a931 689 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
f19a73d6
HV
690 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2],
691 t_fmt_name1[3], t_fmt_name1[4], t_fmt_name1[5],
692 t_fmt_name1[6], t_fmt_name1[7], t_format1);
693 if (tuner2)
90a7ed47
MCC
694 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
695 t_name2, tuner2, tvee->tuner2_type);
f19a73d6 696 if (t_format2)
90a7ed47 697 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
f19a73d6
HV
698 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2],
699 t_fmt_name2[3], t_fmt_name2[4], t_fmt_name2[5],
700 t_fmt_name2[6], t_fmt_name2[7], t_format2);
701 if (audioic < 0) {
90a7ed47 702 tveeprom_info("audio processor is unknown (no idx)\n");
38f9d308 703 tvee->audio_processor = V4L2_IDENT_UNKNOWN;
90a7ed47 704 } else {
0c71bf1c 705 if (audioic < ARRAY_SIZE(audioIC))
90a7ed47 706 tveeprom_info("audio processor is %s (idx %d)\n",
f19a73d6 707 audioIC[audioic].name, audioic);
90a7ed47
MCC
708 else
709 tveeprom_info("audio processor is unknown (idx %d)\n",
710 audioic);
711 }
f19a73d6 712 if (tvee->decoder_processor)
90a7ed47
MCC
713 tveeprom_info("decoder processor is %s (idx %d)\n",
714 STRM(decoderIC, tvee->decoder_processor),
715 tvee->decoder_processor);
b654fcdc 716 if (tvee->has_ir)
f2520106 717 tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
90a7ed47 718 tvee->has_radio ? "" : "no ",
b654fcdc
HV
719 (tvee->has_ir & 2) ? "" : "no ",
720 (tvee->has_ir & 4) ? "" : "no ");
721 else
722 tveeprom_info("has %sradio\n",
723 tvee->has_radio ? "" : "no ");
1da177e4
LT
724}
725EXPORT_SYMBOL(tveeprom_hauppauge_analog);
726
727/* ----------------------------------------------------------------------- */
728/* generic helper functions */
729
730int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
731{
732 unsigned char buf;
733 int err;
734
1da177e4 735 buf = 0;
f19a73d6
HV
736 err = i2c_master_send(c, &buf, 1);
737 if (err != 1) {
0f97a931 738 tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
1da177e4
LT
739 return -1;
740 }
f19a73d6
HV
741 err = i2c_master_recv(c, eedata, len);
742 if (err != len) {
0f97a931 743 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
1da177e4
LT
744 return -1;
745 }
90a7ed47
MCC
746 if (debug) {
747 int i;
748
749 tveeprom_info("full 256-byte eeprom dump:\n");
750 for (i = 0; i < len; i++) {
751 if (0 == (i % 16))
752 tveeprom_info("%02x:", i);
f19a73d6 753 printk(KERN_CONT " %02x", eedata[i]);
90a7ed47 754 if (15 == (i % 16))
f19a73d6 755 printk(KERN_CONT "\n");
90a7ed47
MCC
756 }
757 }
1da177e4
LT
758 return 0;
759}
760EXPORT_SYMBOL(tveeprom_read);
761
1da177e4
LT
762/*
763 * Local variables:
764 * c-basic-offset: 8
765 * End:
766 */