18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * tveeprom - eeprom decoder for tvcard configuration eeproms 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Data and decoding routines shamelessly borrowed from bttv-cards.c 68c2ecf20Sopenharmony_ci * eeprom access routine shamelessly borrowed from bttv-if.c 78c2ecf20Sopenharmony_ci * which are: 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 108c2ecf20Sopenharmony_ci & Marcus Metzler (mocm@thp.uni-koeln.de) 118c2ecf20Sopenharmony_ci (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci * Adjustments to fit a more general model and all bugs: 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci Copyright (C) 2003 John Klar <linpvr at projectplasma.com> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <linux/module.h> 228c2ecf20Sopenharmony_ci#include <linux/errno.h> 238c2ecf20Sopenharmony_ci#include <linux/kernel.h> 248c2ecf20Sopenharmony_ci#include <linux/init.h> 258c2ecf20Sopenharmony_ci#include <linux/types.h> 268c2ecf20Sopenharmony_ci#include <linux/videodev2.h> 278c2ecf20Sopenharmony_ci#include <linux/i2c.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include <media/tuner.h> 308c2ecf20Sopenharmony_ci#include <media/tveeprom.h> 318c2ecf20Sopenharmony_ci#include <media/v4l2-common.h> 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); 348c2ecf20Sopenharmony_ciMODULE_AUTHOR("John Klar"); 358c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define STRM(array, i) \ 388c2ecf20Sopenharmony_ci (i < sizeof(array) / sizeof(char *) ? array[i] : "unknown") 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* 428c2ecf20Sopenharmony_ci * The Hauppauge eeprom uses an 8bit field to determine which 438c2ecf20Sopenharmony_ci * tuner formats the tuner supports. 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_cistatic const struct { 468c2ecf20Sopenharmony_ci int id; 478c2ecf20Sopenharmony_ci const char * const name; 488c2ecf20Sopenharmony_ci} hauppauge_tuner_fmt[] = { 498c2ecf20Sopenharmony_ci { V4L2_STD_UNKNOWN, " UNKNOWN" }, 508c2ecf20Sopenharmony_ci { V4L2_STD_UNKNOWN, " FM" }, 518c2ecf20Sopenharmony_ci { V4L2_STD_B|V4L2_STD_GH, " PAL(B/G)" }, 528c2ecf20Sopenharmony_ci { V4L2_STD_MN, " NTSC(M)" }, 538c2ecf20Sopenharmony_ci { V4L2_STD_PAL_I, " PAL(I)" }, 548c2ecf20Sopenharmony_ci { V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, " SECAM(L/L')" }, 558c2ecf20Sopenharmony_ci { V4L2_STD_DK, " PAL(D/D1/K)" }, 568c2ecf20Sopenharmony_ci { V4L2_STD_ATSC, " ATSC/DVB Digital" }, 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/* This is the full list of possible tuners. Many thanks to Hauppauge for 608c2ecf20Sopenharmony_ci supplying this information. Note that many tuners where only used for 618c2ecf20Sopenharmony_ci testing and never made it to the outside world. So you will only see 628c2ecf20Sopenharmony_ci a subset in actual produced cards. */ 638c2ecf20Sopenharmony_cistatic const struct { 648c2ecf20Sopenharmony_ci int id; 658c2ecf20Sopenharmony_ci const char * const name; 668c2ecf20Sopenharmony_ci} hauppauge_tuner[] = { 678c2ecf20Sopenharmony_ci /* 0-9 */ 688c2ecf20Sopenharmony_ci { TUNER_ABSENT, "None" }, 698c2ecf20Sopenharmony_ci { TUNER_ABSENT, "External" }, 708c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Unspecified" }, 718c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL, "Philips FI1216" }, 728c2ecf20Sopenharmony_ci { TUNER_PHILIPS_SECAM, "Philips FI1216MF" }, 738c2ecf20Sopenharmony_ci { TUNER_PHILIPS_NTSC, "Philips FI1236" }, 748c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_I, "Philips FI1246" }, 758c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_DK, "Philips FI1256" }, 768c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" }, 778c2ecf20Sopenharmony_ci { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" }, 788c2ecf20Sopenharmony_ci /* 10-19 */ 798c2ecf20Sopenharmony_ci { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" }, 808c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" }, 818c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_DK, "Philips FI1256 MK2" }, 828c2ecf20Sopenharmony_ci { TUNER_TEMIC_NTSC, "Temic 4032FY5" }, 838c2ecf20Sopenharmony_ci { TUNER_TEMIC_PAL, "Temic 4002FH5" }, 848c2ecf20Sopenharmony_ci { TUNER_TEMIC_PAL_I, "Temic 4062FY5" }, 858c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL, "Philips FR1216 MK2" }, 868c2ecf20Sopenharmony_ci { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" }, 878c2ecf20Sopenharmony_ci { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" }, 888c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" }, 898c2ecf20Sopenharmony_ci /* 20-29 */ 908c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_DK, "Philips FR1256 MK2" }, 918c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL, "Philips FM1216" }, 928c2ecf20Sopenharmony_ci { TUNER_PHILIPS_SECAM, "Philips FM1216MF" }, 938c2ecf20Sopenharmony_ci { TUNER_PHILIPS_NTSC, "Philips FM1236" }, 948c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_I, "Philips FM1246" }, 958c2ecf20Sopenharmony_ci { TUNER_PHILIPS_PAL_DK, "Philips FM1256" }, 968c2ecf20Sopenharmony_ci { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" }, 978c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung TCPN9082D" }, 988c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung TCPM9092P" }, 998c2ecf20Sopenharmony_ci { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" }, 1008c2ecf20Sopenharmony_ci /* 30-39 */ 1018c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung TCPN9085D" }, 1028c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung TCPB9085P" }, 1038c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung TCPL9091P" }, 1048c2ecf20Sopenharmony_ci { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, 1058c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, 1068c2ecf20Sopenharmony_ci { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, 1078c2ecf20Sopenharmony_ci { TUNER_PHILIPS_NTSC, "Philips TD1536" }, 1088c2ecf20Sopenharmony_ci { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, 1098c2ecf20Sopenharmony_ci { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ 1108c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FI1256MP" }, 1118c2ecf20Sopenharmony_ci /* 40-49 */ 1128c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung TCPQ9091P" }, 1138c2ecf20Sopenharmony_ci { TUNER_TEMIC_4006FN5_MULTI_PAL,"Temic 4006FN5" }, 1148c2ecf20Sopenharmony_ci { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" }, 1158c2ecf20Sopenharmony_ci { TUNER_TEMIC_4046FM5, "Temic 4046FM5" }, 1168c2ecf20Sopenharmony_ci { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" }, 1178c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips TD1536D FH 44"}, 1188c2ecf20Sopenharmony_ci { TUNER_LG_NTSC_FM, "LG TP18NSR01F"}, 1198c2ecf20Sopenharmony_ci { TUNER_LG_PAL_FM, "LG TP18PSB01D"}, 1208c2ecf20Sopenharmony_ci { TUNER_LG_PAL, "LG TP18PSB11D"}, 1218c2ecf20Sopenharmony_ci { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"}, 1228c2ecf20Sopenharmony_ci /* 50-59 */ 1238c2ecf20Sopenharmony_ci { TUNER_LG_PAL_I, "LG TAPC-I701D"}, 1248c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Temic 4042FI5"}, 1258c2ecf20Sopenharmony_ci { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"}, 1268c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TPI8NSR11F"}, 1278c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"}, 1288c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"}, 1298c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FI1236 MK3"}, 1308c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"}, 1318c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"}, 1328c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FM1216MP MK3"}, 1338c2ecf20Sopenharmony_ci /* 60-69 */ 1348c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"}, 1358c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG M001D MK3"}, 1368c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1216ME_MK3, "LG S701D MK3"}, 1378c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG M701D MK3"}, 1388c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Temic 4146FM5"}, 1398c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Temic 4136FY5"}, 1408c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Temic 4106FH5"}, 1418c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FQ1216LMP MK3"}, 1428c2ecf20Sopenharmony_ci { TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"}, 1438c2ecf20Sopenharmony_ci { TUNER_LG_NTSC_TAPE, "LG TAPE H701F MK3"}, 1448c2ecf20Sopenharmony_ci /* 70-79 */ 1458c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TALN H200T"}, 1468c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TALN H250T"}, 1478c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TALN M200T"}, 1488c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TALN Z200T"}, 1498c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TALN S200T"}, 1508c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Thompson DTT7595"}, 1518c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Thompson DTT7592"}, 1528c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Silicon TDA8275C1 8290"}, 1538c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, 1548c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Thompson DTT757"}, 1558c2ecf20Sopenharmony_ci /* 80-89 */ 1568c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK3"}, 1578c2ecf20Sopenharmony_ci { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, 1588c2ecf20Sopenharmony_ci { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, 1598c2ecf20Sopenharmony_ci { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, 1608c2ecf20Sopenharmony_ci { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, 1618c2ecf20Sopenharmony_ci { TUNER_TCL_2002N, "TCL 2002N 6A"}, 1628c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"}, 1638c2ecf20Sopenharmony_ci { TUNER_SAMSUNG_TCPN_2121P30A, "Samsung TCPN 2121P30A"}, 1648c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, 1658c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, 1668c2ecf20Sopenharmony_ci /* 90-99 */ 1678c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TALN H202T"}, 1688c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"}, 1698c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FQ1236A_MK4, "Philips FQ1236A MK4"}, 1708c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FQ1286A MK4"}, 1718c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FQ1216ME MK5"}, 1728c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FQ1236 MK5"}, 1738c2ecf20Sopenharmony_ci { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"}, 1748c2ecf20Sopenharmony_ci { TUNER_TCL_2002MB, "TCL 2002MB_3H"}, 1758c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL 2002MI_3H"}, 1768c2ecf20Sopenharmony_ci { TUNER_TCL_2002N, "TCL 2002N 5H"}, 1778c2ecf20Sopenharmony_ci /* 100-109 */ 1788c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216ME"}, 1798c2ecf20Sopenharmony_ci { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, 1808c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Panasonic ENV57H12D5"}, 1818c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, 1828c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"}, 1838c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"}, 1848c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MQNM05-4"}, 1858c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TAPC-W701D"}, 1868c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL 9886P-WM"}, 1878c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL 1676NM-WM"}, 1888c2ecf20Sopenharmony_ci /* 110-119 */ 1898c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Thompson DTT75105"}, 1908c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Conexant_CX24109"}, 1918c2ecf20Sopenharmony_ci { TUNER_TCL_2002N, "TCL M2523_5N_E"}, 1928c2ecf20Sopenharmony_ci { TUNER_TCL_2002MB, "TCL M2523_3DB_E"}, 1938c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips 8275A"}, 1948c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Microtune MT2060"}, 1958c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK5"}, 1968c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216ME MK5"}, 1978c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL M2523_3DI_E"}, 1988c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Samsung THPD5222FG30A"}, 1998c2ecf20Sopenharmony_ci /* 120-129 */ 2008c2ecf20Sopenharmony_ci { TUNER_XC2028, "Xceive XC3028"}, 2018c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK5"}, 2028c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FQD1216LME"}, 2038c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Conexant CX24118A"}, 2048c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL DMF11WIP"}, 2058c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MFNM05_4H_E"}, 2068c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MNM05_4H_E"}, 2078c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MPE05_2H_E"}, 2088c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MQNM05_4_U"}, 2098c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL M2523_5NH_E"}, 2108c2ecf20Sopenharmony_ci /* 130-139 */ 2118c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL M2523_3DBH_E"}, 2128c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL M2523_3DIH_E"}, 2138c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MFPE05_2_U"}, 2148c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"}, 2158c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips FRH2036B"}, 2168c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Panasonic ENGF75_01GF"}, 2178c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear MXL5005"}, 2188c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear MXL5003"}, 2198c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Xceive XC2028"}, 2208c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Microtune MT2131"}, 2218c2ecf20Sopenharmony_ci /* 140-149 */ 2228c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Philips 8275A_8295"}, 2238c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MF02GIP_5N_E"}, 2248c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MF02GIP_3DB_E"}, 2258c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MF02GIP_3DI_E"}, 2268c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Microtune MT2266"}, 2278c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL MF10WPP_4N_E"}, 2288c2ecf20Sopenharmony_ci { TUNER_ABSENT, "LG TAPQ_H702F"}, 2298c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL M09WPP_4N_E"}, 2308c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear MXL5005_v2"}, 2318c2ecf20Sopenharmony_ci { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"}, 2328c2ecf20Sopenharmony_ci /* 150-159 */ 2338c2ecf20Sopenharmony_ci { TUNER_XC5000, "Xceive XC5000"}, 2348c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Xceive XC3028L"}, 2358c2ecf20Sopenharmony_ci { TUNER_ABSENT, "NXP 18271C2_716x"}, 2368c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Xceive XC4000"}, 2378c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Dibcom 7070"}, 2388c2ecf20Sopenharmony_ci { TUNER_PHILIPS_TDA8290, "NXP 18271C2"}, 2398c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1010"}, 2408c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1150"}, 2418c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear 5007"}, 2428c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL M09WPP_2P_E"}, 2438c2ecf20Sopenharmony_ci /* 160-169 */ 2448c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1180"}, 2458c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Maxim_MAX2165"}, 2468c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1140"}, 2478c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1150 B1"}, 2488c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear 111"}, 2498c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Dibcom 7770"}, 2508c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1180VNS"}, 2518c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1184"}, 2528c2ecf20Sopenharmony_ci { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"}, 2538c2ecf20Sopenharmony_ci { TUNER_ABSENT, "TCL_M11WPP_2PN_E"}, 2548c2ecf20Sopenharmony_ci /* 170-179 */ 2558c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear 301"}, 2568c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Mirics MSi001"}, 2578c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear MxL241SF"}, 2588c2ecf20Sopenharmony_ci { TUNER_XC5000C, "Xceive XC5000C"}, 2598c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Montage M68TS2020"}, 2608c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Siano SMS1530"}, 2618c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Dibcom 7090"}, 2628c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Xceive XC5200C"}, 2638c2ecf20Sopenharmony_ci { TUNER_ABSENT, "NXP 18273"}, 2648c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Montage M88TS2022"}, 2658c2ecf20Sopenharmony_ci /* 180-188 */ 2668c2ecf20Sopenharmony_ci { TUNER_ABSENT, "NXP 18272M"}, 2678c2ecf20Sopenharmony_ci { TUNER_ABSENT, "NXP 18272S"}, 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci { TUNER_ABSENT, "Mirics MSi003"}, 2708c2ecf20Sopenharmony_ci { TUNER_ABSENT, "MaxLinear MxL256"}, 2718c2ecf20Sopenharmony_ci { TUNER_ABSENT, "SiLabs Si2158"}, 2728c2ecf20Sopenharmony_ci { TUNER_ABSENT, "SiLabs Si2178"}, 2738c2ecf20Sopenharmony_ci { TUNER_ABSENT, "SiLabs Si2157"}, 2748c2ecf20Sopenharmony_ci { TUNER_ABSENT, "SiLabs Si2177"}, 2758c2ecf20Sopenharmony_ci { TUNER_ABSENT, "ITE IT9137FN"}, 2768c2ecf20Sopenharmony_ci}; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci/* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are 2798c2ecf20Sopenharmony_ci * internal to a video chip, i.e. not a separate audio chip. */ 2808c2ecf20Sopenharmony_cistatic const struct { 2818c2ecf20Sopenharmony_ci u32 id; 2828c2ecf20Sopenharmony_ci const char * const name; 2838c2ecf20Sopenharmony_ci} audio_ic[] = { 2848c2ecf20Sopenharmony_ci /* 0-4 */ 2858c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_NONE, "None" }, 2868c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "TEA6300" }, 2878c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "TEA6320" }, 2888c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "TDA9850" }, 2898c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3400C" }, 2908c2ecf20Sopenharmony_ci /* 5-9 */ 2918c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3410D" }, 2928c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3415" }, 2938c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3430" }, 2948c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3438" }, 2958c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "CS5331" }, 2968c2ecf20Sopenharmony_ci /* 10-14 */ 2978c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3435" }, 2988c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3440" }, 2998c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3445" }, 3008c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3411" }, 3018c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3416" }, 3028c2ecf20Sopenharmony_ci /* 15-19 */ 3038c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3425" }, 3048c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3451" }, 3058c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP3418" }, 3068c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "Type 0x12" }, 3078c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "OKI7716" }, 3088c2ecf20Sopenharmony_ci /* 20-24 */ 3098c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4410" }, 3108c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4420" }, 3118c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4440" }, 3128c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4450" }, 3138c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4408" }, 3148c2ecf20Sopenharmony_ci /* 25-29 */ 3158c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4418" }, 3168c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4428" }, 3178c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4448" }, 3188c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "MSP4458" }, 3198c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_MSP, "Type 0x1d" }, 3208c2ecf20Sopenharmony_ci /* 30-34 */ 3218c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX880" }, 3228c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX881" }, 3238c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX883" }, 3248c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX882" }, 3258c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX25840" }, 3268c2ecf20Sopenharmony_ci /* 35-39 */ 3278c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX25841" }, 3288c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX25842" }, 3298c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX25843" }, 3308c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX23418" }, 3318c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX23885" }, 3328c2ecf20Sopenharmony_ci /* 40-44 */ 3338c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX23888" }, 3348c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "SAA7131" }, 3358c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX23887" }, 3368c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "SAA7164" }, 3378c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "AU8522" }, 3388c2ecf20Sopenharmony_ci /* 45-49 */ 3398c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "AVF4910B" }, 3408c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "SAA7231" }, 3418c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "CX23102" }, 3428c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_INTERNAL, "SAA7163" }, 3438c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "AK4113" }, 3448c2ecf20Sopenharmony_ci /* 50-52 */ 3458c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "CS5340" }, 3468c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "CS8416" }, 3478c2ecf20Sopenharmony_ci { TVEEPROM_AUDPROC_OTHER, "CX20810" }, 3488c2ecf20Sopenharmony_ci}; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci/* This list is supplied by Hauppauge. Thanks! */ 3518c2ecf20Sopenharmony_cistatic const char *decoderIC[] = { 3528c2ecf20Sopenharmony_ci /* 0-4 */ 3538c2ecf20Sopenharmony_ci "None", "BT815", "BT817", "BT819", "BT815A", 3548c2ecf20Sopenharmony_ci /* 5-9 */ 3558c2ecf20Sopenharmony_ci "BT817A", "BT819A", "BT827", "BT829", "BT848", 3568c2ecf20Sopenharmony_ci /* 10-14 */ 3578c2ecf20Sopenharmony_ci "BT848A", "BT849A", "BT829A", "BT827A", "BT878", 3588c2ecf20Sopenharmony_ci /* 15-19 */ 3598c2ecf20Sopenharmony_ci "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115", 3608c2ecf20Sopenharmony_ci /* 20-24 */ 3618c2ecf20Sopenharmony_ci "CX880", "CX881", "CX883", "SAA7111", "SAA7113", 3628c2ecf20Sopenharmony_ci /* 25-29 */ 3638c2ecf20Sopenharmony_ci "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", 3648c2ecf20Sopenharmony_ci /* 30-34 */ 3658c2ecf20Sopenharmony_ci "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888", 3668c2ecf20Sopenharmony_ci /* 35-39 */ 3678c2ecf20Sopenharmony_ci "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A", 3688c2ecf20Sopenharmony_ci /* 40-44 */ 3698c2ecf20Sopenharmony_ci "SAA7164", "CX23885B", "AU8522", "ADV7401", "AVF4910B", 3708c2ecf20Sopenharmony_ci /* 45-49 */ 3718c2ecf20Sopenharmony_ci "SAA7231", "CX23102", "SAA7163", "ADV7441A", "ADV7181C", 3728c2ecf20Sopenharmony_ci /* 50-53 */ 3738c2ecf20Sopenharmony_ci "CX25836", "TDA9955", "TDA19977", "ADV7842" 3748c2ecf20Sopenharmony_ci}; 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_cistatic int hasRadioTuner(int tunerType) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci switch (tunerType) { 3798c2ecf20Sopenharmony_ci case 18: /* PNPEnv_TUNER_FR1236_MK2 */ 3808c2ecf20Sopenharmony_ci case 23: /* PNPEnv_TUNER_FM1236 */ 3818c2ecf20Sopenharmony_ci case 38: /* PNPEnv_TUNER_FMR1236 */ 3828c2ecf20Sopenharmony_ci case 16: /* PNPEnv_TUNER_FR1216_MK2 */ 3838c2ecf20Sopenharmony_ci case 19: /* PNPEnv_TUNER_FR1246_MK2 */ 3848c2ecf20Sopenharmony_ci case 21: /* PNPEnv_TUNER_FM1216 */ 3858c2ecf20Sopenharmony_ci case 24: /* PNPEnv_TUNER_FM1246 */ 3868c2ecf20Sopenharmony_ci case 17: /* PNPEnv_TUNER_FR1216MF_MK2 */ 3878c2ecf20Sopenharmony_ci case 22: /* PNPEnv_TUNER_FM1216MF */ 3888c2ecf20Sopenharmony_ci case 20: /* PNPEnv_TUNER_FR1256_MK2 */ 3898c2ecf20Sopenharmony_ci case 25: /* PNPEnv_TUNER_FM1256 */ 3908c2ecf20Sopenharmony_ci case 33: /* PNPEnv_TUNER_4039FR5 */ 3918c2ecf20Sopenharmony_ci case 42: /* PNPEnv_TUNER_4009FR5 */ 3928c2ecf20Sopenharmony_ci case 52: /* PNPEnv_TUNER_4049FM5 */ 3938c2ecf20Sopenharmony_ci case 54: /* PNPEnv_TUNER_4049FM5_AltI2C */ 3948c2ecf20Sopenharmony_ci case 44: /* PNPEnv_TUNER_4009FN5 */ 3958c2ecf20Sopenharmony_ci case 31: /* PNPEnv_TUNER_TCPB9085P */ 3968c2ecf20Sopenharmony_ci case 30: /* PNPEnv_TUNER_TCPN9085D */ 3978c2ecf20Sopenharmony_ci case 46: /* PNPEnv_TUNER_TP18NSR01F */ 3988c2ecf20Sopenharmony_ci case 47: /* PNPEnv_TUNER_TP18PSB01D */ 3998c2ecf20Sopenharmony_ci case 49: /* PNPEnv_TUNER_TAPC_I001D */ 4008c2ecf20Sopenharmony_ci case 60: /* PNPEnv_TUNER_TAPE_S001D_MK3 */ 4018c2ecf20Sopenharmony_ci case 57: /* PNPEnv_TUNER_FM1216ME_MK3 */ 4028c2ecf20Sopenharmony_ci case 59: /* PNPEnv_TUNER_FM1216MP_MK3 */ 4038c2ecf20Sopenharmony_ci case 58: /* PNPEnv_TUNER_FM1236_MK3 */ 4048c2ecf20Sopenharmony_ci case 68: /* PNPEnv_TUNER_TAPE_H001F_MK3 */ 4058c2ecf20Sopenharmony_ci case 61: /* PNPEnv_TUNER_TAPE_M001D_MK3 */ 4068c2ecf20Sopenharmony_ci case 78: /* PNPEnv_TUNER_TDA8275C1_8290_FM */ 4078c2ecf20Sopenharmony_ci case 89: /* PNPEnv_TUNER_TCL_MFPE05_2 */ 4088c2ecf20Sopenharmony_ci case 92: /* PNPEnv_TUNER_PHILIPS_FQ1236A_MK4 */ 4098c2ecf20Sopenharmony_ci case 105: 4108c2ecf20Sopenharmony_ci return 1; 4118c2ecf20Sopenharmony_ci } 4128c2ecf20Sopenharmony_ci return 0; 4138c2ecf20Sopenharmony_ci} 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_civoid tveeprom_hauppauge_analog(struct tveeprom *tvee, 4168c2ecf20Sopenharmony_ci unsigned char *eeprom_data) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci /* ---------------------------------------------- 4198c2ecf20Sopenharmony_ci ** The hauppauge eeprom format is tagged 4208c2ecf20Sopenharmony_ci ** 4218c2ecf20Sopenharmony_ci ** if packet[0] == 0x84, then packet[0..1] == length 4228c2ecf20Sopenharmony_ci ** else length = packet[0] & 3f; 4238c2ecf20Sopenharmony_ci ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum 4248c2ecf20Sopenharmony_ci ** 4258c2ecf20Sopenharmony_ci ** In our (ivtv) case we're interested in the following: 4268c2ecf20Sopenharmony_ci ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner) 4278c2ecf20Sopenharmony_ci ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into 4288c2ecf20Sopenharmony_ci ** hauppauge_tuner_fmt) 4298c2ecf20Sopenharmony_ci ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM) 4308c2ecf20Sopenharmony_ci ** audio proc: tag [02].01 or [05].00 (mask with 0x7f) 4318c2ecf20Sopenharmony_ci ** decoder proc: tag [09].01) 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci ** Fun info: 4348c2ecf20Sopenharmony_ci ** model: tag [00].07-08 or [06].00-01 4358c2ecf20Sopenharmony_ci ** revision: tag [00].09-0b or [06].04-06 4368c2ecf20Sopenharmony_ci ** serial#: tag [01].05-07 or [04].04-06 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci ** # of inputs/outputs ??? 4398c2ecf20Sopenharmony_ci */ 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci int i, j, len, done, beenhere, tag, start; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci int tuner1 = 0, t_format1 = 0, audioic = -1; 4448c2ecf20Sopenharmony_ci const char *t_name1 = NULL; 4458c2ecf20Sopenharmony_ci const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" }; 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci int tuner2 = 0, t_format2 = 0; 4488c2ecf20Sopenharmony_ci const char *t_name2 = NULL; 4498c2ecf20Sopenharmony_ci const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci memset(tvee, 0, sizeof(*tvee)); 4528c2ecf20Sopenharmony_ci tvee->tuner_type = TUNER_ABSENT; 4538c2ecf20Sopenharmony_ci tvee->tuner2_type = TUNER_ABSENT; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci done = len = beenhere = 0; 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci /* Different eeprom start offsets for em28xx, cx2388x and cx23418 */ 4588c2ecf20Sopenharmony_ci if (eeprom_data[0] == 0x1a && 4598c2ecf20Sopenharmony_ci eeprom_data[1] == 0xeb && 4608c2ecf20Sopenharmony_ci eeprom_data[2] == 0x67 && 4618c2ecf20Sopenharmony_ci eeprom_data[3] == 0x95) 4628c2ecf20Sopenharmony_ci start = 0xa0; /* Generic em28xx offset */ 4638c2ecf20Sopenharmony_ci else if ((eeprom_data[0] & 0xe1) == 0x01 && 4648c2ecf20Sopenharmony_ci eeprom_data[1] == 0x00 && 4658c2ecf20Sopenharmony_ci eeprom_data[2] == 0x00 && 4668c2ecf20Sopenharmony_ci eeprom_data[8] == 0x84) 4678c2ecf20Sopenharmony_ci start = 8; /* Generic cx2388x offset */ 4688c2ecf20Sopenharmony_ci else if (eeprom_data[1] == 0x70 && 4698c2ecf20Sopenharmony_ci eeprom_data[2] == 0x00 && 4708c2ecf20Sopenharmony_ci eeprom_data[4] == 0x74 && 4718c2ecf20Sopenharmony_ci eeprom_data[8] == 0x84) 4728c2ecf20Sopenharmony_ci start = 8; /* Generic cx23418 offset (models 74xxx) */ 4738c2ecf20Sopenharmony_ci else 4748c2ecf20Sopenharmony_ci start = 0; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci for (i = start; !done && i < 256; i += len) { 4778c2ecf20Sopenharmony_ci if (eeprom_data[i] == 0x84) { 4788c2ecf20Sopenharmony_ci len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); 4798c2ecf20Sopenharmony_ci i += 3; 4808c2ecf20Sopenharmony_ci } else if ((eeprom_data[i] & 0xf0) == 0x70) { 4818c2ecf20Sopenharmony_ci if (eeprom_data[i] & 0x08) { 4828c2ecf20Sopenharmony_ci /* verify checksum! */ 4838c2ecf20Sopenharmony_ci done = 1; 4848c2ecf20Sopenharmony_ci break; 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci len = eeprom_data[i] & 0x07; 4878c2ecf20Sopenharmony_ci ++i; 4888c2ecf20Sopenharmony_ci } else { 4898c2ecf20Sopenharmony_ci pr_warn("Encountered bad packet header [%02x]. Corrupt or not a Hauppauge eeprom.\n", 4908c2ecf20Sopenharmony_ci eeprom_data[i]); 4918c2ecf20Sopenharmony_ci return; 4928c2ecf20Sopenharmony_ci } 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci pr_debug("Tag [%02x] + %d bytes: %*ph\n", 4958c2ecf20Sopenharmony_ci eeprom_data[i], len - 1, len, &eeprom_data[i]); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci /* process by tag */ 4988c2ecf20Sopenharmony_ci tag = eeprom_data[i]; 4998c2ecf20Sopenharmony_ci switch (tag) { 5008c2ecf20Sopenharmony_ci case 0x00: 5018c2ecf20Sopenharmony_ci /* tag: 'Comprehensive' */ 5028c2ecf20Sopenharmony_ci tuner1 = eeprom_data[i+6]; 5038c2ecf20Sopenharmony_ci t_format1 = eeprom_data[i+5]; 5048c2ecf20Sopenharmony_ci tvee->has_radio = eeprom_data[i+len-1]; 5058c2ecf20Sopenharmony_ci /* old style tag, don't know how to detect 5068c2ecf20Sopenharmony_ci IR presence, mark as unknown. */ 5078c2ecf20Sopenharmony_ci tvee->has_ir = 0; 5088c2ecf20Sopenharmony_ci tvee->model = 5098c2ecf20Sopenharmony_ci eeprom_data[i+8] + 5108c2ecf20Sopenharmony_ci (eeprom_data[i+9] << 8); 5118c2ecf20Sopenharmony_ci tvee->revision = eeprom_data[i+10] + 5128c2ecf20Sopenharmony_ci (eeprom_data[i+11] << 8) + 5138c2ecf20Sopenharmony_ci (eeprom_data[i+12] << 16); 5148c2ecf20Sopenharmony_ci break; 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci case 0x01: 5178c2ecf20Sopenharmony_ci /* tag: 'SerialID' */ 5188c2ecf20Sopenharmony_ci tvee->serial_number = 5198c2ecf20Sopenharmony_ci eeprom_data[i+6] + 5208c2ecf20Sopenharmony_ci (eeprom_data[i+7] << 8) + 5218c2ecf20Sopenharmony_ci (eeprom_data[i+8] << 16); 5228c2ecf20Sopenharmony_ci break; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci case 0x02: 5258c2ecf20Sopenharmony_ci /* tag 'AudioInfo' 5268c2ecf20Sopenharmony_ci Note mask with 0x7F, high bit used on some older models 5278c2ecf20Sopenharmony_ci to indicate 4052 mux was removed in favor of using MSP 5288c2ecf20Sopenharmony_ci inputs directly. */ 5298c2ecf20Sopenharmony_ci audioic = eeprom_data[i+2] & 0x7f; 5308c2ecf20Sopenharmony_ci if (audioic < ARRAY_SIZE(audio_ic)) 5318c2ecf20Sopenharmony_ci tvee->audio_processor = audio_ic[audioic].id; 5328c2ecf20Sopenharmony_ci else 5338c2ecf20Sopenharmony_ci tvee->audio_processor = TVEEPROM_AUDPROC_OTHER; 5348c2ecf20Sopenharmony_ci break; 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci /* case 0x03: tag 'EEInfo' */ 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci case 0x04: 5398c2ecf20Sopenharmony_ci /* tag 'SerialID2' */ 5408c2ecf20Sopenharmony_ci tvee->serial_number = 5418c2ecf20Sopenharmony_ci eeprom_data[i+5] + 5428c2ecf20Sopenharmony_ci (eeprom_data[i+6] << 8) + 5438c2ecf20Sopenharmony_ci (eeprom_data[i+7] << 16)+ 5448c2ecf20Sopenharmony_ci (eeprom_data[i+8] << 24); 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci if (eeprom_data[i + 8] == 0xf0) { 5478c2ecf20Sopenharmony_ci tvee->MAC_address[0] = 0x00; 5488c2ecf20Sopenharmony_ci tvee->MAC_address[1] = 0x0D; 5498c2ecf20Sopenharmony_ci tvee->MAC_address[2] = 0xFE; 5508c2ecf20Sopenharmony_ci tvee->MAC_address[3] = eeprom_data[i + 7]; 5518c2ecf20Sopenharmony_ci tvee->MAC_address[4] = eeprom_data[i + 6]; 5528c2ecf20Sopenharmony_ci tvee->MAC_address[5] = eeprom_data[i + 5]; 5538c2ecf20Sopenharmony_ci tvee->has_MAC_address = 1; 5548c2ecf20Sopenharmony_ci } 5558c2ecf20Sopenharmony_ci break; 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci case 0x05: 5588c2ecf20Sopenharmony_ci /* tag 'Audio2' 5598c2ecf20Sopenharmony_ci Note mask with 0x7F, high bit used on some older models 5608c2ecf20Sopenharmony_ci to indicate 4052 mux was removed in favor of using MSP 5618c2ecf20Sopenharmony_ci inputs directly. */ 5628c2ecf20Sopenharmony_ci audioic = eeprom_data[i+1] & 0x7f; 5638c2ecf20Sopenharmony_ci if (audioic < ARRAY_SIZE(audio_ic)) 5648c2ecf20Sopenharmony_ci tvee->audio_processor = audio_ic[audioic].id; 5658c2ecf20Sopenharmony_ci else 5668c2ecf20Sopenharmony_ci tvee->audio_processor = TVEEPROM_AUDPROC_OTHER; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci break; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci case 0x06: 5718c2ecf20Sopenharmony_ci /* tag 'ModelRev' */ 5728c2ecf20Sopenharmony_ci tvee->model = 5738c2ecf20Sopenharmony_ci eeprom_data[i + 1] + 5748c2ecf20Sopenharmony_ci (eeprom_data[i + 2] << 8) + 5758c2ecf20Sopenharmony_ci (eeprom_data[i + 3] << 16) + 5768c2ecf20Sopenharmony_ci (eeprom_data[i + 4] << 24); 5778c2ecf20Sopenharmony_ci tvee->revision = 5788c2ecf20Sopenharmony_ci eeprom_data[i + 5] + 5798c2ecf20Sopenharmony_ci (eeprom_data[i + 6] << 8) + 5808c2ecf20Sopenharmony_ci (eeprom_data[i + 7] << 16); 5818c2ecf20Sopenharmony_ci break; 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci case 0x07: 5848c2ecf20Sopenharmony_ci /* tag 'Details': according to Hauppauge not interesting 5858c2ecf20Sopenharmony_ci on any PCI-era or later boards. */ 5868c2ecf20Sopenharmony_ci break; 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci /* there is no tag 0x08 defined */ 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci case 0x09: 5918c2ecf20Sopenharmony_ci /* tag 'Video' */ 5928c2ecf20Sopenharmony_ci tvee->decoder_processor = eeprom_data[i + 1]; 5938c2ecf20Sopenharmony_ci break; 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci case 0x0a: 5968c2ecf20Sopenharmony_ci /* tag 'Tuner' */ 5978c2ecf20Sopenharmony_ci if (beenhere == 0) { 5988c2ecf20Sopenharmony_ci tuner1 = eeprom_data[i + 2]; 5998c2ecf20Sopenharmony_ci t_format1 = eeprom_data[i + 1]; 6008c2ecf20Sopenharmony_ci beenhere = 1; 6018c2ecf20Sopenharmony_ci } else { 6028c2ecf20Sopenharmony_ci /* a second (radio) tuner may be present */ 6038c2ecf20Sopenharmony_ci tuner2 = eeprom_data[i + 2]; 6048c2ecf20Sopenharmony_ci t_format2 = eeprom_data[i + 1]; 6058c2ecf20Sopenharmony_ci /* not a TV tuner? */ 6068c2ecf20Sopenharmony_ci if (t_format2 == 0) 6078c2ecf20Sopenharmony_ci tvee->has_radio = 1; /* must be radio */ 6088c2ecf20Sopenharmony_ci } 6098c2ecf20Sopenharmony_ci break; 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci case 0x0b: 6128c2ecf20Sopenharmony_ci /* tag 'Inputs': according to Hauppauge this is specific 6138c2ecf20Sopenharmony_ci to each driver family, so no good assumptions can be 6148c2ecf20Sopenharmony_ci made. */ 6158c2ecf20Sopenharmony_ci break; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci /* case 0x0c: tag 'Balun' */ 6188c2ecf20Sopenharmony_ci /* case 0x0d: tag 'Teletext' */ 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci case 0x0e: 6218c2ecf20Sopenharmony_ci /* tag: 'Radio' */ 6228c2ecf20Sopenharmony_ci tvee->has_radio = eeprom_data[i+1]; 6238c2ecf20Sopenharmony_ci break; 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci case 0x0f: 6268c2ecf20Sopenharmony_ci /* tag 'IRInfo' */ 6278c2ecf20Sopenharmony_ci tvee->has_ir = 1 | (eeprom_data[i+1] << 1); 6288c2ecf20Sopenharmony_ci break; 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci /* case 0x10: tag 'VBIInfo' */ 6318c2ecf20Sopenharmony_ci /* case 0x11: tag 'QCInfo' */ 6328c2ecf20Sopenharmony_ci /* case 0x12: tag 'InfoBits' */ 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci default: 6358c2ecf20Sopenharmony_ci pr_debug("Not sure what to do with tag [%02x]\n", 6368c2ecf20Sopenharmony_ci tag); 6378c2ecf20Sopenharmony_ci /* dump the rest of the packet? */ 6388c2ecf20Sopenharmony_ci } 6398c2ecf20Sopenharmony_ci } 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci if (!done) { 6428c2ecf20Sopenharmony_ci pr_warn("Ran out of data!\n"); 6438c2ecf20Sopenharmony_ci return; 6448c2ecf20Sopenharmony_ci } 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci if (tvee->revision != 0) { 6478c2ecf20Sopenharmony_ci tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f); 6488c2ecf20Sopenharmony_ci tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f); 6498c2ecf20Sopenharmony_ci tvee->rev_str[2] = 32 + ((tvee->revision >> 6) & 0x3f); 6508c2ecf20Sopenharmony_ci tvee->rev_str[3] = 32 + (tvee->revision & 0x3f); 6518c2ecf20Sopenharmony_ci tvee->rev_str[4] = 0; 6528c2ecf20Sopenharmony_ci } 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci if (hasRadioTuner(tuner1) && !tvee->has_radio) { 6558c2ecf20Sopenharmony_ci pr_info("The eeprom says no radio is present, but the tuner type\n"); 6568c2ecf20Sopenharmony_ci pr_info("indicates otherwise. I will assume that radio is present.\n"); 6578c2ecf20Sopenharmony_ci tvee->has_radio = 1; 6588c2ecf20Sopenharmony_ci } 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci if (tuner1 < ARRAY_SIZE(hauppauge_tuner)) { 6618c2ecf20Sopenharmony_ci tvee->tuner_type = hauppauge_tuner[tuner1].id; 6628c2ecf20Sopenharmony_ci t_name1 = hauppauge_tuner[tuner1].name; 6638c2ecf20Sopenharmony_ci } else { 6648c2ecf20Sopenharmony_ci t_name1 = "unknown"; 6658c2ecf20Sopenharmony_ci } 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci if (tuner2 < ARRAY_SIZE(hauppauge_tuner)) { 6688c2ecf20Sopenharmony_ci tvee->tuner2_type = hauppauge_tuner[tuner2].id; 6698c2ecf20Sopenharmony_ci t_name2 = hauppauge_tuner[tuner2].name; 6708c2ecf20Sopenharmony_ci } else { 6718c2ecf20Sopenharmony_ci t_name2 = "unknown"; 6728c2ecf20Sopenharmony_ci } 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci tvee->tuner_hauppauge_model = tuner1; 6758c2ecf20Sopenharmony_ci tvee->tuner2_hauppauge_model = tuner2; 6768c2ecf20Sopenharmony_ci tvee->tuner_formats = 0; 6778c2ecf20Sopenharmony_ci tvee->tuner2_formats = 0; 6788c2ecf20Sopenharmony_ci for (i = j = 0; i < 8; i++) { 6798c2ecf20Sopenharmony_ci if (t_format1 & (1 << i)) { 6808c2ecf20Sopenharmony_ci tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; 6818c2ecf20Sopenharmony_ci t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name; 6828c2ecf20Sopenharmony_ci } 6838c2ecf20Sopenharmony_ci } 6848c2ecf20Sopenharmony_ci for (i = j = 0; i < 8; i++) { 6858c2ecf20Sopenharmony_ci if (t_format2 & (1 << i)) { 6868c2ecf20Sopenharmony_ci tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id; 6878c2ecf20Sopenharmony_ci t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name; 6888c2ecf20Sopenharmony_ci } 6898c2ecf20Sopenharmony_ci } 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_ci pr_info("Hauppauge model %d, rev %s, serial# %u\n", 6928c2ecf20Sopenharmony_ci tvee->model, tvee->rev_str, tvee->serial_number); 6938c2ecf20Sopenharmony_ci if (tvee->has_MAC_address == 1) 6948c2ecf20Sopenharmony_ci pr_info("MAC address is %pM\n", tvee->MAC_address); 6958c2ecf20Sopenharmony_ci pr_info("tuner model is %s (idx %d, type %d)\n", 6968c2ecf20Sopenharmony_ci t_name1, tuner1, tvee->tuner_type); 6978c2ecf20Sopenharmony_ci pr_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 6988c2ecf20Sopenharmony_ci t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], 6998c2ecf20Sopenharmony_ci t_fmt_name1[3], t_fmt_name1[4], t_fmt_name1[5], 7008c2ecf20Sopenharmony_ci t_fmt_name1[6], t_fmt_name1[7], t_format1); 7018c2ecf20Sopenharmony_ci if (tuner2) 7028c2ecf20Sopenharmony_ci pr_info("second tuner model is %s (idx %d, type %d)\n", 7038c2ecf20Sopenharmony_ci t_name2, tuner2, tvee->tuner2_type); 7048c2ecf20Sopenharmony_ci if (t_format2) 7058c2ecf20Sopenharmony_ci pr_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 7068c2ecf20Sopenharmony_ci t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], 7078c2ecf20Sopenharmony_ci t_fmt_name2[3], t_fmt_name2[4], t_fmt_name2[5], 7088c2ecf20Sopenharmony_ci t_fmt_name2[6], t_fmt_name2[7], t_format2); 7098c2ecf20Sopenharmony_ci if (audioic < 0) { 7108c2ecf20Sopenharmony_ci pr_info("audio processor is unknown (no idx)\n"); 7118c2ecf20Sopenharmony_ci tvee->audio_processor = TVEEPROM_AUDPROC_OTHER; 7128c2ecf20Sopenharmony_ci } else { 7138c2ecf20Sopenharmony_ci if (audioic < ARRAY_SIZE(audio_ic)) 7148c2ecf20Sopenharmony_ci pr_info("audio processor is %s (idx %d)\n", 7158c2ecf20Sopenharmony_ci audio_ic[audioic].name, audioic); 7168c2ecf20Sopenharmony_ci else 7178c2ecf20Sopenharmony_ci pr_info("audio processor is unknown (idx %d)\n", 7188c2ecf20Sopenharmony_ci audioic); 7198c2ecf20Sopenharmony_ci } 7208c2ecf20Sopenharmony_ci if (tvee->decoder_processor) 7218c2ecf20Sopenharmony_ci pr_info("decoder processor is %s (idx %d)\n", 7228c2ecf20Sopenharmony_ci STRM(decoderIC, tvee->decoder_processor), 7238c2ecf20Sopenharmony_ci tvee->decoder_processor); 7248c2ecf20Sopenharmony_ci if (tvee->has_ir) 7258c2ecf20Sopenharmony_ci pr_info("has %sradio, has %sIR receiver, has %sIR transmitter\n", 7268c2ecf20Sopenharmony_ci tvee->has_radio ? "" : "no ", 7278c2ecf20Sopenharmony_ci (tvee->has_ir & 2) ? "" : "no ", 7288c2ecf20Sopenharmony_ci (tvee->has_ir & 4) ? "" : "no "); 7298c2ecf20Sopenharmony_ci else 7308c2ecf20Sopenharmony_ci pr_info("has %sradio\n", 7318c2ecf20Sopenharmony_ci tvee->has_radio ? "" : "no "); 7328c2ecf20Sopenharmony_ci} 7338c2ecf20Sopenharmony_ciEXPORT_SYMBOL(tveeprom_hauppauge_analog); 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci/* ----------------------------------------------------------------------- */ 7368c2ecf20Sopenharmony_ci/* generic helper functions */ 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ciint tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len) 7398c2ecf20Sopenharmony_ci{ 7408c2ecf20Sopenharmony_ci unsigned char buf; 7418c2ecf20Sopenharmony_ci int err; 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci buf = 0; 7448c2ecf20Sopenharmony_ci err = i2c_master_send(c, &buf, 1); 7458c2ecf20Sopenharmony_ci if (err != 1) { 7468c2ecf20Sopenharmony_ci pr_info("Huh, no eeprom present (err=%d)?\n", err); 7478c2ecf20Sopenharmony_ci return -1; 7488c2ecf20Sopenharmony_ci } 7498c2ecf20Sopenharmony_ci err = i2c_master_recv(c, eedata, len); 7508c2ecf20Sopenharmony_ci if (err != len) { 7518c2ecf20Sopenharmony_ci pr_warn("i2c eeprom read error (err=%d)\n", err); 7528c2ecf20Sopenharmony_ci return -1; 7538c2ecf20Sopenharmony_ci } 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci print_hex_dump_debug("full 256-byte eeprom dump:", DUMP_PREFIX_NONE, 7568c2ecf20Sopenharmony_ci 16, 1, eedata, len, true); 7578c2ecf20Sopenharmony_ci return 0; 7588c2ecf20Sopenharmony_ci} 7598c2ecf20Sopenharmony_ciEXPORT_SYMBOL(tveeprom_read); 760