Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * tveeprom - eeprom decoder for tvcard configuration eeproms
0004  *
0005  * Data and decoding routines shamelessly borrowed from bttv-cards.c
0006  * eeprom access routine shamelessly borrowed from bttv-if.c
0007  * which are:
0008 
0009     Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
0010                & Marcus Metzler (mocm@thp.uni-koeln.de)
0011     (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
0012 
0013  * Adjustments to fit a more general model and all bugs:
0014 
0015     Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
0016 
0017  */
0018 
0019 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0020 
0021 #include <linux/module.h>
0022 #include <linux/errno.h>
0023 #include <linux/kernel.h>
0024 #include <linux/init.h>
0025 #include <linux/types.h>
0026 #include <linux/videodev2.h>
0027 #include <linux/i2c.h>
0028 
0029 #include <media/tuner.h>
0030 #include <media/tveeprom.h>
0031 #include <media/v4l2-common.h>
0032 
0033 MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
0034 MODULE_AUTHOR("John Klar");
0035 MODULE_LICENSE("GPL");
0036 
0037 #define STRM(array, i) \
0038     (i < sizeof(array) / sizeof(char *) ? array[i] : "unknown")
0039 
0040 
0041 /*
0042  * The Hauppauge eeprom uses an 8bit field to determine which
0043  * tuner formats the tuner supports.
0044  */
0045 static const struct {
0046     int id;
0047     const char * const name;
0048 } hauppauge_tuner_fmt[] = {
0049     { V4L2_STD_UNKNOWN,                   " UNKNOWN" },
0050     { V4L2_STD_UNKNOWN,                   " FM" },
0051     { V4L2_STD_B|V4L2_STD_GH,             " PAL(B/G)" },
0052     { V4L2_STD_MN,                        " NTSC(M)" },
0053     { V4L2_STD_PAL_I,                     " PAL(I)" },
0054     { V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, " SECAM(L/L')" },
0055     { V4L2_STD_DK,                        " PAL(D/D1/K)" },
0056     { V4L2_STD_ATSC,                      " ATSC/DVB Digital" },
0057 };
0058 
0059 /* This is the full list of possible tuners. Many thanks to Hauppauge for
0060    supplying this information. Note that many tuners where only used for
0061    testing and never made it to the outside world. So you will only see
0062    a subset in actual produced cards. */
0063 static const struct {
0064     int  id;
0065     const char * const name;
0066 } hauppauge_tuner[] = {
0067     /* 0-9 */
0068     { TUNER_ABSENT,         "None" },
0069     { TUNER_ABSENT,         "External" },
0070     { TUNER_ABSENT,         "Unspecified" },
0071     { TUNER_PHILIPS_PAL,        "Philips FI1216" },
0072     { TUNER_PHILIPS_SECAM,      "Philips FI1216MF" },
0073     { TUNER_PHILIPS_NTSC,       "Philips FI1236" },
0074     { TUNER_PHILIPS_PAL_I,      "Philips FI1246" },
0075     { TUNER_PHILIPS_PAL_DK,     "Philips FI1256" },
0076     { TUNER_PHILIPS_PAL,        "Philips FI1216 MK2" },
0077     { TUNER_PHILIPS_SECAM,      "Philips FI1216MF MK2" },
0078     /* 10-19 */
0079     { TUNER_PHILIPS_NTSC,       "Philips FI1236 MK2" },
0080     { TUNER_PHILIPS_PAL_I,      "Philips FI1246 MK2" },
0081     { TUNER_PHILIPS_PAL_DK,     "Philips FI1256 MK2" },
0082     { TUNER_TEMIC_NTSC,     "Temic 4032FY5" },
0083     { TUNER_TEMIC_PAL,      "Temic 4002FH5" },
0084     { TUNER_TEMIC_PAL_I,        "Temic 4062FY5" },
0085     { TUNER_PHILIPS_PAL,        "Philips FR1216 MK2" },
0086     { TUNER_PHILIPS_SECAM,      "Philips FR1216MF MK2" },
0087     { TUNER_PHILIPS_NTSC,       "Philips FR1236 MK2" },
0088     { TUNER_PHILIPS_PAL_I,      "Philips FR1246 MK2" },
0089     /* 20-29 */
0090     { TUNER_PHILIPS_PAL_DK,     "Philips FR1256 MK2" },
0091     { TUNER_PHILIPS_PAL,        "Philips FM1216" },
0092     { TUNER_PHILIPS_SECAM,      "Philips FM1216MF" },
0093     { TUNER_PHILIPS_NTSC,       "Philips FM1236" },
0094     { TUNER_PHILIPS_PAL_I,      "Philips FM1246" },
0095     { TUNER_PHILIPS_PAL_DK,     "Philips FM1256" },
0096     { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
0097     { TUNER_ABSENT,         "Samsung TCPN9082D" },
0098     { TUNER_ABSENT,         "Samsung TCPM9092P" },
0099     { TUNER_TEMIC_4006FH5_PAL,  "Temic 4006FH5" },
0100     /* 30-39 */
0101     { TUNER_ABSENT,         "Samsung TCPN9085D" },
0102     { TUNER_ABSENT,         "Samsung TCPB9085P" },
0103     { TUNER_ABSENT,         "Samsung TCPL9091P" },
0104     { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
0105     { TUNER_PHILIPS_FQ1216ME,   "Philips FQ1216 ME" },
0106     { TUNER_TEMIC_4066FY5_PAL_I,    "Temic 4066FY5" },
0107     { TUNER_PHILIPS_NTSC,       "Philips TD1536" },
0108     { TUNER_PHILIPS_NTSC,       "Philips TD1536D" },
0109     { TUNER_PHILIPS_NTSC,       "Philips FMR1236" }, /* mono radio */
0110     { TUNER_ABSENT,         "Philips FI1256MP" },
0111     /* 40-49 */
0112     { TUNER_ABSENT,         "Samsung TCPQ9091P" },
0113     { TUNER_TEMIC_4006FN5_MULTI_PAL,"Temic 4006FN5" },
0114     { TUNER_TEMIC_4009FR5_PAL,  "Temic 4009FR5" },
0115     { TUNER_TEMIC_4046FM5,      "Temic 4046FM5" },
0116     { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
0117     { TUNER_ABSENT,         "Philips TD1536D FH 44"},
0118     { TUNER_LG_NTSC_FM,     "LG TP18NSR01F"},
0119     { TUNER_LG_PAL_FM,      "LG TP18PSB01D"},
0120     { TUNER_LG_PAL,     "LG TP18PSB11D"},
0121     { TUNER_LG_PAL_I_FM,        "LG TAPC-I001D"},
0122     /* 50-59 */
0123     { TUNER_LG_PAL_I,       "LG TAPC-I701D"},
0124     { TUNER_ABSENT,         "Temic 4042FI5"},
0125     { TUNER_MICROTUNE_4049FM5,  "Microtune 4049 FM5"},
0126     { TUNER_ABSENT,         "LG TPI8NSR11F"},
0127     { TUNER_ABSENT,         "Microtune 4049 FM5 Alt I2C"},
0128     { TUNER_PHILIPS_FM1216ME_MK3,   "Philips FQ1216ME MK3"},
0129     { TUNER_ABSENT,         "Philips FI1236 MK3"},
0130     { TUNER_PHILIPS_FM1216ME_MK3,   "Philips FM1216 ME MK3"},
0131     { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
0132     { TUNER_ABSENT,         "Philips FM1216MP MK3"},
0133     /* 60-69 */
0134     { TUNER_PHILIPS_FM1216ME_MK3,   "LG S001D MK3"},
0135     { TUNER_ABSENT,         "LG M001D MK3"},
0136     { TUNER_PHILIPS_FM1216ME_MK3,   "LG S701D MK3"},
0137     { TUNER_ABSENT,         "LG M701D MK3"},
0138     { TUNER_ABSENT,         "Temic 4146FM5"},
0139     { TUNER_ABSENT,         "Temic 4136FY5"},
0140     { TUNER_ABSENT,         "Temic 4106FH5"},
0141     { TUNER_ABSENT,         "Philips FQ1216LMP MK3"},
0142     { TUNER_LG_NTSC_TAPE,       "LG TAPE H001F MK3"},
0143     { TUNER_LG_NTSC_TAPE,       "LG TAPE H701F MK3"},
0144     /* 70-79 */
0145     { TUNER_ABSENT,         "LG TALN H200T"},
0146     { TUNER_ABSENT,         "LG TALN H250T"},
0147     { TUNER_ABSENT,         "LG TALN M200T"},
0148     { TUNER_ABSENT,         "LG TALN Z200T"},
0149     { TUNER_ABSENT,         "LG TALN S200T"},
0150     { TUNER_ABSENT,         "Thompson DTT7595"},
0151     { TUNER_ABSENT,         "Thompson DTT7592"},
0152     { TUNER_ABSENT,         "Silicon TDA8275C1 8290"},
0153     { TUNER_ABSENT,         "Silicon TDA8275C1 8290 FM"},
0154     { TUNER_ABSENT,         "Thompson DTT757"},
0155     /* 80-89 */
0156     { TUNER_PHILIPS_FQ1216LME_MK3,  "Philips FQ1216LME MK3"},
0157     { TUNER_LG_PAL_NEW_TAPC,    "LG TAPC G701D"},
0158     { TUNER_LG_NTSC_NEW_TAPC,   "LG TAPC H791F"},
0159     { TUNER_LG_PAL_NEW_TAPC,    "TCL 2002MB 3"},
0160     { TUNER_LG_PAL_NEW_TAPC,    "TCL 2002MI 3"},
0161     { TUNER_TCL_2002N,      "TCL 2002N 6A"},
0162     { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
0163     { TUNER_SAMSUNG_TCPN_2121P30A,  "Samsung TCPN 2121P30A"},
0164     { TUNER_ABSENT,         "Samsung TCPE 4121P30A"},
0165     { TUNER_PHILIPS_FM1216ME_MK3,   "TCL MFPE05 2"},
0166     /* 90-99 */
0167     { TUNER_ABSENT,         "LG TALN H202T"},
0168     { TUNER_PHILIPS_FQ1216AME_MK4,  "Philips FQ1216AME MK4"},
0169     { TUNER_PHILIPS_FQ1236A_MK4,    "Philips FQ1236A MK4"},
0170     { TUNER_ABSENT,         "Philips FQ1286A MK4"},
0171     { TUNER_ABSENT,         "Philips FQ1216ME MK5"},
0172     { TUNER_ABSENT,         "Philips FQ1236 MK5"},
0173     { TUNER_SAMSUNG_TCPG_6121P30A,  "Samsung TCPG 6121P30A"},
0174     { TUNER_TCL_2002MB,     "TCL 2002MB_3H"},
0175     { TUNER_ABSENT,         "TCL 2002MI_3H"},
0176     { TUNER_TCL_2002N,      "TCL 2002N 5H"},
0177     /* 100-109 */
0178     { TUNER_PHILIPS_FMD1216ME_MK3,  "Philips FMD1216ME"},
0179     { TUNER_TEA5767,        "Philips TEA5768HL FM Radio"},
0180     { TUNER_ABSENT,         "Panasonic ENV57H12D5"},
0181     { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
0182     { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"},
0183     { TUNER_PHILIPS_FM1216ME_MK3,   "TCL MPE05-2"},
0184     { TUNER_ABSENT,         "TCL MQNM05-4"},
0185     { TUNER_ABSENT,         "LG TAPC-W701D"},
0186     { TUNER_ABSENT,         "TCL 9886P-WM"},
0187     { TUNER_ABSENT,         "TCL 1676NM-WM"},
0188     /* 110-119 */
0189     { TUNER_ABSENT,         "Thompson DTT75105"},
0190     { TUNER_ABSENT,         "Conexant_CX24109"},
0191     { TUNER_TCL_2002N,      "TCL M2523_5N_E"},
0192     { TUNER_TCL_2002MB,     "TCL M2523_3DB_E"},
0193     { TUNER_ABSENT,         "Philips 8275A"},
0194     { TUNER_ABSENT,         "Microtune MT2060"},
0195     { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK5"},
0196     { TUNER_PHILIPS_FM1216ME_MK3,   "Philips FM1216ME MK5"},
0197     { TUNER_ABSENT,         "TCL M2523_3DI_E"},
0198     { TUNER_ABSENT,         "Samsung THPD5222FG30A"},
0199     /* 120-129 */
0200     { TUNER_XC2028,         "Xceive XC3028"},
0201     { TUNER_PHILIPS_FQ1216LME_MK3,  "Philips FQ1216LME MK5"},
0202     { TUNER_ABSENT,         "Philips FQD1216LME"},
0203     { TUNER_ABSENT,         "Conexant CX24118A"},
0204     { TUNER_ABSENT,         "TCL DMF11WIP"},
0205     { TUNER_ABSENT,         "TCL MFNM05_4H_E"},
0206     { TUNER_ABSENT,         "TCL MNM05_4H_E"},
0207     { TUNER_ABSENT,         "TCL MPE05_2H_E"},
0208     { TUNER_ABSENT,         "TCL MQNM05_4_U"},
0209     { TUNER_ABSENT,         "TCL M2523_5NH_E"},
0210     /* 130-139 */
0211     { TUNER_ABSENT,         "TCL M2523_3DBH_E"},
0212     { TUNER_ABSENT,         "TCL M2523_3DIH_E"},
0213     { TUNER_ABSENT,         "TCL MFPE05_2_U"},
0214     { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"},
0215     { TUNER_ABSENT,         "Philips FRH2036B"},
0216     { TUNER_ABSENT,         "Panasonic ENGF75_01GF"},
0217     { TUNER_ABSENT,         "MaxLinear MXL5005"},
0218     { TUNER_ABSENT,         "MaxLinear MXL5003"},
0219     { TUNER_ABSENT,         "Xceive XC2028"},
0220     { TUNER_ABSENT,         "Microtune MT2131"},
0221     /* 140-149 */
0222     { TUNER_ABSENT,         "Philips 8275A_8295"},
0223     { TUNER_ABSENT,         "TCL MF02GIP_5N_E"},
0224     { TUNER_ABSENT,         "TCL MF02GIP_3DB_E"},
0225     { TUNER_ABSENT,         "TCL MF02GIP_3DI_E"},
0226     { TUNER_ABSENT,         "Microtune MT2266"},
0227     { TUNER_ABSENT,         "TCL MF10WPP_4N_E"},
0228     { TUNER_ABSENT,         "LG TAPQ_H702F"},
0229     { TUNER_ABSENT,         "TCL M09WPP_4N_E"},
0230     { TUNER_ABSENT,         "MaxLinear MXL5005_v2"},
0231     { TUNER_PHILIPS_TDA8290,    "Philips 18271_8295"},
0232     /* 150-159 */
0233     { TUNER_XC5000,                 "Xceive XC5000"},
0234     { TUNER_ABSENT,                 "Xceive XC3028L"},
0235     { TUNER_ABSENT,                 "NXP 18271C2_716x"},
0236     { TUNER_ABSENT,                 "Xceive XC4000"},
0237     { TUNER_ABSENT,                 "Dibcom 7070"},
0238     { TUNER_PHILIPS_TDA8290,        "NXP 18271C2"},
0239     { TUNER_ABSENT,                 "Siano SMS1010"},
0240     { TUNER_ABSENT,                 "Siano SMS1150"},
0241     { TUNER_ABSENT,                 "MaxLinear 5007"},
0242     { TUNER_ABSENT,                 "TCL M09WPP_2P_E"},
0243     /* 160-169 */
0244     { TUNER_ABSENT,                 "Siano SMS1180"},
0245     { TUNER_ABSENT,                 "Maxim_MAX2165"},
0246     { TUNER_ABSENT,                 "Siano SMS1140"},
0247     { TUNER_ABSENT,                 "Siano SMS1150 B1"},
0248     { TUNER_ABSENT,                 "MaxLinear 111"},
0249     { TUNER_ABSENT,                 "Dibcom 7770"},
0250     { TUNER_ABSENT,                 "Siano SMS1180VNS"},
0251     { TUNER_ABSENT,                 "Siano SMS1184"},
0252     { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"},
0253     { TUNER_ABSENT,                 "TCL_M11WPP_2PN_E"},
0254     /* 170-179 */
0255     { TUNER_ABSENT,                 "MaxLinear 301"},
0256     { TUNER_ABSENT,                 "Mirics MSi001"},
0257     { TUNER_ABSENT,                 "MaxLinear MxL241SF"},
0258     { TUNER_XC5000C,                "Xceive XC5000C"},
0259     { TUNER_ABSENT,                 "Montage M68TS2020"},
0260     { TUNER_ABSENT,                 "Siano SMS1530"},
0261     { TUNER_ABSENT,                 "Dibcom 7090"},
0262     { TUNER_ABSENT,                 "Xceive XC5200C"},
0263     { TUNER_ABSENT,                 "NXP 18273"},
0264     { TUNER_ABSENT,                 "Montage M88TS2022"},
0265     /* 180-188 */
0266     { TUNER_ABSENT,                 "NXP 18272M"},
0267     { TUNER_ABSENT,                 "NXP 18272S"},
0268 
0269     { TUNER_ABSENT,                 "Mirics MSi003"},
0270     { TUNER_ABSENT,                 "MaxLinear MxL256"},
0271     { TUNER_ABSENT,                 "SiLabs Si2158"},
0272     { TUNER_ABSENT,                 "SiLabs Si2178"},
0273     { TUNER_ABSENT,                 "SiLabs Si2157"},
0274     { TUNER_ABSENT,                 "SiLabs Si2177"},
0275     { TUNER_ABSENT,                 "ITE IT9137FN"},
0276 };
0277 
0278 /* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are
0279  * internal to a video chip, i.e. not a separate audio chip. */
0280 static const struct {
0281     u32   id;
0282     const char * const name;
0283 } audio_ic[] = {
0284     /* 0-4 */
0285     { TVEEPROM_AUDPROC_NONE,  "None"      },
0286     { TVEEPROM_AUDPROC_OTHER, "TEA6300"   },
0287     { TVEEPROM_AUDPROC_OTHER, "TEA6320"   },
0288     { TVEEPROM_AUDPROC_OTHER, "TDA9850"   },
0289     { TVEEPROM_AUDPROC_MSP,   "MSP3400C"  },
0290     /* 5-9 */
0291     { TVEEPROM_AUDPROC_MSP,   "MSP3410D"  },
0292     { TVEEPROM_AUDPROC_MSP,   "MSP3415"   },
0293     { TVEEPROM_AUDPROC_MSP,   "MSP3430"   },
0294     { TVEEPROM_AUDPROC_MSP,   "MSP3438"   },
0295     { TVEEPROM_AUDPROC_OTHER, "CS5331"    },
0296     /* 10-14 */
0297     { TVEEPROM_AUDPROC_MSP,   "MSP3435"   },
0298     { TVEEPROM_AUDPROC_MSP,   "MSP3440"   },
0299     { TVEEPROM_AUDPROC_MSP,   "MSP3445"   },
0300     { TVEEPROM_AUDPROC_MSP,   "MSP3411"   },
0301     { TVEEPROM_AUDPROC_MSP,   "MSP3416"   },
0302     /* 15-19 */
0303     { TVEEPROM_AUDPROC_MSP,   "MSP3425"   },
0304     { TVEEPROM_AUDPROC_MSP,   "MSP3451"   },
0305     { TVEEPROM_AUDPROC_MSP,   "MSP3418"   },
0306     { TVEEPROM_AUDPROC_OTHER, "Type 0x12" },
0307     { TVEEPROM_AUDPROC_OTHER, "OKI7716"   },
0308     /* 20-24 */
0309     { TVEEPROM_AUDPROC_MSP,   "MSP4410"   },
0310     { TVEEPROM_AUDPROC_MSP,   "MSP4420"   },
0311     { TVEEPROM_AUDPROC_MSP,   "MSP4440"   },
0312     { TVEEPROM_AUDPROC_MSP,   "MSP4450"   },
0313     { TVEEPROM_AUDPROC_MSP,   "MSP4408"   },
0314     /* 25-29 */
0315     { TVEEPROM_AUDPROC_MSP,   "MSP4418"   },
0316     { TVEEPROM_AUDPROC_MSP,   "MSP4428"   },
0317     { TVEEPROM_AUDPROC_MSP,   "MSP4448"   },
0318     { TVEEPROM_AUDPROC_MSP,   "MSP4458"   },
0319     { TVEEPROM_AUDPROC_MSP,   "Type 0x1d" },
0320     /* 30-34 */
0321     { TVEEPROM_AUDPROC_INTERNAL, "CX880"     },
0322     { TVEEPROM_AUDPROC_INTERNAL, "CX881"     },
0323     { TVEEPROM_AUDPROC_INTERNAL, "CX883"     },
0324     { TVEEPROM_AUDPROC_INTERNAL, "CX882"     },
0325     { TVEEPROM_AUDPROC_INTERNAL, "CX25840"   },
0326     /* 35-39 */
0327     { TVEEPROM_AUDPROC_INTERNAL, "CX25841"   },
0328     { TVEEPROM_AUDPROC_INTERNAL, "CX25842"   },
0329     { TVEEPROM_AUDPROC_INTERNAL, "CX25843"   },
0330     { TVEEPROM_AUDPROC_INTERNAL, "CX23418"   },
0331     { TVEEPROM_AUDPROC_INTERNAL, "CX23885"   },
0332     /* 40-44 */
0333     { TVEEPROM_AUDPROC_INTERNAL, "CX23888"   },
0334     { TVEEPROM_AUDPROC_INTERNAL, "SAA7131"   },
0335     { TVEEPROM_AUDPROC_INTERNAL, "CX23887"   },
0336     { TVEEPROM_AUDPROC_INTERNAL, "SAA7164"   },
0337     { TVEEPROM_AUDPROC_INTERNAL, "AU8522"    },
0338     /* 45-49 */
0339     { TVEEPROM_AUDPROC_INTERNAL, "AVF4910B"  },
0340     { TVEEPROM_AUDPROC_INTERNAL, "SAA7231"   },
0341     { TVEEPROM_AUDPROC_INTERNAL, "CX23102"   },
0342     { TVEEPROM_AUDPROC_INTERNAL, "SAA7163"   },
0343     { TVEEPROM_AUDPROC_OTHER,    "AK4113"    },
0344     /* 50-52 */
0345     { TVEEPROM_AUDPROC_OTHER,    "CS5340"    },
0346     { TVEEPROM_AUDPROC_OTHER,    "CS8416"    },
0347     { TVEEPROM_AUDPROC_OTHER,    "CX20810"   },
0348 };
0349 
0350 /* This list is supplied by Hauppauge. Thanks! */
0351 static const char *decoderIC[] = {
0352     /* 0-4 */
0353     "None", "BT815", "BT817", "BT819", "BT815A",
0354     /* 5-9 */
0355     "BT817A", "BT819A", "BT827", "BT829", "BT848",
0356     /* 10-14 */
0357     "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
0358     /* 15-19 */
0359     "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
0360     /* 20-24 */
0361     "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
0362     /* 25-29 */
0363     "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
0364     /* 30-34 */
0365     "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
0366     /* 35-39 */
0367     "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
0368     /* 40-44 */
0369     "SAA7164", "CX23885B", "AU8522", "ADV7401", "AVF4910B",
0370     /* 45-49 */
0371     "SAA7231", "CX23102", "SAA7163", "ADV7441A", "ADV7181C",
0372     /* 50-53 */
0373     "CX25836", "TDA9955", "TDA19977", "ADV7842"
0374 };
0375 
0376 static int hasRadioTuner(int tunerType)
0377 {
0378     switch (tunerType) {
0379     case 18: /* PNPEnv_TUNER_FR1236_MK2 */
0380     case 23: /* PNPEnv_TUNER_FM1236 */
0381     case 38: /* PNPEnv_TUNER_FMR1236 */
0382     case 16: /* PNPEnv_TUNER_FR1216_MK2 */
0383     case 19: /* PNPEnv_TUNER_FR1246_MK2 */
0384     case 21: /* PNPEnv_TUNER_FM1216 */
0385     case 24: /* PNPEnv_TUNER_FM1246 */
0386     case 17: /* PNPEnv_TUNER_FR1216MF_MK2 */
0387     case 22: /* PNPEnv_TUNER_FM1216MF */
0388     case 20: /* PNPEnv_TUNER_FR1256_MK2 */
0389     case 25: /* PNPEnv_TUNER_FM1256 */
0390     case 33: /* PNPEnv_TUNER_4039FR5 */
0391     case 42: /* PNPEnv_TUNER_4009FR5 */
0392     case 52: /* PNPEnv_TUNER_4049FM5 */
0393     case 54: /* PNPEnv_TUNER_4049FM5_AltI2C */
0394     case 44: /* PNPEnv_TUNER_4009FN5 */
0395     case 31: /* PNPEnv_TUNER_TCPB9085P */
0396     case 30: /* PNPEnv_TUNER_TCPN9085D */
0397     case 46: /* PNPEnv_TUNER_TP18NSR01F */
0398     case 47: /* PNPEnv_TUNER_TP18PSB01D */
0399     case 49: /* PNPEnv_TUNER_TAPC_I001D */
0400     case 60: /* PNPEnv_TUNER_TAPE_S001D_MK3 */
0401     case 57: /* PNPEnv_TUNER_FM1216ME_MK3 */
0402     case 59: /* PNPEnv_TUNER_FM1216MP_MK3 */
0403     case 58: /* PNPEnv_TUNER_FM1236_MK3 */
0404     case 68: /* PNPEnv_TUNER_TAPE_H001F_MK3 */
0405     case 61: /* PNPEnv_TUNER_TAPE_M001D_MK3 */
0406     case 78: /* PNPEnv_TUNER_TDA8275C1_8290_FM */
0407     case 89: /* PNPEnv_TUNER_TCL_MFPE05_2 */
0408     case 92: /* PNPEnv_TUNER_PHILIPS_FQ1236A_MK4 */
0409     case 105:
0410         return 1;
0411     }
0412     return 0;
0413 }
0414 
0415 void tveeprom_hauppauge_analog(struct tveeprom *tvee,
0416                    unsigned char *eeprom_data)
0417 {
0418     /* ----------------------------------------------
0419     ** The hauppauge eeprom format is tagged
0420     **
0421     ** if packet[0] == 0x84, then packet[0..1] == length
0422     ** else length = packet[0] & 3f;
0423     ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
0424     **
0425     ** In our (ivtv) case we're interested in the following:
0426     ** tuner type:   tag [00].05 or [0a].01 (index into hauppauge_tuner)
0427     ** tuner fmts:   tag [00].04 or [0a].00 (bitmask index into
0428     **       hauppauge_tuner_fmt)
0429     ** radio:        tag [00].{last} or [0e].00  (bitmask.  bit2=FM)
0430     ** audio proc:   tag [02].01 or [05].00 (mask with 0x7f)
0431     ** decoder proc: tag [09].01)
0432 
0433     ** Fun info:
0434     ** model:      tag [00].07-08 or [06].00-01
0435     ** revision:   tag [00].09-0b or [06].04-06
0436     ** serial#:    tag [01].05-07 or [04].04-06
0437 
0438     ** # of inputs/outputs ???
0439     */
0440 
0441     int i, j, len, done, beenhere, tag, start;
0442 
0443     int tuner1 = 0, t_format1 = 0, audioic = -1;
0444     const char *t_name1 = NULL;
0445     const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
0446 
0447     int tuner2 = 0, t_format2 = 0;
0448     const char *t_name2 = NULL;
0449     const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
0450 
0451     memset(tvee, 0, sizeof(*tvee));
0452     tvee->tuner_type = TUNER_ABSENT;
0453     tvee->tuner2_type = TUNER_ABSENT;
0454 
0455     done = len = beenhere = 0;
0456 
0457     /* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
0458     if (eeprom_data[0] == 0x1a &&
0459         eeprom_data[1] == 0xeb &&
0460         eeprom_data[2] == 0x67 &&
0461         eeprom_data[3] == 0x95)
0462         start = 0xa0; /* Generic em28xx offset */
0463     else if ((eeprom_data[0] & 0xe1) == 0x01 &&
0464          eeprom_data[1] == 0x00 &&
0465          eeprom_data[2] == 0x00 &&
0466          eeprom_data[8] == 0x84)
0467         start = 8; /* Generic cx2388x offset */
0468     else if (eeprom_data[1] == 0x70 &&
0469          eeprom_data[2] == 0x00 &&
0470          eeprom_data[4] == 0x74 &&
0471          eeprom_data[8] == 0x84)
0472         start = 8; /* Generic cx23418 offset (models 74xxx) */
0473     else
0474         start = 0;
0475 
0476     for (i = start; !done && i < 256; i += len) {
0477         if (eeprom_data[i] == 0x84) {
0478             len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
0479             i += 3;
0480         } else if ((eeprom_data[i] & 0xf0) == 0x70) {
0481             if (eeprom_data[i] & 0x08) {
0482                 /* verify checksum! */
0483                 done = 1;
0484                 break;
0485             }
0486             len = eeprom_data[i] & 0x07;
0487             ++i;
0488         } else {
0489             pr_warn("Encountered bad packet header [%02x]. Corrupt or not a Hauppauge eeprom.\n",
0490                 eeprom_data[i]);
0491             return;
0492         }
0493 
0494         pr_debug("Tag [%02x] + %d bytes: %*ph\n",
0495             eeprom_data[i], len - 1, len, &eeprom_data[i]);
0496 
0497         /* process by tag */
0498         tag = eeprom_data[i];
0499         switch (tag) {
0500         case 0x00:
0501             /* tag: 'Comprehensive' */
0502             tuner1 = eeprom_data[i+6];
0503             t_format1 = eeprom_data[i+5];
0504             tvee->has_radio = eeprom_data[i+len-1];
0505             /* old style tag, don't know how to detect
0506             IR presence, mark as unknown. */
0507             tvee->has_ir = 0;
0508             tvee->model =
0509                 eeprom_data[i+8] +
0510                 (eeprom_data[i+9] << 8);
0511             tvee->revision = eeprom_data[i+10] +
0512                 (eeprom_data[i+11] << 8) +
0513                 (eeprom_data[i+12] << 16);
0514             break;
0515 
0516         case 0x01:
0517             /* tag: 'SerialID' */
0518             tvee->serial_number =
0519                 eeprom_data[i+6] +
0520                 (eeprom_data[i+7] << 8) +
0521                 (eeprom_data[i+8] << 16);
0522             break;
0523 
0524         case 0x02:
0525             /* tag 'AudioInfo'
0526             Note mask with 0x7F, high bit used on some older models
0527             to indicate 4052 mux was removed in favor of using MSP
0528             inputs directly. */
0529             audioic = eeprom_data[i+2] & 0x7f;
0530             if (audioic < ARRAY_SIZE(audio_ic))
0531                 tvee->audio_processor = audio_ic[audioic].id;
0532             else
0533                 tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
0534             break;
0535 
0536         /* case 0x03: tag 'EEInfo' */
0537 
0538         case 0x04:
0539             /* tag 'SerialID2' */
0540             tvee->serial_number =
0541                 eeprom_data[i+5] +
0542                 (eeprom_data[i+6] << 8) +
0543                 (eeprom_data[i+7] << 16)+
0544                 (eeprom_data[i+8] << 24);
0545 
0546             if (eeprom_data[i + 8] == 0xf0) {
0547                 tvee->MAC_address[0] = 0x00;
0548                 tvee->MAC_address[1] = 0x0D;
0549                 tvee->MAC_address[2] = 0xFE;
0550                 tvee->MAC_address[3] = eeprom_data[i + 7];
0551                 tvee->MAC_address[4] = eeprom_data[i + 6];
0552                 tvee->MAC_address[5] = eeprom_data[i + 5];
0553                 tvee->has_MAC_address = 1;
0554             }
0555             break;
0556 
0557         case 0x05:
0558             /* tag 'Audio2'
0559             Note mask with 0x7F, high bit used on some older models
0560             to indicate 4052 mux was removed in favor of using MSP
0561             inputs directly. */
0562             audioic = eeprom_data[i+1] & 0x7f;
0563             if (audioic < ARRAY_SIZE(audio_ic))
0564                 tvee->audio_processor = audio_ic[audioic].id;
0565             else
0566                 tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
0567 
0568             break;
0569 
0570         case 0x06:
0571             /* tag 'ModelRev' */
0572             tvee->model =
0573                 eeprom_data[i + 1] +
0574                 (eeprom_data[i + 2] << 8) +
0575                 (eeprom_data[i + 3] << 16) +
0576                 (eeprom_data[i + 4] << 24);
0577             tvee->revision =
0578                 eeprom_data[i + 5] +
0579                 (eeprom_data[i + 6] << 8) +
0580                 (eeprom_data[i + 7] << 16);
0581             break;
0582 
0583         case 0x07:
0584             /* tag 'Details': according to Hauppauge not interesting
0585             on any PCI-era or later boards. */
0586             break;
0587 
0588         /* there is no tag 0x08 defined */
0589 
0590         case 0x09:
0591             /* tag 'Video' */
0592             tvee->decoder_processor = eeprom_data[i + 1];
0593             break;
0594 
0595         case 0x0a:
0596             /* tag 'Tuner' */
0597             if (beenhere == 0) {
0598                 tuner1 = eeprom_data[i + 2];
0599                 t_format1 = eeprom_data[i + 1];
0600                 beenhere = 1;
0601             } else {
0602                 /* a second (radio) tuner may be present */
0603                 tuner2 = eeprom_data[i + 2];
0604                 t_format2 = eeprom_data[i + 1];
0605                 /* not a TV tuner? */
0606                 if (t_format2 == 0)
0607                     tvee->has_radio = 1; /* must be radio */
0608             }
0609             break;
0610 
0611         case 0x0b:
0612             /* tag 'Inputs': according to Hauppauge this is specific
0613             to each driver family, so no good assumptions can be
0614             made. */
0615             break;
0616 
0617         /* case 0x0c: tag 'Balun' */
0618         /* case 0x0d: tag 'Teletext' */
0619 
0620         case 0x0e:
0621             /* tag: 'Radio' */
0622             tvee->has_radio = eeprom_data[i+1];
0623             break;
0624 
0625         case 0x0f:
0626             /* tag 'IRInfo' */
0627             tvee->has_ir = 1 | (eeprom_data[i+1] << 1);
0628             break;
0629 
0630         /* case 0x10: tag 'VBIInfo' */
0631         /* case 0x11: tag 'QCInfo' */
0632         /* case 0x12: tag 'InfoBits' */
0633 
0634         default:
0635             pr_debug("Not sure what to do with tag [%02x]\n",
0636                     tag);
0637             /* dump the rest of the packet? */
0638         }
0639     }
0640 
0641     if (!done) {
0642         pr_warn("Ran out of data!\n");
0643         return;
0644     }
0645 
0646     if (tvee->revision != 0) {
0647         tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
0648         tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
0649         tvee->rev_str[2] = 32 + ((tvee->revision >>  6) & 0x3f);
0650         tvee->rev_str[3] = 32 + (tvee->revision & 0x3f);
0651         tvee->rev_str[4] = 0;
0652     }
0653 
0654     if (hasRadioTuner(tuner1) && !tvee->has_radio) {
0655         pr_info("The eeprom says no radio is present, but the tuner type\n");
0656         pr_info("indicates otherwise. I will assume that radio is present.\n");
0657         tvee->has_radio = 1;
0658     }
0659 
0660     if (tuner1 < ARRAY_SIZE(hauppauge_tuner)) {
0661         tvee->tuner_type = hauppauge_tuner[tuner1].id;
0662         t_name1 = hauppauge_tuner[tuner1].name;
0663     } else {
0664         t_name1 = "unknown";
0665     }
0666 
0667     if (tuner2 < ARRAY_SIZE(hauppauge_tuner)) {
0668         tvee->tuner2_type = hauppauge_tuner[tuner2].id;
0669         t_name2 = hauppauge_tuner[tuner2].name;
0670     } else {
0671         t_name2 = "unknown";
0672     }
0673 
0674     tvee->tuner_hauppauge_model = tuner1;
0675     tvee->tuner2_hauppauge_model = tuner2;
0676     tvee->tuner_formats = 0;
0677     tvee->tuner2_formats = 0;
0678     for (i = j = 0; i < 8; i++) {
0679         if (t_format1 & (1 << i)) {
0680             tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
0681             t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
0682         }
0683     }
0684     for (i = j = 0; i < 8; i++) {
0685         if (t_format2 & (1 << i)) {
0686             tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
0687             t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
0688         }
0689     }
0690 
0691     pr_info("Hauppauge model %d, rev %s, serial# %u\n",
0692         tvee->model, tvee->rev_str, tvee->serial_number);
0693     if (tvee->has_MAC_address == 1)
0694         pr_info("MAC address is %pM\n", tvee->MAC_address);
0695     pr_info("tuner model is %s (idx %d, type %d)\n",
0696         t_name1, tuner1, tvee->tuner_type);
0697     pr_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
0698         t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2],
0699         t_fmt_name1[3], t_fmt_name1[4], t_fmt_name1[5],
0700         t_fmt_name1[6], t_fmt_name1[7], t_format1);
0701     if (tuner2)
0702         pr_info("second tuner model is %s (idx %d, type %d)\n",
0703                     t_name2, tuner2, tvee->tuner2_type);
0704     if (t_format2)
0705         pr_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
0706             t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2],
0707             t_fmt_name2[3], t_fmt_name2[4], t_fmt_name2[5],
0708             t_fmt_name2[6], t_fmt_name2[7], t_format2);
0709     if (audioic < 0) {
0710         pr_info("audio processor is unknown (no idx)\n");
0711         tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
0712     } else {
0713         if (audioic < ARRAY_SIZE(audio_ic))
0714             pr_info("audio processor is %s (idx %d)\n",
0715                     audio_ic[audioic].name, audioic);
0716         else
0717             pr_info("audio processor is unknown (idx %d)\n",
0718                                 audioic);
0719     }
0720     if (tvee->decoder_processor)
0721         pr_info("decoder processor is %s (idx %d)\n",
0722             STRM(decoderIC, tvee->decoder_processor),
0723             tvee->decoder_processor);
0724     if (tvee->has_ir)
0725         pr_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
0726                 tvee->has_radio ? "" : "no ",
0727                 (tvee->has_ir & 2) ? "" : "no ",
0728                 (tvee->has_ir & 4) ? "" : "no ");
0729     else
0730         pr_info("has %sradio\n",
0731                 tvee->has_radio ? "" : "no ");
0732 }
0733 EXPORT_SYMBOL(tveeprom_hauppauge_analog);
0734 
0735 /* ----------------------------------------------------------------------- */
0736 /* generic helper functions                                                */
0737 
0738 int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
0739 {
0740     unsigned char buf;
0741     int err;
0742 
0743     buf = 0;
0744     err = i2c_master_send(c, &buf, 1);
0745     if (err != 1) {
0746         pr_info("Huh, no eeprom present (err=%d)?\n", err);
0747         return -1;
0748     }
0749     err = i2c_master_recv(c, eedata, len);
0750     if (err != len) {
0751         pr_warn("i2c eeprom read error (err=%d)\n", err);
0752         return -1;
0753     }
0754 
0755     print_hex_dump_debug("full 256-byte eeprom dump:", DUMP_PREFIX_NONE,
0756                  16, 1, eedata, len, true);
0757     return 0;
0758 }
0759 EXPORT_SYMBOL(tveeprom_read);