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