2005-04-17 02:20:36 +04:00
/*
2005-11-09 08:37:48 +03:00
i2c tv tuner chip device driver
controls the philips tda8290 + 75 tuner chip combo .
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 .
2007-08-28 04:22:20 +04:00
This " tda8290 " module was split apart from the original " tuner " module .
2005-11-09 08:37:48 +03:00
*/
2005-04-17 02:20:36 +04:00
# include <linux/i2c.h>
# include <linux/delay.h>
2007-08-21 08:14:12 +04:00
# include <linux/videodev.h>
2007-08-28 04:22:20 +04:00
# include "tda8290.h"
2007-08-26 02:08:45 +04:00
# include "tda827x.h"
2007-10-22 16:56:38 +04:00
# include "tda18271.h"
2007-08-28 04:22:20 +04:00
2007-10-22 16:56:38 +04:00
static int tuner_debug ;
2007-08-26 02:08:45 +04:00
module_param_named ( debug , tuner_debug , int , 0644 ) ;
2007-08-28 04:22:20 +04:00
MODULE_PARM_DESC ( debug , " enable verbose debug messages " ) ;
2007-11-04 17:03:36 +03:00
# define PREFIX "tda8290"
2005-04-17 02:20:36 +04:00
/* ---------------------------------------------------------------------- */
2007-05-30 05:54:06 +04:00
struct tda8290_priv {
2007-08-21 08:24:42 +04:00
struct tuner_i2c_props i2c_props ;
2007-05-30 05:54:06 +04:00
unsigned char tda8290_easy_mode ;
2007-08-26 02:08:45 +04:00
2007-05-30 05:54:06 +04:00
unsigned char tda827x_addr ;
2007-10-27 09:00:57 +04:00
unsigned char ver ;
# define TDA8290 1
# define TDA8295 2
# define TDA8275 4
# define TDA8275A 8
# define TDA18271 16
2005-04-17 02:20:36 +04:00
2007-08-26 02:08:45 +04:00
struct tda827x_config cfg ;
2007-10-22 02:39:50 +04:00
struct tuner * t ;
2005-04-17 02:20:36 +04:00
} ;
2005-11-09 08:37:48 +03:00
/*---------------------------------------------------------------------*/
2005-04-17 02:20:36 +04:00
2007-10-24 16:30:17 +04:00
static int tda8290_i2c_bridge ( struct dvb_frontend * fe , int close )
2005-11-09 08:37:48 +03:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-08-21 08:24:42 +04:00
2005-11-09 08:37:48 +03:00
unsigned char enable [ 2 ] = { 0x21 , 0xC0 } ;
2006-02-07 11:49:09 +03:00
unsigned char disable [ 2 ] = { 0x21 , 0x00 } ;
2005-11-09 08:37:48 +03:00
unsigned char * msg ;
2007-10-24 16:30:17 +04:00
if ( close ) {
2005-11-09 08:37:48 +03:00
msg = enable ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , msg , 2 ) ;
2005-11-09 08:37:48 +03:00
/* let the bridge stabilize */
msleep ( 20 ) ;
} else {
msg = disable ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , msg , 2 ) ;
2005-11-09 08:37:48 +03:00
}
2007-10-24 16:30:17 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2007-10-24 16:30:17 +04:00
static int tda8295_i2c_bridge ( struct dvb_frontend * fe , int close )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
unsigned char enable [ 2 ] = { 0x45 , 0xc1 } ;
unsigned char disable [ 2 ] = { 0x46 , 0x00 } ;
unsigned char buf [ 3 ] = { 0x45 , 0x01 , 0x00 } ;
unsigned char * msg ;
2007-10-24 16:30:17 +04:00
2007-10-22 16:56:38 +04:00
if ( close ) {
msg = enable ;
tuner_i2c_xfer_send ( & priv - > i2c_props , msg , 2 ) ;
/* let the bridge stabilize */
msleep ( 20 ) ;
} else {
msg = disable ;
tuner_i2c_xfer_send ( & priv - > i2c_props , msg , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & msg [ 1 ] , 1 ) ;
buf [ 2 ] = msg [ 1 ] ;
buf [ 2 ] & = ~ 0x04 ;
tuner_i2c_xfer_send ( & priv - > i2c_props , buf , 3 ) ;
msleep ( 5 ) ;
msg [ 1 ] | = 0x04 ;
tuner_i2c_xfer_send ( & priv - > i2c_props , msg , 2 ) ;
}
2007-10-24 16:30:17 +04:00
return 0 ;
2007-10-22 16:56:38 +04:00
}
2005-11-09 08:37:48 +03:00
/*---------------------------------------------------------------------*/
2007-10-22 02:39:50 +04:00
static void set_audio ( struct dvb_frontend * fe )
2005-04-17 02:20:36 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
struct tuner * t = priv - > t ;
2007-08-28 04:22:20 +04:00
char * mode ;
2007-08-26 02:08:45 +04:00
if ( t - > std & V4L2_STD_MN ) {
2007-08-28 04:22:20 +04:00
priv - > tda8290_easy_mode = 0x01 ;
mode = " MN " ;
2007-08-26 02:08:45 +04:00
} else if ( t - > std & V4L2_STD_B ) {
2007-08-28 04:22:20 +04:00
priv - > tda8290_easy_mode = 0x02 ;
mode = " B " ;
2007-08-26 02:08:45 +04:00
} else if ( t - > std & V4L2_STD_GH ) {
2007-08-28 04:22:20 +04:00
priv - > tda8290_easy_mode = 0x04 ;
mode = " GH " ;
2007-08-26 02:08:45 +04:00
} else if ( t - > std & V4L2_STD_PAL_I ) {
2007-08-28 04:22:20 +04:00
priv - > tda8290_easy_mode = 0x08 ;
mode = " I " ;
2007-08-26 02:08:45 +04:00
} else if ( t - > std & V4L2_STD_DK ) {
2007-08-28 04:22:20 +04:00
priv - > tda8290_easy_mode = 0x10 ;
mode = " DK " ;
2007-08-26 02:08:45 +04:00
} else if ( t - > std & V4L2_STD_SECAM_L ) {
2007-08-28 04:22:20 +04:00
priv - > tda8290_easy_mode = 0x20 ;
mode = " L " ;
2007-08-26 02:08:45 +04:00
} else if ( t - > std & V4L2_STD_SECAM_LC ) {
2007-08-28 04:22:20 +04:00
priv - > tda8290_easy_mode = 0x40 ;
mode = " LC " ;
} else {
priv - > tda8290_easy_mode = 0x10 ;
mode = " xx " ;
}
2007-10-27 09:00:57 +04:00
tuner_dbg ( " setting tda829x to system %s \n " , mode ) ;
2007-08-28 04:22:20 +04:00
}
2007-10-22 02:39:50 +04:00
static void tda8290_set_freq ( struct dvb_frontend * fe , unsigned int freq )
2007-08-28 04:22:20 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
struct tuner * t = priv - > t ;
2005-11-09 08:37:48 +03:00
unsigned char soft_reset [ ] = { 0x00 , 0x00 } ;
2007-05-30 05:54:06 +04:00
unsigned char easy_mode [ ] = { 0x01 , priv - > tda8290_easy_mode } ;
2005-11-09 08:37:48 +03:00
unsigned char expert_mode [ ] = { 0x01 , 0x80 } ;
2006-02-07 11:49:09 +03:00
unsigned char agc_out_on [ ] = { 0x02 , 0x00 } ;
2005-11-09 08:37:48 +03:00
unsigned char gainset_off [ ] = { 0x28 , 0x14 } ;
unsigned char if_agc_spd [ ] = { 0x0f , 0x88 } ;
unsigned char adc_head_6 [ ] = { 0x05 , 0x04 } ;
unsigned char adc_head_9 [ ] = { 0x05 , 0x02 } ;
unsigned char adc_head_12 [ ] = { 0x05 , 0x01 } ;
unsigned char pll_bw_nom [ ] = { 0x0d , 0x47 } ;
unsigned char pll_bw_low [ ] = { 0x0d , 0x27 } ;
unsigned char gainset_2 [ ] = { 0x28 , 0x64 } ;
unsigned char agc_rst_on [ ] = { 0x0e , 0x0b } ;
unsigned char agc_rst_off [ ] = { 0x0e , 0x09 } ;
unsigned char if_agc_set [ ] = { 0x0f , 0x81 } ;
unsigned char addr_adc_sat = 0x1a ;
unsigned char addr_agc_stat = 0x1d ;
unsigned char addr_pll_stat = 0x1b ;
unsigned char adc_sat , agc_stat ,
2005-11-09 08:37:50 +03:00
pll_stat ;
2007-04-27 19:31:12 +04:00
int i ;
2005-11-09 08:37:48 +03:00
2007-08-26 02:08:45 +04:00
struct analog_parameters params = {
. frequency = freq ,
. mode = t - > mode ,
. audmode = t - > audmode ,
. std = t - > std
} ;
2007-10-22 02:39:50 +04:00
set_audio ( fe ) ;
2007-08-28 04:22:20 +04:00
2007-08-26 02:08:45 +04:00
tuner_dbg ( " tda827xa config is 0x%02x \n " , t - > config ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , easy_mode , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , agc_out_on , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , soft_reset , 2 ) ;
2005-11-09 08:37:48 +03:00
msleep ( 1 ) ;
2007-05-30 05:54:06 +04:00
expert_mode [ 1 ] = priv - > tda8290_easy_mode + 0x80 ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , expert_mode , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , gainset_off , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , if_agc_spd , 2 ) ;
2007-05-30 05:54:06 +04:00
if ( priv - > tda8290_easy_mode & 0x60 )
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , adc_head_9 , 2 ) ;
2005-11-09 08:37:48 +03:00
else
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , adc_head_6 , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , pll_bw_nom , 2 ) ;
2005-11-09 08:37:48 +03:00
2007-10-22 02:39:50 +04:00
tda8290_i2c_bridge ( fe , 1 ) ;
2007-08-26 02:08:45 +04:00
2007-10-22 02:39:50 +04:00
if ( fe - > ops . tuner_ops . set_analog_params )
fe - > ops . tuner_ops . set_analog_params ( fe , & params ) ;
2007-08-26 02:08:45 +04:00
2007-04-27 19:31:12 +04:00
for ( i = 0 ; i < 3 ; i + + ) {
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_pll_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & pll_stat , 1 ) ;
2007-04-27 19:31:12 +04:00
if ( pll_stat & 0x80 ) {
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_adc_sat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & adc_sat , 1 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_agc_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & agc_stat , 1 ) ;
2007-04-27 19:31:12 +04:00
tuner_dbg ( " tda8290 is locked, AGC: %d \n " , agc_stat ) ;
break ;
} else {
tuner_dbg ( " tda8290 not locked, no signal? \n " ) ;
msleep ( 100 ) ;
}
}
2005-11-09 08:37:48 +03:00
/* adjust headroom resp. gain */
2005-11-09 08:38:38 +03:00
if ( ( agc_stat > 115 ) | | ( ! ( pll_stat & 0x80 ) & & ( adc_sat < 20 ) ) ) {
tuner_dbg ( " adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d \n " ,
agc_stat , adc_sat , pll_stat & 0x80 ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , gainset_2 , 2 ) ;
2005-11-09 08:37:48 +03:00
msleep ( 100 ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_agc_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & agc_stat , 1 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_pll_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & pll_stat , 1 ) ;
2005-11-09 08:37:48 +03:00
if ( ( agc_stat > 115 ) | | ! ( pll_stat & 0x80 ) ) {
2005-11-09 08:38:38 +03:00
tuner_dbg ( " adjust gain, step 2. Agc: %d, lock: %d \n " ,
agc_stat , pll_stat & 0x80 ) ;
2007-08-26 02:08:45 +04:00
if ( priv - > cfg . agcf )
2007-10-22 02:39:50 +04:00
priv - > cfg . agcf ( fe ) ;
2005-11-09 08:37:48 +03:00
msleep ( 100 ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_agc_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & agc_stat , 1 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_pll_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & pll_stat , 1 ) ;
2005-11-09 08:37:48 +03:00
if ( ( agc_stat > 115 ) | | ! ( pll_stat & 0x80 ) ) {
tuner_dbg ( " adjust gain, step 3. Agc: %d \n " , agc_stat ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , adc_head_12 , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , pll_bw_low , 2 ) ;
2005-11-09 08:37:48 +03:00
msleep ( 100 ) ;
}
}
}
2005-04-17 02:20:36 +04:00
2005-11-09 08:37:48 +03:00
/* l/ l' deadlock? */
2007-05-30 05:54:06 +04:00
if ( priv - > tda8290_easy_mode & 0x60 ) {
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_adc_sat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & adc_sat , 1 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & addr_pll_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & pll_stat , 1 ) ;
2005-11-09 08:37:48 +03:00
if ( ( adc_sat > 20 ) | | ! ( pll_stat & 0x80 ) ) {
2005-11-09 08:38:38 +03:00
tuner_dbg ( " trying to resolve SECAM L deadlock \n " ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , agc_rst_on , 2 ) ;
2005-11-09 08:37:48 +03:00
msleep ( 40 ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , agc_rst_off , 2 ) ;
2005-11-09 08:37:48 +03:00
}
}
2005-06-29 07:45:21 +04:00
2007-10-22 02:39:50 +04:00
tda8290_i2c_bridge ( fe , 0 ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , if_agc_set , 2 ) ;
2005-04-17 02:20:36 +04:00
}
2005-11-09 08:37:48 +03:00
/*---------------------------------------------------------------------*/
2007-10-22 02:39:50 +04:00
static void tda8295_power ( struct dvb_frontend * fe , int enable )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
unsigned char buf [ ] = { 0x30 , 0x00 } ; /* clb_stdbt */
tuner_i2c_xfer_send ( & priv - > i2c_props , & buf [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & buf [ 1 ] , 1 ) ;
if ( enable )
buf [ 1 ] = 0x01 ;
else
buf [ 1 ] = 0x03 ;
tuner_i2c_xfer_send ( & priv - > i2c_props , buf , 2 ) ;
}
2007-10-22 02:39:50 +04:00
static void tda8295_set_easy_mode ( struct dvb_frontend * fe , int enable )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
unsigned char buf [ ] = { 0x01 , 0x00 } ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & buf [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & buf [ 1 ] , 1 ) ;
if ( enable )
buf [ 1 ] = 0x01 ; /* rising edge sets regs 0x02 - 0x23 */
else
buf [ 1 ] = 0x00 ; /* reset active bit */
tuner_i2c_xfer_send ( & priv - > i2c_props , buf , 2 ) ;
}
2007-10-22 02:39:50 +04:00
static void tda8295_set_video_std ( struct dvb_frontend * fe )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
unsigned char buf [ ] = { 0x00 , priv - > tda8290_easy_mode } ;
tuner_i2c_xfer_send ( & priv - > i2c_props , buf , 2 ) ;
2007-10-22 02:39:50 +04:00
tda8295_set_easy_mode ( fe , 1 ) ;
2007-10-22 16:56:38 +04:00
msleep ( 20 ) ;
2007-10-22 02:39:50 +04:00
tda8295_set_easy_mode ( fe , 0 ) ;
2007-10-22 16:56:38 +04:00
}
/*---------------------------------------------------------------------*/
2007-10-22 02:39:50 +04:00
static void tda8295_agc1_out ( struct dvb_frontend * fe , int enable )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
unsigned char buf [ ] = { 0x02 , 0x00 } ; /* DIV_FUNC */
tuner_i2c_xfer_send ( & priv - > i2c_props , & buf [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & buf [ 1 ] , 1 ) ;
if ( enable )
buf [ 1 ] & = ~ 0x40 ;
else
buf [ 1 ] | = 0x40 ;
tuner_i2c_xfer_send ( & priv - > i2c_props , buf , 2 ) ;
}
2007-10-22 02:39:50 +04:00
static void tda8295_agc2_out ( struct dvb_frontend * fe , int enable )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
unsigned char set_gpio_cf [ ] = { 0x44 , 0x00 } ;
unsigned char set_gpio_val [ ] = { 0x46 , 0x00 } ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & set_gpio_cf [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & set_gpio_cf [ 1 ] , 1 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & set_gpio_val [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & set_gpio_val [ 1 ] , 1 ) ;
set_gpio_cf [ 1 ] & = 0xf0 ; /* clear GPIO_0 bits 3-0 */
if ( enable ) {
set_gpio_cf [ 1 ] | = 0x01 ; /* config GPIO_0 as Open Drain Out */
set_gpio_val [ 1 ] & = 0xfe ; /* set GPIO_0 pin low */
}
tuner_i2c_xfer_send ( & priv - > i2c_props , set_gpio_cf , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_gpio_val , 2 ) ;
}
2007-10-22 02:39:50 +04:00
static int tda8295_has_signal ( struct dvb_frontend * fe )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
unsigned char hvpll_stat = 0x26 ;
unsigned char ret ;
tuner_i2c_xfer_send ( & priv - > i2c_props , & hvpll_stat , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & ret , 1 ) ;
return ( ret & 0x01 ) ? 65535 : 0 ;
}
/*---------------------------------------------------------------------*/
2007-10-22 02:39:50 +04:00
static void tda8295_set_freq ( struct dvb_frontend * fe , unsigned int freq )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
struct tuner * t = priv - > t ;
2007-10-22 16:56:38 +04:00
unsigned char blanking_mode [ ] = { 0x1d , 0x00 } ;
struct analog_parameters params = {
. frequency = freq ,
. mode = t - > mode ,
. audmode = t - > audmode ,
. std = t - > std
} ;
2007-10-22 02:39:50 +04:00
set_audio ( fe ) ;
2007-10-22 16:56:38 +04:00
2007-10-22 08:10:39 +04:00
tuner_dbg ( " %s: freq = %d \n " , __FUNCTION__ , freq ) ;
2007-10-22 16:56:38 +04:00
2007-10-22 02:39:50 +04:00
tda8295_power ( fe , 1 ) ;
tda8295_agc1_out ( fe , 1 ) ;
2007-10-22 16:56:38 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , & blanking_mode [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & blanking_mode [ 1 ] , 1 ) ;
2007-10-22 02:39:50 +04:00
tda8295_set_video_std ( fe ) ;
2007-10-22 16:56:38 +04:00
blanking_mode [ 1 ] = 0x03 ;
tuner_i2c_xfer_send ( & priv - > i2c_props , blanking_mode , 2 ) ;
msleep ( 20 ) ;
2007-10-22 02:39:50 +04:00
tda8295_i2c_bridge ( fe , 1 ) ;
2007-10-22 16:56:38 +04:00
2007-10-22 02:39:50 +04:00
if ( fe - > ops . tuner_ops . set_analog_params )
fe - > ops . tuner_ops . set_analog_params ( fe , & params ) ;
2007-10-22 16:56:38 +04:00
if ( priv - > cfg . agcf )
2007-10-22 02:39:50 +04:00
priv - > cfg . agcf ( fe ) ;
2007-10-22 16:56:38 +04:00
2007-10-22 02:39:50 +04:00
if ( tda8295_has_signal ( fe ) )
2007-10-22 16:56:38 +04:00
tuner_dbg ( " tda8295 is locked \n " ) ;
else
tuner_dbg ( " tda8295 not locked, no signal? \n " ) ;
2007-10-22 02:39:50 +04:00
tda8295_i2c_bridge ( fe , 0 ) ;
2007-10-22 16:56:38 +04:00
}
/*---------------------------------------------------------------------*/
2007-10-22 02:39:50 +04:00
static int tda8290_has_signal ( struct dvb_frontend * fe )
2005-04-17 02:20:36 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2005-04-17 02:20:36 +04:00
2007-08-28 04:22:20 +04:00
unsigned char i2c_get_afc [ 1 ] = { 0x1B } ;
unsigned char afc = 0 ;
2005-04-17 02:20:36 +04:00
2007-08-28 04:22:20 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , i2c_get_afc , ARRAY_SIZE ( i2c_get_afc ) ) ;
tuner_i2c_xfer_recv ( & priv - > i2c_props , & afc , 1 ) ;
2007-08-26 02:08:45 +04:00
return ( afc & 0x80 ) ? 65535 : 0 ;
2005-04-17 02:20:36 +04:00
}
2005-11-09 08:37:48 +03:00
/*---------------------------------------------------------------------*/
2007-10-22 02:39:50 +04:00
static void tda8290_standby ( struct dvb_frontend * fe )
2005-09-10 00:03:37 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2005-11-09 08:37:48 +03:00
unsigned char cb1 [ ] = { 0x30 , 0xD0 } ;
unsigned char tda8290_standby [ ] = { 0x00 , 0x02 } ;
2006-02-07 11:49:09 +03:00
unsigned char tda8290_agc_tri [ ] = { 0x02 , 0x20 } ;
2007-05-30 05:54:06 +04:00
struct i2c_msg msg = { . addr = priv - > tda827x_addr , . flags = 0 , . buf = cb1 , . len = 2 } ;
2005-11-09 08:37:48 +03:00
2007-10-22 02:39:50 +04:00
tda8290_i2c_bridge ( fe , 1 ) ;
2007-10-27 09:00:57 +04:00
if ( priv - > ver & TDA8275A )
2005-11-09 08:37:48 +03:00
cb1 [ 1 ] = 0x90 ;
2007-08-21 08:24:42 +04:00
i2c_transfer ( priv - > i2c_props . adap , & msg , 1 ) ;
2007-10-22 02:39:50 +04:00
tda8290_i2c_bridge ( fe , 0 ) ;
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , tda8290_agc_tri , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , tda8290_standby , 2 ) ;
2005-09-10 00:03:37 +04:00
}
2007-10-22 02:39:50 +04:00
static void tda8295_standby ( struct dvb_frontend * fe )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
tda8295_agc1_out ( fe , 0 ) ; /* Put AGC in tri-state */
2007-10-22 16:56:38 +04:00
2007-10-22 02:39:50 +04:00
tda8295_power ( fe , 0 ) ;
2007-10-22 16:56:38 +04:00
}
2007-10-22 02:39:50 +04:00
static void tda8290_init_if ( struct dvb_frontend * fe )
2005-11-09 08:37:48 +03:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
struct tuner * t = priv - > t ;
2007-08-21 08:24:42 +04:00
2005-11-09 08:37:48 +03:00
unsigned char set_VS [ ] = { 0x30 , 0x6F } ;
2007-04-27 19:31:12 +04:00
unsigned char set_GP00_CF [ ] = { 0x20 , 0x01 } ;
2005-11-09 08:37:48 +03:00
unsigned char set_GP01_CF [ ] = { 0x20 , 0x0B } ;
2007-08-26 02:08:45 +04:00
if ( ( t - > config = = 1 ) | | ( t - > config = = 2 ) )
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , set_GP00_CF , 2 ) ;
2007-04-27 19:31:12 +04:00
else
2007-08-21 08:24:42 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , set_GP01_CF , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_VS , 2 ) ;
2005-11-09 08:37:48 +03:00
}
2007-10-22 02:39:50 +04:00
static void tda8295_init_if ( struct dvb_frontend * fe )
2007-10-22 16:56:38 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2007-10-22 16:56:38 +04:00
static unsigned char set_adc_ctl [ ] = { 0x33 , 0x14 } ;
static unsigned char set_adc_ctl2 [ ] = { 0x34 , 0x00 } ;
static unsigned char set_pll_reg6 [ ] = { 0x3e , 0x63 } ;
static unsigned char set_pll_reg0 [ ] = { 0x38 , 0x23 } ;
static unsigned char set_pll_reg7 [ ] = { 0x3f , 0x01 } ;
static unsigned char set_pll_reg10 [ ] = { 0x42 , 0x61 } ;
static unsigned char set_gpio_reg0 [ ] = { 0x44 , 0x0b } ;
2007-10-22 02:39:50 +04:00
tda8295_power ( fe , 1 ) ;
2007-10-22 16:56:38 +04:00
2007-10-22 02:39:50 +04:00
tda8295_set_easy_mode ( fe , 0 ) ;
tda8295_set_video_std ( fe ) ;
2007-10-22 16:56:38 +04:00
tuner_i2c_xfer_send ( & priv - > i2c_props , set_adc_ctl , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_adc_ctl2 , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_pll_reg6 , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_pll_reg0 , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_pll_reg7 , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_pll_reg10 , 2 ) ;
tuner_i2c_xfer_send ( & priv - > i2c_props , set_gpio_reg0 , 2 ) ;
2007-10-22 02:39:50 +04:00
tda8295_agc1_out ( fe , 0 ) ;
tda8295_agc2_out ( fe , 0 ) ;
2007-10-22 16:56:38 +04:00
}
2007-10-22 02:39:50 +04:00
static void tda8290_init_tuner ( struct dvb_frontend * fe )
2005-04-17 02:20:36 +04:00
{
2007-10-22 02:39:50 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
2005-11-09 08:37:48 +03:00
unsigned char tda8275_init [ ] = { 0x00 , 0x00 , 0x00 , 0x40 , 0xdC , 0x04 , 0xAf ,
2005-11-09 08:37:50 +03:00
0x3F , 0x2A , 0x04 , 0xFF , 0x00 , 0x00 , 0x40 } ;
2005-11-09 08:37:48 +03:00
unsigned char tda8275a_init [ ] = { 0x00 , 0x00 , 0x00 , 0x00 , 0xdC , 0x05 , 0x8b ,
2005-11-09 08:37:50 +03:00
0x0c , 0x04 , 0x20 , 0xFF , 0x00 , 0x00 , 0x4b } ;
2007-05-30 05:54:06 +04:00
struct i2c_msg msg = { . addr = priv - > tda827x_addr , . flags = 0 ,
2005-11-09 08:37:51 +03:00
. buf = tda8275_init , . len = 14 } ;
2007-10-27 09:00:57 +04:00
if ( priv - > ver & TDA8275A )
2005-11-09 08:37:48 +03:00
msg . buf = tda8275a_init ;
2007-10-22 02:39:50 +04:00
tda8290_i2c_bridge ( fe , 1 ) ;
2007-08-21 08:24:42 +04:00
i2c_transfer ( priv - > i2c_props . adap , & msg , 1 ) ;
2007-10-22 02:39:50 +04:00
tda8290_i2c_bridge ( fe , 0 ) ;
2005-11-09 08:37:48 +03:00
}
/*---------------------------------------------------------------------*/
2005-04-17 02:20:36 +04:00
2007-10-22 02:39:50 +04:00
static void tda829x_release ( struct dvb_frontend * fe )
2007-06-04 22:20:11 +04:00
{
2007-10-22 02:39:50 +04:00
if ( fe - > ops . tuner_ops . release )
fe - > ops . tuner_ops . release ( fe ) ;
2007-06-04 22:20:11 +04:00
2007-10-22 02:39:50 +04:00
kfree ( fe - > analog_demod_priv ) ;
fe - > analog_demod_priv = NULL ;
2007-08-28 04:22:20 +04:00
}
2007-10-27 09:00:57 +04:00
static int tda829x_find_tuner ( struct dvb_frontend * fe )
2005-11-09 08:37:48 +03:00
{
2007-10-27 09:00:57 +04:00
struct tda8290_priv * priv = fe - > analog_demod_priv ;
struct analog_tuner_ops * ops = fe - > ops . analog_demod_ops ;
struct tuner * t = priv - > t ;
2005-11-09 08:37:48 +03:00
int i , ret , tuners_found ;
u32 tuner_addrs ;
2007-10-27 09:00:57 +04:00
u8 data ;
struct i2c_msg msg = { . flags = I2C_M_RD , . buf = & data , . len = 1 } ;
2005-11-09 08:37:48 +03:00
2007-10-27 09:00:57 +04:00
if ( NULL = = ops )
return - EINVAL ;
2007-08-26 02:08:45 +04:00
2007-10-27 09:00:57 +04:00
ops - > i2c_gate_ctrl ( fe , 1 ) ;
2007-08-21 08:24:42 +04:00
2005-11-09 08:37:48 +03:00
/* probe for tuner chip */
tuners_found = 0 ;
tuner_addrs = 0 ;
2007-10-27 09:00:57 +04:00
for ( i = 0x60 ; i < = 0x63 ; i + + ) {
2005-11-09 08:37:48 +03:00
msg . addr = i ;
2007-08-21 08:24:42 +04:00
ret = i2c_transfer ( priv - > i2c_props . adap , & msg , 1 ) ;
2005-11-09 08:37:48 +03:00
if ( ret = = 1 ) {
tuners_found + + ;
tuner_addrs = ( tuner_addrs < < 8 ) + i ;
}
}
/* if there is more than one tuner, we expect the right one is
behind the bridge and we choose the highest address that doesn ' t
give a response now
*/
2007-10-27 09:00:57 +04:00
ops - > i2c_gate_ctrl ( fe , 0 ) ;
if ( tuners_found > 1 )
2005-11-09 08:37:48 +03:00
for ( i = 0 ; i < tuners_found ; i + + ) {
msg . addr = tuner_addrs & 0xff ;
2007-08-21 08:24:42 +04:00
ret = i2c_transfer ( priv - > i2c_props . adap , & msg , 1 ) ;
2007-10-27 09:00:57 +04:00
if ( ret = = 1 )
2005-11-09 08:37:48 +03:00
tuner_addrs = tuner_addrs > > 8 ;
else
break ;
}
2007-10-27 09:00:57 +04:00
2005-11-09 08:37:48 +03:00
if ( tuner_addrs = = 0 ) {
2007-10-27 09:00:57 +04:00
tuner_addrs = 0x60 ;
tuner_info ( " could not clearly identify tuner address, "
" defaulting to %x \n " , tuner_addrs ) ;
2005-11-09 08:37:48 +03:00
} else {
tuner_addrs = tuner_addrs & 0xff ;
2007-08-28 04:22:20 +04:00
tuner_info ( " setting tuner address to %x \n " , tuner_addrs ) ;
2005-11-09 08:37:48 +03:00
}
2007-05-30 05:54:06 +04:00
priv - > tda827x_addr = tuner_addrs ;
2005-11-09 08:37:48 +03:00
msg . addr = tuner_addrs ;
2007-10-27 09:00:57 +04:00
ops - > i2c_gate_ctrl ( fe , 1 ) ;
2007-08-21 08:24:42 +04:00
ret = i2c_transfer ( priv - > i2c_props . adap , & msg , 1 ) ;
2007-08-28 04:22:20 +04:00
2007-10-27 09:00:57 +04:00
if ( ret ! = 1 ) {
tuner_warn ( " tuner access failed! \n " ) ;
return - EREMOTEIO ;
2005-11-09 08:37:48 +03:00
}
2007-08-26 02:08:45 +04:00
2007-10-27 09:00:57 +04:00
if ( data = = 0x83 ) {
priv - > ver | = TDA18271 ;
tda18271_attach ( & t - > fe , priv - > tda827x_addr ,
priv - > i2c_props . adap ) ;
} else {
if ( ( data & 0x3c ) = = 0 )
priv - > ver | = TDA8275 ;
else
priv - > ver | = TDA8275A ;
2007-06-06 23:15:15 +04:00
2007-10-27 09:00:57 +04:00
tda827x_attach ( & t - > fe , priv - > tda827x_addr ,
priv - > i2c_props . adap , & priv - > cfg ) ;
}
2007-11-23 21:08:11 +03:00
if ( t - > fe . ops . tuner_ops . init )
t - > fe . ops . tuner_ops . init ( & t - > fe ) ;
if ( t - > fe . ops . tuner_ops . sleep )
t - > fe . ops . tuner_ops . sleep ( & t - > fe ) ;
2007-10-27 09:00:57 +04:00
ops - > i2c_gate_ctrl ( fe , 0 ) ;
2007-08-26 02:08:45 +04:00
2007-10-27 09:00:57 +04:00
switch ( priv - > ver ) {
case TDA8290 | TDA8275 :
2007-09-14 12:13:54 +04:00
strlcpy ( t - > i2c - > name , " tda8290+75 " , sizeof ( t - > i2c - > name ) ) ;
2007-10-27 09:00:57 +04:00
break ;
case TDA8295 | TDA8275 :
2007-09-14 12:13:54 +04:00
strlcpy ( t - > i2c - > name , " tda8295+75 " , sizeof ( t - > i2c - > name ) ) ;
2007-10-27 09:00:57 +04:00
break ;
case TDA8290 | TDA8275A :
2007-09-14 12:13:54 +04:00
strlcpy ( t - > i2c - > name , " tda8290+75a " , sizeof ( t - > i2c - > name ) ) ;
2007-10-27 09:00:57 +04:00
break ;
case TDA8295 | TDA8275A :
2007-09-14 12:13:54 +04:00
strlcpy ( t - > i2c - > name , " tda8295+75a " , sizeof ( t - > i2c - > name ) ) ;
2007-10-27 09:00:57 +04:00
break ;
case TDA8290 | TDA18271 :
2007-09-14 12:13:54 +04:00
strlcpy ( t - > i2c - > name , " tda8290+18271 " , sizeof ( t - > i2c - > name ) ) ;
2007-10-27 09:00:57 +04:00
break ;
case TDA8295 | TDA18271 :
2007-09-14 12:13:54 +04:00
strlcpy ( t - > i2c - > name , " tda8295+18271 " , sizeof ( t - > i2c - > name ) ) ;
2007-10-27 09:00:57 +04:00
break ;
default :
return - EINVAL ;
}
2007-08-26 02:08:45 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2007-10-22 16:56:38 +04:00
2007-11-04 04:14:54 +03:00
static int tda8290_probe ( struct tuner_i2c_props * i2c_props )
{
# define TDA8290_ID 0x89
unsigned char tda8290_id [ ] = { 0x1f , 0x00 } ;
/* detect tda8290 */
tuner_i2c_xfer_send ( i2c_props , & tda8290_id [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( i2c_props , & tda8290_id [ 1 ] , 1 ) ;
if ( tda8290_id [ 1 ] = = TDA8290_ID ) {
if ( tuner_debug )
printk ( KERN_DEBUG " %s: tda8290 detected @ %d-%04x \n " ,
__FUNCTION__ , i2c_adapter_id ( i2c_props - > adap ) ,
i2c_props - > addr ) ;
return 0 ;
}
2007-11-04 16:51:28 +03:00
return - ENODEV ;
2007-11-04 04:14:54 +03:00
}
static int tda8295_probe ( struct tuner_i2c_props * i2c_props )
{
# define TDA8295_ID 0x8a
unsigned char tda8295_id [ ] = { 0x2f , 0x00 } ;
/* detect tda8295 */
tuner_i2c_xfer_send ( i2c_props , & tda8295_id [ 0 ] , 1 ) ;
tuner_i2c_xfer_recv ( i2c_props , & tda8295_id [ 1 ] , 1 ) ;
if ( tda8295_id [ 1 ] = = TDA8295_ID ) {
if ( tuner_debug )
printk ( KERN_DEBUG " %s: tda8295 detected @ %d-%04x \n " ,
__FUNCTION__ , i2c_adapter_id ( i2c_props - > adap ) ,
i2c_props - > addr ) ;
return 0 ;
}
2007-11-04 16:51:28 +03:00
return - ENODEV ;
2007-11-04 04:14:54 +03:00
}
2007-10-27 09:00:57 +04:00
static struct analog_tuner_ops tda8290_tuner_ops = {
. set_tv_freq = tda8290_set_freq ,
. set_radio_freq = tda8290_set_freq ,
. has_signal = tda8290_has_signal ,
. standby = tda8290_standby ,
. release = tda829x_release ,
. i2c_gate_ctrl = tda8290_i2c_bridge ,
} ;
static struct analog_tuner_ops tda8295_tuner_ops = {
. set_tv_freq = tda8295_set_freq ,
. set_radio_freq = tda8295_set_freq ,
. has_signal = tda8295_has_signal ,
. standby = tda8295_standby ,
. release = tda829x_release ,
. i2c_gate_ctrl = tda8295_i2c_bridge ,
} ;
int tda829x_attach ( struct tuner * t )
2007-10-22 16:56:38 +04:00
{
2007-10-27 09:00:57 +04:00
struct dvb_frontend * fe = & t - > fe ;
2007-10-22 16:56:38 +04:00
struct tda8290_priv * priv = NULL ;
2007-10-27 09:00:57 +04:00
2007-10-22 16:56:38 +04:00
priv = kzalloc ( sizeof ( struct tda8290_priv ) , GFP_KERNEL ) ;
if ( priv = = NULL )
return - ENOMEM ;
2007-10-27 09:00:57 +04:00
fe - > analog_demod_priv = priv ;
2007-10-22 16:56:38 +04:00
2007-09-14 12:13:54 +04:00
priv - > i2c_props . addr = t - > i2c - > addr ;
priv - > i2c_props . adap = t - > i2c - > adapter ;
2007-10-27 09:00:57 +04:00
priv - > cfg . config = & t - > config ;
priv - > cfg . tuner_callback = t - > tuner_callback ;
2007-10-22 02:39:50 +04:00
priv - > t = t ;
2007-10-22 16:56:38 +04:00
2007-11-04 04:14:54 +03:00
if ( tda8290_probe ( & priv - > i2c_props ) = = 0 ) {
2007-10-27 09:00:57 +04:00
priv - > ver = TDA8290 ;
fe - > ops . analog_demod_ops = & tda8290_tuner_ops ;
2007-10-22 16:56:38 +04:00
}
2007-10-27 09:00:57 +04:00
2007-11-04 04:14:54 +03:00
if ( tda8295_probe ( & priv - > i2c_props ) = = 0 ) {
2007-10-27 09:00:57 +04:00
priv - > ver = TDA8295 ;
fe - > ops . analog_demod_ops = & tda8295_tuner_ops ;
2007-10-22 16:56:38 +04:00
}
2007-10-27 09:00:57 +04:00
if ( tda829x_find_tuner ( fe ) < 0 )
return - EINVAL ;
2007-10-22 16:56:38 +04:00
2007-10-27 09:00:57 +04:00
if ( priv - > ver & TDA8290 ) {
tda8290_init_tuner ( fe ) ;
tda8290_init_if ( fe ) ;
} else if ( priv - > ver & TDA8295 )
tda8295_init_if ( fe ) ;
2007-10-22 16:56:38 +04:00
2007-09-14 12:13:54 +04:00
tuner_info ( " type set to %s \n " , t - > i2c - > name ) ;
2007-10-22 16:56:38 +04:00
t - > mode = V4L2_TUNER_ANALOG_TV ;
return 0 ;
}
2007-10-27 09:00:57 +04:00
EXPORT_SYMBOL_GPL ( tda829x_attach ) ;
2005-04-17 02:20:36 +04:00
2007-11-04 04:14:54 +03:00
int tda829x_probe ( struct tuner * t )
2005-11-09 08:38:00 +03:00
{
2007-08-28 04:22:20 +04:00
struct tuner_i2c_props i2c_props = {
2007-09-14 12:13:54 +04:00
. adap = t - > i2c - > adapter ,
. addr = t - > i2c - > addr
2007-08-28 04:22:20 +04:00
} ;
2007-08-21 08:24:42 +04:00
2006-02-27 06:09:11 +03:00
unsigned char soft_reset [ ] = { 0x00 , 0x00 } ;
unsigned char easy_mode_b [ ] = { 0x01 , 0x02 } ;
unsigned char easy_mode_g [ ] = { 0x01 , 0x04 } ;
unsigned char restore_9886 [ ] = { 0x00 , 0xd6 , 0x30 } ;
2005-11-09 08:38:00 +03:00
unsigned char addr_dto_lsb = 0x07 ;
unsigned char data ;
2007-11-04 17:03:22 +03:00
# define PROBE_BUFFER_SIZE 8
unsigned char buf [ PROBE_BUFFER_SIZE ] ;
int i ;
/* rule out tda9887, which would return the same byte repeatedly */
tuner_i2c_xfer_send ( & i2c_props , soft_reset , 1 ) ;
tuner_i2c_xfer_recv ( & i2c_props , buf , PROBE_BUFFER_SIZE ) ;
for ( i = 1 ; i < PROBE_BUFFER_SIZE ; i + + ) {
2007-11-05 15:54:42 +03:00
if ( buf [ i ] ! = buf [ 0 ] )
break ;
2007-11-04 17:03:22 +03:00
}
/* all bytes are equal, not a tda829x - probably a tda9887 */
if ( i = = PROBE_BUFFER_SIZE )
return - ENODEV ;
2005-11-09 08:38:00 +03:00
2007-11-04 04:14:54 +03:00
if ( ( tda8290_probe ( & i2c_props ) = = 0 ) | |
( tda8295_probe ( & i2c_props ) = = 0 ) )
return 0 ;
/* fall back to old probing method */
2007-08-28 04:22:20 +04:00
tuner_i2c_xfer_send ( & i2c_props , easy_mode_b , 2 ) ;
tuner_i2c_xfer_send ( & i2c_props , soft_reset , 2 ) ;
tuner_i2c_xfer_send ( & i2c_props , & addr_dto_lsb , 1 ) ;
tuner_i2c_xfer_recv ( & i2c_props , & data , 1 ) ;
2005-11-09 08:38:00 +03:00
if ( data = = 0 ) {
2007-08-28 04:22:20 +04:00
tuner_i2c_xfer_send ( & i2c_props , easy_mode_g , 2 ) ;
tuner_i2c_xfer_send ( & i2c_props , soft_reset , 2 ) ;
tuner_i2c_xfer_send ( & i2c_props , & addr_dto_lsb , 1 ) ;
tuner_i2c_xfer_recv ( & i2c_props , & data , 1 ) ;
2005-11-09 08:38:00 +03:00
if ( data = = 0x7b ) {
return 0 ;
}
}
2007-08-28 04:22:20 +04:00
tuner_i2c_xfer_send ( & i2c_props , restore_9886 , 3 ) ;
2007-11-04 16:51:28 +03:00
return - ENODEV ;
2005-11-09 08:38:00 +03:00
}
2007-11-04 04:14:54 +03:00
EXPORT_SYMBOL_GPL ( tda829x_probe ) ;
2007-08-28 04:22:20 +04:00
2007-10-27 09:00:57 +04:00
MODULE_DESCRIPTION ( " Philips/NXP TDA8290/TDA8295 analog IF demodulator driver " ) ;
2007-10-22 16:56:38 +04:00
MODULE_AUTHOR ( " Gerd Knorr, Hartmut Hackmann, Michael Krufky " ) ;
2007-08-28 04:22:20 +04:00
MODULE_LICENSE ( " GPL " ) ;
2005-04-17 02:20:36 +04:00
/*
* Overrides for Emacs so that we follow Linus ' s tabbing style .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Local variables :
* c - basic - offset : 8
* End :
*/