2005-04-17 02:20:36 +04:00
/*
* tveeprom - eeprom decoder for tvcard configuration eeproms
*
* Data and decoding routines shamelessly borrowed from bttv - cards . c
* eeprom access routine shamelessly borrowed from bttv - if . c
* which are :
Copyright ( C ) 1996 , 97 , 98 Ralph Metzler ( rjkm @ thp . uni - koeln . de )
2005-11-09 08:37:43 +03:00
& Marcus Metzler ( mocm @ thp . uni - koeln . de )
2005-04-17 02:20:36 +04:00
( c ) 1999 - 2001 Gerd Knorr < kraxel @ goldbach . in - berlin . de >
* Adjustments to fit a more general model and all bugs :
2005-11-09 08:37:43 +03:00
Copyright ( C ) 2003 John Klar < linpvr at projectplasma . com >
2005-04-17 02:20:36 +04:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/module.h>
# include <linux/errno.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/types.h>
2008-07-25 12:32:50 +04:00
# include <linux/videodev2.h>
2005-04-17 02:20:36 +04:00
# include <linux/i2c.h>
# include <media/tuner.h>
# include <media/tveeprom.h>
2006-01-09 20:32:40 +03:00
# include <media/v4l2-common.h>
2008-07-23 12:09:15 +04:00
# include <media/v4l2-chip-ident.h>
2005-04-17 02:20:36 +04:00
MODULE_DESCRIPTION ( " i2c Hauppauge eeprom decoder driver " ) ;
MODULE_AUTHOR ( " John Klar " ) ;
MODULE_LICENSE ( " GPL " ) ;
2007-12-12 12:50:20 +03:00
static int debug ;
2005-04-17 02:20:36 +04:00
module_param ( debug , int , 0644 ) ;
2005-09-10 00:04:05 +04:00
MODULE_PARM_DESC ( debug , " Debug level (0-1) " ) ;
2005-04-17 02:20:36 +04:00
2007-12-12 12:50:20 +03:00
# define STRM(array, i) \
( i < sizeof ( array ) / sizeof ( char * ) ? array [ i ] : " unknown " )
2005-04-17 02:20:36 +04:00
2006-01-09 20:32:40 +03:00
# define tveeprom_info(fmt, arg...) \
v4l_printk ( KERN_INFO , " tveeprom " , c - > adapter , c - > addr , fmt , # # arg )
# define tveeprom_warn(fmt, arg...) \
v4l_printk ( KERN_WARNING , " tveeprom " , c - > adapter , c - > addr , fmt , # # arg )
# define tveeprom_dbg(fmt, arg...) do { \
2005-09-10 00:04:05 +04:00
if ( debug ) \
2007-12-12 12:50:20 +03:00
v4l_printk ( KERN_DEBUG , " tveeprom " , \
c - > adapter , c - > addr , fmt , # # arg ) ; \
2006-01-09 20:32:40 +03:00
} while ( 0 )
2005-04-17 02:20:36 +04:00
2006-01-09 20:25:16 +03:00
/*
* The Hauppauge eeprom uses an 8 bit field to determine which
* tuner formats the tuner supports .
*/
2005-04-17 02:20:36 +04:00
static struct HAUPPAUGE_TUNER_FMT
{
int id ;
char * name ;
}
hauppauge_tuner_fmt [ ] =
{
2006-06-29 01:17:44 +04:00
{ V4L2_STD_UNKNOWN , " UNKNOWN " } ,
{ V4L2_STD_UNKNOWN , " FM " } ,
{ V4L2_STD_B | V4L2_STD_GH , " PAL(B/G) " } ,
{ V4L2_STD_MN , " NTSC(M) " } ,
{ V4L2_STD_PAL_I , " PAL(I) " } ,
{ V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC , " SECAM(L/L') " } ,
{ V4L2_STD_DK , " PAL(D/D1/K) " } ,
{ V4L2_STD_ATSC , " ATSC/DVB Digital " } ,
2005-04-17 02:20:36 +04:00
} ;
/* This is the full list of possible tuners. Many thanks to Hauppauge for
supplying this information . Note that many tuners where only used for
testing and never made it to the outside world . So you will only see
a subset in actual produced cards . */
static struct HAUPPAUGE_TUNER
{
int id ;
char * name ;
}
hauppauge_tuner [ ] =
{
/* 0-9 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " None " } ,
{ TUNER_ABSENT , " External " } ,
{ TUNER_ABSENT , " Unspecified " } ,
{ TUNER_PHILIPS_PAL , " Philips FI1216 " } ,
{ TUNER_PHILIPS_SECAM , " Philips FI1216MF " } ,
{ TUNER_PHILIPS_NTSC , " Philips FI1236 " } ,
{ TUNER_PHILIPS_PAL_I , " Philips FI1246 " } ,
{ TUNER_PHILIPS_PAL_DK , " Philips FI1256 " } ,
{ TUNER_PHILIPS_PAL , " Philips FI1216 MK2 " } ,
{ TUNER_PHILIPS_SECAM , " Philips FI1216MF MK2 " } ,
2005-04-17 02:20:36 +04:00
/* 10-19 */
2007-12-12 12:50:20 +03:00
{ TUNER_PHILIPS_NTSC , " Philips FI1236 MK2 " } ,
{ TUNER_PHILIPS_PAL_I , " Philips FI1246 MK2 " } ,
{ TUNER_PHILIPS_PAL_DK , " Philips FI1256 MK2 " } ,
{ TUNER_TEMIC_NTSC , " Temic 4032FY5 " } ,
{ TUNER_TEMIC_PAL , " Temic 4002FH5 " } ,
{ TUNER_TEMIC_PAL_I , " Temic 4062FY5 " } ,
{ TUNER_PHILIPS_PAL , " Philips FR1216 MK2 " } ,
{ TUNER_PHILIPS_SECAM , " Philips FR1216MF MK2 " } ,
{ TUNER_PHILIPS_NTSC , " Philips FR1236 MK2 " } ,
{ TUNER_PHILIPS_PAL_I , " Philips FR1246 MK2 " } ,
2005-04-17 02:20:36 +04:00
/* 20-29 */
2007-12-12 12:50:20 +03:00
{ TUNER_PHILIPS_PAL_DK , " Philips FR1256 MK2 " } ,
{ TUNER_PHILIPS_PAL , " Philips FM1216 " } ,
{ TUNER_PHILIPS_SECAM , " Philips FM1216MF " } ,
{ TUNER_PHILIPS_NTSC , " Philips FM1236 " } ,
{ TUNER_PHILIPS_PAL_I , " Philips FM1246 " } ,
{ TUNER_PHILIPS_PAL_DK , " Philips FM1256 " } ,
{ TUNER_TEMIC_4036FY5_NTSC , " Temic 4036FY5 " } ,
{ TUNER_ABSENT , " Samsung TCPN9082D " } ,
{ TUNER_ABSENT , " Samsung TCPM9092P " } ,
{ TUNER_TEMIC_4006FH5_PAL , " Temic 4006FH5 " } ,
2005-04-17 02:20:36 +04:00
/* 30-39 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " Samsung TCPN9085D " } ,
{ TUNER_ABSENT , " Samsung TCPB9085P " } ,
{ TUNER_ABSENT , " Samsung TCPL9091P " } ,
{ TUNER_TEMIC_4039FR5_NTSC , " Temic 4039FR5 " } ,
{ TUNER_PHILIPS_FQ1216ME , " Philips FQ1216 ME " } ,
{ TUNER_TEMIC_4066FY5_PAL_I , " Temic 4066FY5 " } ,
{ TUNER_PHILIPS_NTSC , " Philips TD1536 " } ,
{ TUNER_PHILIPS_NTSC , " Philips TD1536D " } ,
{ TUNER_PHILIPS_NTSC , " Philips FMR1236 " } , /* mono radio */
{ TUNER_ABSENT , " Philips FI1256MP " } ,
2005-04-17 02:20:36 +04:00
/* 40-49 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " Samsung TCPQ9091P " } ,
2005-04-17 02:20:36 +04:00
{ TUNER_TEMIC_4006FN5_MULTI_PAL , " Temic 4006FN5 " } ,
2007-12-12 12:50:20 +03:00
{ TUNER_TEMIC_4009FR5_PAL , " Temic 4009FR5 " } ,
{ TUNER_TEMIC_4046FM5 , " Temic 4046FM5 " } ,
2005-04-17 02:20:36 +04:00
{ TUNER_TEMIC_4009FN5_MULTI_PAL_FM , " Temic 4009FN5 " } ,
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " Philips TD1536D FH 44 " } ,
{ TUNER_LG_NTSC_FM , " LG TP18NSR01F " } ,
{ TUNER_LG_PAL_FM , " LG TP18PSB01D " } ,
{ TUNER_LG_PAL , " LG TP18PSB11D " } ,
{ TUNER_LG_PAL_I_FM , " LG TAPC-I001D " } ,
2005-04-17 02:20:36 +04:00
/* 50-59 */
2007-12-12 12:50:20 +03:00
{ TUNER_LG_PAL_I , " LG TAPC-I701D " } ,
{ TUNER_ABSENT , " Temic 4042FI5 " } ,
{ TUNER_MICROTUNE_4049FM5 , " Microtune 4049 FM5 " } ,
{ TUNER_ABSENT , " LG TPI8NSR11F " } ,
{ TUNER_ABSENT , " Microtune 4049 FM5 Alt I2C " } ,
{ TUNER_PHILIPS_FM1216ME_MK3 , " Philips FQ1216ME MK3 " } ,
{ TUNER_ABSENT , " Philips FI1236 MK3 " } ,
{ TUNER_PHILIPS_FM1216ME_MK3 , " Philips FM1216 ME MK3 " } ,
{ TUNER_PHILIPS_FM1236_MK3 , " Philips FM1236 MK3 " } ,
{ TUNER_ABSENT , " Philips FM1216MP MK3 " } ,
2005-04-17 02:20:36 +04:00
/* 60-69 */
2007-12-12 12:50:20 +03:00
{ TUNER_PHILIPS_FM1216ME_MK3 , " LG S001D MK3 " } ,
{ TUNER_ABSENT , " LG M001D MK3 " } ,
{ TUNER_PHILIPS_FM1216ME_MK3 , " LG S701D MK3 " } ,
{ TUNER_ABSENT , " LG M701D MK3 " } ,
{ TUNER_ABSENT , " Temic 4146FM5 " } ,
{ TUNER_ABSENT , " Temic 4136FY5 " } ,
{ TUNER_ABSENT , " Temic 4106FH5 " } ,
{ TUNER_ABSENT , " Philips FQ1216LMP MK3 " } ,
{ TUNER_LG_NTSC_TAPE , " LG TAPE H001F MK3 " } ,
{ TUNER_LG_NTSC_TAPE , " LG TAPE H701F MK3 " } ,
2005-04-17 02:20:36 +04:00
/* 70-79 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " LG TALN H200T " } ,
{ TUNER_ABSENT , " LG TALN H250T " } ,
{ TUNER_ABSENT , " LG TALN M200T " } ,
{ TUNER_ABSENT , " LG TALN Z200T " } ,
{ TUNER_ABSENT , " LG TALN S200T " } ,
{ TUNER_ABSENT , " Thompson DTT7595 " } ,
{ TUNER_ABSENT , " Thompson DTT7592 " } ,
{ TUNER_ABSENT , " Silicon TDA8275C1 8290 " } ,
{ TUNER_ABSENT , " Silicon TDA8275C1 8290 FM " } ,
{ TUNER_ABSENT , " Thompson DTT757 " } ,
2005-04-17 02:20:36 +04:00
/* 80-89 */
2009-06-08 04:39:03 +04:00
{ TUNER_PHILIPS_FQ1216LME_MK3 , " Philips FQ1216LME MK3 " } ,
2007-12-12 12:50:20 +03:00
{ TUNER_LG_PAL_NEW_TAPC , " LG TAPC G701D " } ,
{ TUNER_LG_NTSC_NEW_TAPC , " LG TAPC H791F " } ,
{ TUNER_LG_PAL_NEW_TAPC , " TCL 2002MB 3 " } ,
{ TUNER_LG_PAL_NEW_TAPC , " TCL 2002MI 3 " } ,
{ TUNER_TCL_2002N , " TCL 2002N 6A " } ,
{ TUNER_PHILIPS_FM1236_MK3 , " Philips FQ1236 MK3 " } ,
{ TUNER_SAMSUNG_TCPN_2121P30A , " Samsung TCPN 2121P30A " } ,
{ TUNER_ABSENT , " Samsung TCPE 4121P30A " } ,
{ TUNER_PHILIPS_FM1216ME_MK3 , " TCL MFPE05 2 " } ,
2005-04-17 02:20:36 +04:00
/* 90-99 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " LG TALN H202T " } ,
{ TUNER_PHILIPS_FQ1216AME_MK4 , " Philips FQ1216AME MK4 " } ,
{ TUNER_PHILIPS_FQ1236A_MK4 , " Philips FQ1236A MK4 " } ,
{ TUNER_ABSENT , " Philips FQ1286A MK4 " } ,
{ TUNER_ABSENT , " Philips FQ1216ME MK5 " } ,
{ TUNER_ABSENT , " Philips FQ1236 MK5 " } ,
{ TUNER_SAMSUNG_TCPG_6121P30A , " Samsung TCPG 6121P30A " } ,
{ TUNER_TCL_2002MB , " TCL 2002MB_3H " } ,
{ TUNER_ABSENT , " TCL 2002MI_3H " } ,
{ TUNER_TCL_2002N , " TCL 2002N 5H " } ,
2005-11-09 08:36:44 +03:00
/* 100-109 */
2007-12-12 12:50:20 +03:00
{ TUNER_PHILIPS_FMD1216ME_MK3 , " Philips FMD1216ME " } ,
{ TUNER_TEA5767 , " Philips TEA5768HL FM Radio " } ,
{ TUNER_ABSENT , " Panasonic ENV57H12D5 " } ,
{ TUNER_PHILIPS_FM1236_MK3 , " TCL MFNM05-4 " } ,
2009-05-09 07:43:40 +04:00
{ TUNER_PHILIPS_FM1236_MK3 , " TCL MNM05-4 " } ,
2007-12-12 12:50:20 +03:00
{ TUNER_PHILIPS_FM1216ME_MK3 , " TCL MPE05-2 " } ,
{ TUNER_ABSENT , " TCL MQNM05-4 " } ,
{ TUNER_ABSENT , " LG TAPC-W701D " } ,
{ TUNER_ABSENT , " TCL 9886P-WM " } ,
{ TUNER_ABSENT , " TCL 1676NM-WM " } ,
2005-12-01 11:51:27 +03:00
/* 110-119 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " Thompson DTT75105 " } ,
{ TUNER_ABSENT , " Conexant_CX24109 " } ,
{ TUNER_TCL_2002N , " TCL M2523_5N_E " } ,
{ TUNER_TCL_2002MB , " TCL M2523_3DB_E " } ,
{ TUNER_ABSENT , " Philips 8275A " } ,
{ TUNER_ABSENT , " Microtune MT2060 " } ,
{ TUNER_PHILIPS_FM1236_MK3 , " Philips FM1236 MK5 " } ,
{ TUNER_PHILIPS_FM1216ME_MK3 , " Philips FM1216ME MK5 " } ,
{ TUNER_ABSENT , " TCL M2523_3DI_E " } ,
{ TUNER_ABSENT , " Samsung THPD5222FG30A " } ,
2005-12-01 11:51:27 +03:00
/* 120-129 */
2007-12-12 12:50:20 +03:00
{ TUNER_XC2028 , " Xceive XC3028 " } ,
2009-06-08 04:39:03 +04:00
{ TUNER_PHILIPS_FQ1216LME_MK3 , " Philips FQ1216LME MK5 " } ,
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " Philips FQD1216LME " } ,
{ TUNER_ABSENT , " Conexant CX24118A " } ,
{ TUNER_ABSENT , " TCL DMF11WIP " } ,
{ TUNER_ABSENT , " TCL MFNM05_4H_E " } ,
{ TUNER_ABSENT , " TCL MNM05_4H_E " } ,
{ TUNER_ABSENT , " TCL MPE05_2H_E " } ,
{ TUNER_ABSENT , " TCL MQNM05_4_U " } ,
{ TUNER_ABSENT , " TCL M2523_5NH_E " } ,
2007-03-13 04:26:40 +03:00
/* 130-139 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " TCL M2523_3DBH_E " } ,
{ TUNER_ABSENT , " TCL M2523_3DIH_E " } ,
{ TUNER_ABSENT , " TCL MFPE05_2_U " } ,
2008-10-15 21:14:30 +04:00
{ TUNER_PHILIPS_FMD1216MEX_MK3 , " Philips FMD1216MEX " } ,
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " Philips FRH2036B " } ,
{ TUNER_ABSENT , " Panasonic ENGF75_01GF " } ,
{ TUNER_ABSENT , " MaxLinear MXL5005 " } ,
{ TUNER_ABSENT , " MaxLinear MXL5003 " } ,
{ TUNER_ABSENT , " Xceive XC2028 " } ,
{ TUNER_ABSENT , " Microtune MT2131 " } ,
2007-03-13 04:26:40 +03:00
/* 140-149 */
2007-12-12 12:50:20 +03:00
{ TUNER_ABSENT , " Philips 8275A_8295 " } ,
{ TUNER_ABSENT , " TCL MF02GIP_5N_E " } ,
{ TUNER_ABSENT , " TCL MF02GIP_3DB_E " } ,
{ TUNER_ABSENT , " TCL MF02GIP_3DI_E " } ,
{ TUNER_ABSENT , " Microtune MT2266 " } ,
{ TUNER_ABSENT , " TCL MF10WPP_4N_E " } ,
{ TUNER_ABSENT , " LG TAPQ_H702F " } ,
{ TUNER_ABSENT , " TCL M09WPP_4N_E " } ,
{ TUNER_ABSENT , " MaxLinear MXL5005_v2 " } ,
{ TUNER_PHILIPS_TDA8290 , " Philips 18271_8295 " } ,
2007-12-20 07:20:38 +03:00
/* 150-159 */
2009-03-11 09:00:49 +03:00
{ TUNER_XC5000 , " Xceive XC5000 " } ,
2009-01-06 20:10:59 +03:00
{ TUNER_ABSENT , " Xceive XC3028L " } ,
{ TUNER_ABSENT , " NXP 18271C2_716x " } ,
{ TUNER_ABSENT , " Xceive XC4000 " } ,
{ TUNER_ABSENT , " Dibcom 7070 " } ,
{ TUNER_PHILIPS_TDA8290 , " NXP 18271C2 " } ,
2005-04-17 02:20:36 +04:00
} ;
2008-07-23 12:09:15 +04:00
/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
* internal to a video chip , i . e . not a separate audio chip . */
2005-11-09 08:36:56 +03:00
static struct HAUPPAUGE_AUDIOIC
{
2008-07-23 12:09:15 +04:00
u32 id ;
2005-11-09 08:36:56 +03:00
char * name ;
}
audioIC [ ] =
{
/* 0-4 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_NONE , " None " } ,
{ V4L2_IDENT_UNKNOWN , " TEA6300 " } ,
{ V4L2_IDENT_UNKNOWN , " TEA6320 " } ,
{ V4L2_IDENT_UNKNOWN , " TDA9850 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3400C " } ,
2005-11-09 08:36:56 +03:00
/* 5-9 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_MSPX4XX , " MSP3410D " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3415 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3430 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3438 " } ,
{ V4L2_IDENT_UNKNOWN , " CS5331 " } ,
2005-11-09 08:36:56 +03:00
/* 10-14 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_MSPX4XX , " MSP3435 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3440 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3445 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3411 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3416 " } ,
2005-11-09 08:36:56 +03:00
/* 15-19 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_MSPX4XX , " MSP3425 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3451 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP3418 " } ,
{ V4L2_IDENT_UNKNOWN , " Type 0x12 " } ,
{ V4L2_IDENT_UNKNOWN , " OKI7716 " } ,
2005-11-09 08:36:56 +03:00
/* 20-24 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_MSPX4XX , " MSP4410 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP4420 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP4440 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP4450 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP4408 " } ,
2005-11-09 08:36:56 +03:00
/* 25-29 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_MSPX4XX , " MSP4418 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP4428 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP4448 " } ,
{ V4L2_IDENT_MSPX4XX , " MSP4458 " } ,
{ V4L2_IDENT_MSPX4XX , " Type 0x1d " } ,
2005-11-09 08:36:56 +03:00
/* 30-34 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_AMBIGUOUS , " CX880 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX881 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX883 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX882 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX25840 " } ,
2007-03-13 04:26:40 +03:00
/* 35-39 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_AMBIGUOUS , " CX25841 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX25842 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX25843 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX23418 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX23885 " } ,
2008-05-13 08:25:24 +04:00
/* 40-44 */
2008-07-23 12:09:15 +04:00
{ V4L2_IDENT_AMBIGUOUS , " CX23888 " } ,
{ V4L2_IDENT_AMBIGUOUS , " SAA7131 " } ,
{ V4L2_IDENT_AMBIGUOUS , " CX23887 " } ,
{ V4L2_IDENT_AMBIGUOUS , " SAA7164 " } ,
{ V4L2_IDENT_AMBIGUOUS , " AU8522 " } ,
2005-09-10 00:04:05 +04:00
} ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:05 +04:00
/* This list is supplied by Hauppauge. Thanks! */
static const char * decoderIC [ ] = {
2005-11-09 08:36:56 +03:00
/* 0-4 */
" None " , " BT815 " , " BT817 " , " BT819 " , " BT815A " ,
/* 5-9 */
" BT817A " , " BT819A " , " BT827 " , " BT829 " , " BT848 " ,
/* 10-14 */
" BT848A " , " BT849A " , " BT829A " , " BT827A " , " BT878 " ,
/* 15-19 */
" BT879 " , " BT880 " , " VPX3226E " , " SAA7114 " , " SAA7115 " ,
/* 20-24 */
" CX880 " , " CX881 " , " CX883 " , " SAA7111 " , " SAA7113 " ,
/* 25-29 */
" CX882 " , " TVP5150A " , " CX25840 " , " CX25841 " , " CX25842 " ,
2007-03-13 04:26:40 +03:00
/* 30-34 */
" CX25843 " , " CX23418 " , " NEC61153 " , " CX23885 " , " CX23888 " ,
2008-05-13 08:25:24 +04:00
/* 35-39 */
" SAA7131 " , " CX25837 " , " CX23887 " , " CX23885A " , " CX23887A " ,
/* 40-42 */
" SAA7164 " , " CX23885B " , " AU8522 "
2005-04-17 02:20:36 +04:00
} ;
static int hasRadioTuner ( int tunerType )
{
2005-11-09 08:37:43 +03:00
switch ( tunerType ) {
2007-12-12 12:50:20 +03:00
case 18 : /* PNPEnv_TUNER_FR1236_MK2 */
case 23 : /* PNPEnv_TUNER_FM1236 */
case 38 : /* PNPEnv_TUNER_FMR1236 */
case 16 : /* PNPEnv_TUNER_FR1216_MK2 */
case 19 : /* PNPEnv_TUNER_FR1246_MK2 */
case 21 : /* PNPEnv_TUNER_FM1216 */
case 24 : /* PNPEnv_TUNER_FM1246 */
case 17 : /* PNPEnv_TUNER_FR1216MF_MK2 */
case 22 : /* PNPEnv_TUNER_FM1216MF */
case 20 : /* PNPEnv_TUNER_FR1256_MK2 */
case 25 : /* PNPEnv_TUNER_FM1256 */
case 33 : /* PNPEnv_TUNER_4039FR5 */
case 42 : /* PNPEnv_TUNER_4009FR5 */
case 52 : /* PNPEnv_TUNER_4049FM5 */
case 54 : /* PNPEnv_TUNER_4049FM5_AltI2C */
case 44 : /* PNPEnv_TUNER_4009FN5 */
case 31 : /* PNPEnv_TUNER_TCPB9085P */
case 30 : /* PNPEnv_TUNER_TCPN9085D */
case 46 : /* PNPEnv_TUNER_TP18NSR01F */
case 47 : /* PNPEnv_TUNER_TP18PSB01D */
case 49 : /* PNPEnv_TUNER_TAPC_I001D */
case 60 : /* PNPEnv_TUNER_TAPE_S001D_MK3 */
case 57 : /* PNPEnv_TUNER_FM1216ME_MK3 */
case 59 : /* PNPEnv_TUNER_FM1216MP_MK3 */
case 58 : /* PNPEnv_TUNER_FM1236_MK3 */
case 68 : /* PNPEnv_TUNER_TAPE_H001F_MK3 */
case 61 : /* PNPEnv_TUNER_TAPE_M001D_MK3 */
case 78 : /* PNPEnv_TUNER_TDA8275C1_8290_FM */
case 89 : /* PNPEnv_TUNER_TCL_MFPE05_2 */
case 92 : /* PNPEnv_TUNER_PHILIPS_FQ1236A_MK4 */
case 105 :
2005-11-09 08:36:56 +03:00
return 1 ;
2005-11-09 08:37:43 +03:00
}
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:05 +04:00
void tveeprom_hauppauge_analog ( struct i2c_client * c , struct tveeprom * tvee ,
2005-11-09 08:37:45 +03:00
unsigned char * eeprom_data )
2005-04-17 02:20:36 +04:00
{
/* ----------------------------------------------
* * The hauppauge eeprom format is tagged
* *
* * if packet [ 0 ] = = 0x84 , then packet [ 0. .1 ] = = length
* * else length = packet [ 0 ] & 3f ;
* * if packet [ 0 ] & f8 = = f8 , then EOD and packet [ 1 ] = = checksum
* *
* * In our ( ivtv ) case we ' re interested in the following :
2005-09-10 00:04:05 +04:00
* * tuner type : tag [ 00 ] .05 or [ 0 a ] .01 ( index into hauppauge_tuner )
2007-12-12 12:50:20 +03:00
* * tuner fmts : tag [ 00 ] .04 or [ 0 a ] .00 ( bitmask index into
* * hauppauge_tuner_fmt )
2005-09-10 00:04:05 +04:00
* * radio : tag [ 00 ] . { last } or [ 0 e ] .00 ( bitmask . bit2 = FM )
* * audio proc : tag [ 02 ] .01 or [ 05 ] .00 ( mask with 0x7f )
* * decoder proc : tag [ 09 ] .01 )
2005-04-17 02:20:36 +04:00
* * Fun info :
* * model : tag [ 00 ] .07 - 08 or [ 06 ] .00 - 01
* * revision : tag [ 00 ] .09 - 0 b or [ 06 ] .04 - 06
* * serial # : tag [ 01 ] .05 - 07 or [ 04 ] .04 - 06
* * # of inputs / outputs ? ? ?
*/
2007-12-12 12:21:58 +03:00
int i , j , len , done , beenhere , tag , start ;
2005-04-17 02:20:36 +04:00
2007-12-12 12:21:58 +03:00
int tuner1 = 0 , t_format1 = 0 , audioic = - 1 ;
2005-09-10 00:04:05 +04:00
char * t_name1 = NULL ;
2005-11-09 08:36:56 +03:00
const char * t_fmt_name1 [ 8 ] = { " none " , " " , " " , " " , " " , " " , " " , " " } ;
2005-04-17 02:20:36 +04:00
2005-11-09 08:36:56 +03:00
int tuner2 = 0 , t_format2 = 0 ;
2005-09-10 00:04:05 +04:00
char * t_name2 = NULL ;
2005-11-09 08:36:56 +03:00
const char * t_fmt_name2 [ 8 ] = { " none " , " " , " " , " " , " " , " " , " " , " " } ;
2005-09-10 00:04:05 +04:00
2005-11-09 08:36:56 +03:00
memset ( tvee , 0 , sizeof ( * tvee ) ) ;
2009-01-09 14:38:47 +03:00
tvee - > tuner_type = TUNER_ABSENT ;
tvee - > tuner2_type = TUNER_ABSENT ;
2005-09-10 00:04:05 +04:00
done = len = beenhere = 0 ;
2005-11-09 08:36:56 +03:00
2007-12-12 12:21:58 +03:00
/* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
if ( eeprom_data [ 0 ] = = 0x1a & &
eeprom_data [ 1 ] = = 0xeb & &
eeprom_data [ 2 ] = = 0x67 & &
eeprom_data [ 3 ] = = 0x95 )
start = 0xa0 ; /* Generic em28xx offset */
else if ( ( eeprom_data [ 0 ] & 0xe1 ) = = 0x01 & &
eeprom_data [ 1 ] = = 0x00 & &
eeprom_data [ 2 ] = = 0x00 & &
eeprom_data [ 8 ] = = 0x84 )
start = 8 ; /* Generic cx2388x offset */
else if ( eeprom_data [ 1 ] = = 0x70 & &
eeprom_data [ 2 ] = = 0x00 & &
eeprom_data [ 4 ] = = 0x74 & &
eeprom_data [ 8 ] = = 0x84 )
start = 8 ; /* Generic cx23418 offset (models 74xxx) */
2005-11-09 08:36:56 +03:00
else
2007-12-12 12:21:58 +03:00
start = 0 ;
2005-11-09 08:36:56 +03:00
for ( i = start ; ! done & & i < 256 ; i + = len ) {
2005-04-17 02:20:36 +04:00
if ( eeprom_data [ i ] = = 0x84 ) {
len = eeprom_data [ i + 1 ] + ( eeprom_data [ i + 2 ] < < 8 ) ;
2005-09-10 00:04:05 +04:00
i + = 3 ;
2005-04-17 02:20:36 +04:00
} else if ( ( eeprom_data [ i ] & 0xf0 ) = = 0x70 ) {
2005-09-10 00:04:05 +04:00
if ( eeprom_data [ i ] & 0x08 ) {
2005-04-17 02:20:36 +04:00
/* verify checksum! */
done = 1 ;
break ;
}
len = eeprom_data [ i ] & 0x07 ;
+ + i ;
} else {
2005-09-10 00:04:05 +04:00
tveeprom_warn ( " Encountered bad packet header [%02x]. "
2007-12-12 12:50:20 +03:00
" Corrupt or not a Hauppauge eeprom. \n " ,
eeprom_data [ i ] ) ;
2005-04-17 02:20:36 +04:00
return ;
}
2005-11-09 08:36:56 +03:00
if ( debug ) {
2007-12-12 12:50:20 +03:00
tveeprom_info ( " Tag [%02x] + %d bytes: " ,
eeprom_data [ i ] , len - 1 ) ;
for ( j = 1 ; j < len ; j + + )
printk ( KERN_CONT " %02x " , eeprom_data [ i + j ] ) ;
printk ( KERN_CONT " \n " ) ;
2005-11-09 08:36:56 +03:00
}
2005-04-17 02:20:36 +04:00
/* process by tag */
tag = eeprom_data [ i ] ;
switch ( tag ) {
case 0x00 :
2005-11-09 08:36:56 +03:00
/* tag: 'Comprehensive' */
2005-09-10 00:04:05 +04:00
tuner1 = eeprom_data [ i + 6 ] ;
t_format1 = eeprom_data [ i + 5 ] ;
2005-04-17 02:20:36 +04:00
tvee - > has_radio = eeprom_data [ i + len - 1 ] ;
2005-11-09 08:36:56 +03:00
/* old style tag, don't know how to detect
IR presence , mark as unknown . */
2008-07-22 22:50:31 +04:00
tvee - > has_ir = 0 ;
2005-04-17 02:20:36 +04:00
tvee - > model =
eeprom_data [ i + 8 ] +
( eeprom_data [ i + 9 ] < < 8 ) ;
tvee - > revision = eeprom_data [ i + 10 ] +
( eeprom_data [ i + 11 ] < < 8 ) +
( eeprom_data [ i + 12 ] < < 16 ) ;
break ;
2005-09-10 00:04:05 +04:00
2005-04-17 02:20:36 +04:00
case 0x01 :
2005-11-09 08:36:56 +03:00
/* tag: 'SerialID' */
2005-04-17 02:20:36 +04:00
tvee - > serial_number =
eeprom_data [ i + 6 ] +
( eeprom_data [ i + 7 ] < < 8 ) +
( eeprom_data [ i + 8 ] < < 16 ) ;
break ;
2005-09-10 00:04:05 +04:00
2005-04-17 02:20:36 +04:00
case 0x02 :
2005-11-09 08:36:56 +03:00
/* tag 'AudioInfo'
Note mask with 0x7F , high bit used on some older models
to indicate 4052 mux was removed in favor of using MSP
inputs directly . */
audioic = eeprom_data [ i + 2 ] & 0x7f ;
2007-06-05 12:20:56 +04:00
if ( audioic < ARRAY_SIZE ( audioIC ) )
2005-11-09 08:36:56 +03:00
tvee - > audio_processor = audioIC [ audioic ] . id ;
else
2008-07-23 12:09:15 +04:00
tvee - > audio_processor = V4L2_IDENT_UNKNOWN ;
2005-04-17 02:20:36 +04:00
break ;
2005-09-10 00:04:05 +04:00
2005-11-09 08:36:56 +03:00
/* case 0x03: tag 'EEInfo' */
2005-09-10 00:04:05 +04:00
2005-04-17 02:20:36 +04:00
case 0x04 :
2005-11-09 08:36:56 +03:00
/* tag 'SerialID2' */
2005-04-17 02:20:36 +04:00
tvee - > serial_number =
eeprom_data [ i + 5 ] +
( eeprom_data [ i + 6 ] < < 8 ) +
( eeprom_data [ i + 7 ] < < 16 ) ;
2005-12-01 11:51:27 +03:00
2007-12-12 12:50:20 +03:00
if ( ( eeprom_data [ i + 8 ] & 0xf0 ) & &
( tvee - > serial_number < 0xffffff ) ) {
tvee - > MAC_address [ 0 ] = 0x00 ;
tvee - > MAC_address [ 1 ] = 0x0D ;
tvee - > MAC_address [ 2 ] = 0xFE ;
tvee - > MAC_address [ 3 ] = eeprom_data [ i + 7 ] ;
tvee - > MAC_address [ 4 ] = eeprom_data [ i + 6 ] ;
tvee - > MAC_address [ 5 ] = eeprom_data [ i + 5 ] ;
tvee - > has_MAC_address = 1 ;
}
2005-04-17 02:20:36 +04:00
break ;
2005-09-10 00:04:05 +04:00
2005-04-17 02:20:36 +04:00
case 0x05 :
2005-11-09 08:36:56 +03:00
/* tag 'Audio2'
Note mask with 0x7F , high bit used on some older models
to indicate 4052 mux was removed in favor of using MSP
inputs directly . */
audioic = eeprom_data [ i + 1 ] & 0x7f ;
2007-06-05 12:20:56 +04:00
if ( audioic < ARRAY_SIZE ( audioIC ) )
2005-11-09 08:36:56 +03:00
tvee - > audio_processor = audioIC [ audioic ] . id ;
else
2008-07-23 12:09:15 +04:00
tvee - > audio_processor = V4L2_IDENT_UNKNOWN ;
2005-11-09 08:36:56 +03:00
2005-04-17 02:20:36 +04:00
break ;
2005-09-10 00:04:05 +04:00
2005-04-17 02:20:36 +04:00
case 0x06 :
2005-11-09 08:36:56 +03:00
/* tag 'ModelRev' */
2005-04-17 02:20:36 +04:00
tvee - > model =
2005-12-01 11:51:27 +03:00
eeprom_data [ i + 1 ] +
( eeprom_data [ i + 2 ] < < 8 ) +
( eeprom_data [ i + 3 ] < < 16 ) +
( eeprom_data [ i + 4 ] < < 24 ) ;
tvee - > revision =
2007-12-12 12:50:20 +03:00
eeprom_data [ i + 5 ] +
2005-12-01 11:51:27 +03:00
( eeprom_data [ i + 6 ] < < 8 ) +
( eeprom_data [ i + 7 ] < < 16 ) ;
2005-04-17 02:20:36 +04:00
break ;
2005-09-10 00:04:05 +04:00
case 0x07 :
2005-11-09 08:36:56 +03:00
/* tag 'Details': according to Hauppauge not interesting
on any PCI - era or later boards . */
2005-09-10 00:04:05 +04:00
break ;
2005-11-09 08:36:56 +03:00
/* there is no tag 0x08 defined */
2005-09-10 00:04:05 +04:00
case 0x09 :
2005-11-09 08:36:56 +03:00
/* tag 'Video' */
2005-09-10 00:04:05 +04:00
tvee - > decoder_processor = eeprom_data [ i + 1 ] ;
break ;
2005-04-17 02:20:36 +04:00
case 0x0a :
2005-11-09 08:36:56 +03:00
/* tag 'Tuner' */
2005-09-10 00:04:05 +04:00
if ( beenhere = = 0 ) {
2007-12-12 12:50:20 +03:00
tuner1 = eeprom_data [ i + 2 ] ;
t_format1 = eeprom_data [ i + 1 ] ;
2005-04-17 02:20:36 +04:00
beenhere = 1 ;
} else {
2005-11-09 08:36:56 +03:00
/* a second (radio) tuner may be present */
2007-12-12 12:50:20 +03:00
tuner2 = eeprom_data [ i + 2 ] ;
t_format2 = eeprom_data [ i + 1 ] ;
/* not a TV tuner? */
if ( t_format2 = = 0 )
2005-11-09 08:36:56 +03:00
tvee - > has_radio = 1 ; /* must be radio */
}
2005-09-10 00:04:05 +04:00
break ;
2005-11-09 08:36:56 +03:00
case 0x0b :
/* tag 'Inputs': according to Hauppauge this is specific
to each driver family , so no good assumptions can be
made . */
break ;
2005-09-10 00:04:05 +04:00
2005-11-09 08:36:56 +03:00
/* case 0x0c: tag 'Balun' */
/* case 0x0d: tag 'Teletext' */
2005-09-10 00:04:05 +04:00
2005-04-17 02:20:36 +04:00
case 0x0e :
2005-11-09 08:36:56 +03:00
/* tag: 'Radio' */
2005-04-17 02:20:36 +04:00
tvee - > has_radio = eeprom_data [ i + 1 ] ;
break ;
2005-09-10 00:04:05 +04:00
2005-11-09 08:36:56 +03:00
case 0x0f :
/* tag 'IRInfo' */
2008-07-22 22:50:31 +04:00
tvee - > has_ir = 1 | ( eeprom_data [ i + 1 ] < < 1 ) ;
2005-11-09 08:36:56 +03:00
break ;
2005-09-10 00:04:05 +04:00
2005-11-09 08:36:56 +03:00
/* case 0x10: tag 'VBIInfo' */
/* case 0x11: tag 'QCInfo' */
/* case 0x12: tag 'InfoBits' */
2005-09-10 00:04:05 +04:00
2005-04-17 02:20:36 +04:00
default :
2007-12-12 12:50:20 +03:00
tveeprom_dbg ( " Not sure what to do with tag [%02x] \n " ,
tag ) ;
2005-04-17 02:20:36 +04:00
/* dump the rest of the packet? */
}
}
if ( ! done ) {
2005-09-10 00:04:05 +04:00
tveeprom_warn ( " Ran out of data! \n " ) ;
2005-04-17 02:20:36 +04:00
return ;
}
if ( tvee - > revision ! = 0 ) {
tvee - > rev_str [ 0 ] = 32 + ( ( tvee - > revision > > 18 ) & 0x3f ) ;
tvee - > rev_str [ 1 ] = 32 + ( ( tvee - > revision > > 12 ) & 0x3f ) ;
tvee - > rev_str [ 2 ] = 32 + ( ( tvee - > revision > > 6 ) & 0x3f ) ;
2007-12-12 12:50:20 +03:00
tvee - > rev_str [ 3 ] = 32 + ( tvee - > revision & 0x3f ) ;
2005-04-17 02:20:36 +04:00
tvee - > rev_str [ 4 ] = 0 ;
}
2005-11-09 08:36:56 +03:00
if ( hasRadioTuner ( tuner1 ) & & ! tvee - > has_radio ) {
tveeprom_info ( " The eeprom says no radio is present, but the tuner type \n " ) ;
tveeprom_info ( " indicates otherwise. I will assume that radio is present. \n " ) ;
tvee - > has_radio = 1 ;
}
2005-04-17 02:20:36 +04:00
2009-07-22 07:02:29 +04:00
if ( tuner1 < ARRAY_SIZE ( hauppauge_tuner ) ) {
2005-09-10 00:04:05 +04:00
tvee - > tuner_type = hauppauge_tuner [ tuner1 ] . id ;
t_name1 = hauppauge_tuner [ tuner1 ] . name ;
2005-04-17 02:20:36 +04:00
} else {
2005-09-10 00:04:05 +04:00
t_name1 = " unknown " ;
}
2009-07-22 07:02:29 +04:00
if ( tuner2 < ARRAY_SIZE ( hauppauge_tuner ) ) {
2005-09-10 00:04:05 +04:00
tvee - > tuner2_type = hauppauge_tuner [ tuner2 ] . id ;
t_name2 = hauppauge_tuner [ tuner2 ] . name ;
} else {
t_name2 = " unknown " ;
2005-04-17 02:20:36 +04:00
}
2005-12-01 11:51:42 +03:00
tvee - > tuner_hauppauge_model = tuner1 ;
tvee - > tuner2_hauppauge_model = tuner2 ;
2005-04-17 02:20:36 +04:00
tvee - > tuner_formats = 0 ;
2005-09-10 00:04:05 +04:00
tvee - > tuner2_formats = 0 ;
for ( i = j = 0 ; i < 8 ; i + + ) {
if ( t_format1 & ( 1 < < i ) ) {
2005-04-17 02:20:36 +04:00
tvee - > tuner_formats | = hauppauge_tuner_fmt [ i ] . id ;
2005-09-10 00:04:05 +04:00
t_fmt_name1 [ j + + ] = hauppauge_tuner_fmt [ i ] . name ;
2005-04-17 02:20:36 +04:00
}
2006-08-08 02:43:21 +04:00
}
for ( i = j = 0 ; i < 8 ; i + + ) {
2005-11-09 08:36:56 +03:00
if ( t_format2 & ( 1 < < i ) ) {
tvee - > tuner2_formats | = hauppauge_tuner_fmt [ i ] . id ;
t_fmt_name2 [ j + + ] = hauppauge_tuner_fmt [ i ] . name ;
}
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:05 +04:00
tveeprom_info ( " Hauppauge model %d, rev %s, serial# %d \n " ,
2005-11-09 08:36:56 +03:00
tvee - > model , tvee - > rev_str , tvee - > serial_number ) ;
2007-12-12 12:50:20 +03:00
if ( tvee - > has_MAC_address = = 1 )
2009-12-30 22:13:10 +03:00
tveeprom_info ( " MAC address is %pM \n " , tvee - > MAC_address ) ;
2005-09-10 00:04:05 +04:00
tveeprom_info ( " tuner model is %s (idx %d, type %d) \n " ,
2005-11-09 08:36:56 +03:00
t_name1 , tuner1 , tvee - > tuner_type ) ;
2005-09-10 00:04:05 +04:00
tveeprom_info ( " TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x) \n " ,
2007-12-12 12:50:20 +03:00
t_fmt_name1 [ 0 ] , t_fmt_name1 [ 1 ] , t_fmt_name1 [ 2 ] ,
t_fmt_name1 [ 3 ] , t_fmt_name1 [ 4 ] , t_fmt_name1 [ 5 ] ,
t_fmt_name1 [ 6 ] , t_fmt_name1 [ 7 ] , t_format1 ) ;
if ( tuner2 )
2005-11-09 08:36:56 +03:00
tveeprom_info ( " second tuner model is %s (idx %d, type %d) \n " ,
t_name2 , tuner2 , tvee - > tuner2_type ) ;
2007-12-12 12:50:20 +03:00
if ( t_format2 )
2005-11-09 08:36:56 +03:00
tveeprom_info ( " TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x) \n " ,
2007-12-12 12:50:20 +03:00
t_fmt_name2 [ 0 ] , t_fmt_name2 [ 1 ] , t_fmt_name2 [ 2 ] ,
t_fmt_name2 [ 3 ] , t_fmt_name2 [ 4 ] , t_fmt_name2 [ 5 ] ,
t_fmt_name2 [ 6 ] , t_fmt_name2 [ 7 ] , t_format2 ) ;
if ( audioic < 0 ) {
2005-11-09 08:36:56 +03:00
tveeprom_info ( " audio processor is unknown (no idx) \n " ) ;
2008-07-23 12:09:15 +04:00
tvee - > audio_processor = V4L2_IDENT_UNKNOWN ;
2005-11-09 08:36:56 +03:00
} else {
2007-06-05 12:20:56 +04:00
if ( audioic < ARRAY_SIZE ( audioIC ) )
2005-11-09 08:36:56 +03:00
tveeprom_info ( " audio processor is %s (idx %d) \n " ,
2007-12-12 12:50:20 +03:00
audioIC [ audioic ] . name , audioic ) ;
2005-11-09 08:36:56 +03:00
else
tveeprom_info ( " audio processor is unknown (idx %d) \n " ,
audioic ) ;
}
2007-12-12 12:50:20 +03:00
if ( tvee - > decoder_processor )
2005-11-09 08:36:56 +03:00
tveeprom_info ( " decoder processor is %s (idx %d) \n " ,
STRM ( decoderIC , tvee - > decoder_processor ) ,
tvee - > decoder_processor ) ;
2008-07-22 22:50:31 +04:00
if ( tvee - > has_ir )
2006-11-12 15:28:46 +03:00
tveeprom_info ( " has %sradio, has %sIR receiver, has %sIR transmitter \n " ,
2005-11-09 08:36:56 +03:00
tvee - > has_radio ? " " : " no " ,
2008-07-22 22:50:31 +04:00
( tvee - > has_ir & 2 ) ? " " : " no " ,
( tvee - > has_ir & 4 ) ? " " : " no " ) ;
else
tveeprom_info ( " has %sradio \n " ,
tvee - > has_radio ? " " : " no " ) ;
2005-04-17 02:20:36 +04:00
}
EXPORT_SYMBOL ( tveeprom_hauppauge_analog ) ;
/* ----------------------------------------------------------------------- */
/* generic helper functions */
int tveeprom_read ( struct i2c_client * c , unsigned char * eedata , int len )
{
unsigned char buf ;
int err ;
buf = 0 ;
2007-12-12 12:50:20 +03:00
err = i2c_master_send ( c , & buf , 1 ) ;
if ( err ! = 1 ) {
2005-09-10 00:04:05 +04:00
tveeprom_info ( " Huh, no eeprom present (err=%d)? \n " , err ) ;
2005-04-17 02:20:36 +04:00
return - 1 ;
}
2007-12-12 12:50:20 +03:00
err = i2c_master_recv ( c , eedata , len ) ;
if ( err ! = len ) {
2005-09-10 00:04:05 +04:00
tveeprom_warn ( " i2c eeprom read error (err=%d) \n " , err ) ;
2005-04-17 02:20:36 +04:00
return - 1 ;
}
2005-11-09 08:36:56 +03:00
if ( debug ) {
int i ;
tveeprom_info ( " full 256-byte eeprom dump: \n " ) ;
for ( i = 0 ; i < len ; i + + ) {
if ( 0 = = ( i % 16 ) )
tveeprom_info ( " %02x: " , i ) ;
2007-12-12 12:50:20 +03:00
printk ( KERN_CONT " %02x " , eedata [ i ] ) ;
2005-11-09 08:36:56 +03:00
if ( 15 = = ( i % 16 ) )
2007-12-12 12:50:20 +03:00
printk ( KERN_CONT " \n " ) ;
2005-11-09 08:36:56 +03:00
}
}
2005-04-17 02:20:36 +04:00
return 0 ;
}
EXPORT_SYMBOL ( tveeprom_read ) ;
/*
* Local variables :
* c - basic - offset : 8
* End :
*/