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