2009-03-03 20:37:50 +03:00
/*
2009-03-03 19:31:36 +03:00
cx231xx_avcore . c - driver for Conexant Cx23100 / 101 / 102
USB video capture devices
2009-03-03 20:37:50 +03:00
Copyright ( C ) 2008 < srinivasa . deevi at conexant dot com >
This program contains the specific code to control the avdecoder chip and
other related usb control functions for cx231xx based chipset .
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/init.h>
# include <linux/list.h>
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/bitmap.h>
# include <linux/usb.h>
# include <linux/i2c.h>
# include <linux/mm.h>
# include <linux/mutex.h>
2010-07-07 01:12:25 +04:00
# include <media/tuner.h>
2009-03-03 20:37:50 +03:00
# include <media/v4l2-common.h>
# include <media/v4l2-ioctl.h>
# include "cx231xx.h"
2010-07-07 01:12:25 +04:00
# include "cx231xx-dif.h"
2009-03-03 20:37:50 +03:00
2010-07-07 01:12:25 +04:00
# define TUNER_MODE_FM_RADIO 0
2009-03-03 19:31:36 +03:00
/******************************************************************************
2009-03-22 04:00:20 +03:00
- : BLOCK ARRANGEMENT : -
I2S block - - - - - - - - - - - - - - - - - - - - - - |
[ I2S audio ] |
|
Analog Front End - - > Direct IF - | - > Cx25840 - - > Audio
[ video & audio ] | [ Audio ]
|
| - > Cx25840 - - > Video
[ Video ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-07 01:12:25 +04:00
/******************************************************************************
* VERVE REGISTER *
2010-10-07 10:23:25 +04:00
* *
2010-07-07 01:12:25 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int verve_write_byte ( struct cx231xx * dev , u8 saddr , u8 data )
{
return cx231xx_write_i2c_data ( dev , VERVE_I2C_ADDRESS ,
saddr , 1 , data , 1 ) ;
}
static int verve_read_byte ( struct cx231xx * dev , u8 saddr , u8 * data )
{
int status ;
u32 temp = 0 ;
status = cx231xx_read_i2c_data ( dev , VERVE_I2C_ADDRESS ,
saddr , 1 , & temp , 1 ) ;
* data = ( u8 ) temp ;
return status ;
}
void initGPIO ( struct cx231xx * dev )
{
u32 _gpio_direction = 0 ;
u32 value = 0 ;
u8 val = 0 ;
_gpio_direction = _gpio_direction & 0xFC0003FF ;
_gpio_direction = _gpio_direction | 0x03FDFC00 ;
cx231xx_send_gpio_cmd ( dev , _gpio_direction , ( u8 * ) & value , 4 , 0 , 0 ) ;
verve_read_byte ( dev , 0x07 , & val ) ;
cx231xx_info ( " verve_read_byte address0x07=0x%x \n " , val ) ;
verve_write_byte ( dev , 0x07 , 0xF4 ) ;
verve_read_byte ( dev , 0x07 , & val ) ;
cx231xx_info ( " verve_read_byte address0x07=0x%x \n " , val ) ;
2012-06-18 07:20:06 +04:00
cx231xx_capture_start ( dev , 1 , Vbi ) ;
2010-07-07 01:12:25 +04:00
cx231xx_mode_register ( dev , EP_MODE_SET , 0x0500FE00 ) ;
cx231xx_mode_register ( dev , GBULK_BIT_EN , 0xFFFDFFFF ) ;
}
void uninitGPIO ( struct cx231xx * dev )
{
u8 value [ 4 ] = { 0 , 0 , 0 , 0 } ;
2012-06-18 07:20:06 +04:00
cx231xx_capture_start ( dev , 0 , Vbi ) ;
2010-07-07 01:12:25 +04:00
verve_write_byte ( dev , 0x07 , 0x14 ) ;
cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
0x68 , value , 4 ) ;
}
2009-03-22 04:00:20 +03:00
/******************************************************************************
* A F E - B L O C K C O N T R O L functions *
* [ ANALOG FRONT END ] *
2009-03-11 03:16:26 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-22 04:00:20 +03:00
static int afe_write_byte ( struct cx231xx * dev , u16 saddr , u8 data )
{
return cx231xx_write_i2c_data ( dev , AFE_DEVICE_ADDRESS ,
saddr , 2 , data , 1 ) ;
}
static int afe_read_byte ( struct cx231xx * dev , u16 saddr , u8 * data )
{
int status ;
u32 temp = 0 ;
status = cx231xx_read_i2c_data ( dev , AFE_DEVICE_ADDRESS ,
saddr , 2 , & temp , 1 ) ;
* data = ( u8 ) temp ;
return status ;
}
int cx231xx_afe_init_super_block ( struct cx231xx * dev , u32 ref_count )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
u8 temp = 0 ;
2009-03-22 04:00:20 +03:00
u8 afe_power_status = 0 ;
2009-03-03 12:14:34 +03:00
int i = 0 ;
/* super block initialize */
temp = ( u8 ) ( ref_count & 0xff ) ;
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_TUNE2 , temp ) ;
2009-03-11 03:16:26 +03:00
if ( status < 0 )
return status ;
2009-03-03 12:14:34 +03:00
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , SUP_BLK_TUNE2 , & afe_power_status ) ;
2009-03-11 03:16:26 +03:00
if ( status < 0 )
return status ;
2009-03-03 12:14:34 +03:00
temp = ( u8 ) ( ( ref_count & 0x300 ) > > 8 ) ;
temp | = 0x40 ;
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_TUNE1 , temp ) ;
2009-03-11 03:16:26 +03:00
if ( status < 0 )
return status ;
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_PLL2 , 0x0f ) ;
2009-03-11 03:16:26 +03:00
if ( status < 0 )
return status ;
2009-03-03 12:14:34 +03:00
/* enable pll */
2009-03-22 04:00:20 +03:00
while ( afe_power_status ! = 0x18 ) {
status = afe_write_byte ( dev , SUP_BLK_PWRDN , 0x18 ) ;
2009-03-11 03:16:26 +03:00
if ( status < 0 ) {
cx231xx_info (
" : Init Super Block failed in send cmd \n " ) ;
break ;
}
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , SUP_BLK_PWRDN , & afe_power_status ) ;
afe_power_status & = 0xff ;
2009-03-03 12:14:34 +03:00
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_info (
2009-03-11 03:16:26 +03:00
" : Init Super Block failed in receive cmd \n " ) ;
2009-03-03 12:14:34 +03:00
break ;
}
i + + ;
if ( i = = 10 ) {
2009-03-04 23:49:01 +03:00
cx231xx_info (
" : Init Super Block force break in loop !!!! \n " ) ;
2009-03-03 12:14:34 +03:00
status = - 1 ;
break ;
}
}
if ( status < 0 )
return status ;
/* start tuning filter */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_TUNE3 , 0x40 ) ;
2009-03-11 03:16:26 +03:00
if ( status < 0 )
return status ;
2009-03-03 12:14:34 +03:00
msleep ( 5 ) ;
/* exit tuning */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_TUNE3 , 0x00 ) ;
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-22 04:00:20 +03:00
int cx231xx_afe_init_channels ( struct cx231xx * dev )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
/* power up all 3 channels, clear pd_buffer */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH1 , 0x00 ) ;
status = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 , 0x00 ) ;
status = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 , 0x00 ) ;
2009-03-03 12:14:34 +03:00
/* Enable quantizer calibration */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_COM_QUANT , 0x02 ) ;
2009-03-03 12:14:34 +03:00
/* channel initialize, force modulator (fb) reset */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_FB_FRCRST_CH1 , 0x17 ) ;
status = afe_write_byte ( dev , ADC_FB_FRCRST_CH2 , 0x17 ) ;
status = afe_write_byte ( dev , ADC_FB_FRCRST_CH3 , 0x17 ) ;
2009-03-03 12:14:34 +03:00
/* start quantilizer calibration */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_CAL_ATEST_CH1 , 0x10 ) ;
status = afe_write_byte ( dev , ADC_CAL_ATEST_CH2 , 0x10 ) ;
status = afe_write_byte ( dev , ADC_CAL_ATEST_CH3 , 0x10 ) ;
2009-03-03 12:14:34 +03:00
msleep ( 5 ) ;
/* exit modulator (fb) reset */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_FB_FRCRST_CH1 , 0x07 ) ;
status = afe_write_byte ( dev , ADC_FB_FRCRST_CH2 , 0x07 ) ;
status = afe_write_byte ( dev , ADC_FB_FRCRST_CH3 , 0x07 ) ;
2009-03-03 12:14:34 +03:00
/* enable the pre_clamp in each channel for single-ended input */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_NTF_PRECLMP_EN_CH1 , 0xf0 ) ;
status = afe_write_byte ( dev , ADC_NTF_PRECLMP_EN_CH2 , 0xf0 ) ;
status = afe_write_byte ( dev , ADC_NTF_PRECLMP_EN_CH3 , 0xf0 ) ;
2009-03-03 12:14:34 +03:00
/* use diode instead of resistor, so set term_en to 0, res_en to 0 */
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , AFE_DEVICE_ADDRESS , 8 ,
2009-03-03 12:14:34 +03:00
ADC_QGAIN_RES_TRM_CH1 , 3 , 7 , 0x00 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , AFE_DEVICE_ADDRESS , 8 ,
2009-03-03 12:14:34 +03:00
ADC_QGAIN_RES_TRM_CH2 , 3 , 7 , 0x00 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , AFE_DEVICE_ADDRESS , 8 ,
2009-03-03 12:14:34 +03:00
ADC_QGAIN_RES_TRM_CH3 , 3 , 7 , 0x00 ) ;
/* dynamic element matching off */
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_DCSERVO_DEM_CH1 , 0x03 ) ;
status = afe_write_byte ( dev , ADC_DCSERVO_DEM_CH2 , 0x03 ) ;
status = afe_write_byte ( dev , ADC_DCSERVO_DEM_CH3 , 0x03 ) ;
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-22 04:00:20 +03:00
int cx231xx_afe_setup_AFE_for_baseband ( struct cx231xx * dev )
2009-03-03 20:37:50 +03:00
{
2009-03-22 04:00:20 +03:00
u8 c_value = 0 ;
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , ADC_PWRDN_CLAMP_CH2 , & c_value ) ;
2009-03-03 12:14:34 +03:00
c_value & = ( ~ ( 0x50 ) ) ;
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 , c_value ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
/*
2009-03-11 03:16:26 +03:00
The Analog Front End in Cx231xx has 3 channels . These
channels are used to share between different inputs
like tuner , s - video and composite inputs .
2009-03-03 20:37:50 +03:00
channel 1 - - - - - pin 1 to pin4 ( in reg is 1 - 4 )
channel 2 - - - - - pin 5 to pin8 ( in reg is 5 - 8 )
channel 3 - - - - - pin 9 to pin 12 ( in reg is 9 - 11 )
*/
2009-03-22 04:00:20 +03:00
int cx231xx_afe_set_input_mux ( struct cx231xx * dev , u32 input_mux )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
u8 ch1_setting = ( u8 ) input_mux ;
u8 ch2_setting = ( u8 ) ( input_mux > > 8 ) ;
u8 ch3_setting = ( u8 ) ( input_mux > > 16 ) ;
int status = 0 ;
2009-03-22 04:00:20 +03:00
u8 value = 0 ;
2009-03-03 12:14:34 +03:00
if ( ch1_setting ! = 0 ) {
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , ADC_INPUT_CH1 , & value ) ;
2010-12-28 03:04:58 +03:00
value & = ~ INPUT_SEL_MASK ;
2009-03-03 12:14:34 +03:00
value | = ( ch1_setting - 1 ) < < 4 ;
value & = 0xff ;
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_INPUT_CH1 , value ) ;
2009-03-03 12:14:34 +03:00
}
if ( ch2_setting ! = 0 ) {
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , ADC_INPUT_CH2 , & value ) ;
2010-12-28 03:04:58 +03:00
value & = ~ INPUT_SEL_MASK ;
2009-03-03 12:14:34 +03:00
value | = ( ch2_setting - 1 ) < < 4 ;
value & = 0xff ;
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_INPUT_CH2 , value ) ;
2009-03-03 12:14:34 +03:00
}
2009-03-03 19:31:36 +03:00
/* For ch3_setting, the value to put in the register is
7 less than the input number */
2009-03-03 12:14:34 +03:00
if ( ch3_setting ! = 0 ) {
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , ADC_INPUT_CH3 , & value ) ;
2010-12-28 03:04:58 +03:00
value & = ~ INPUT_SEL_MASK ;
2009-03-03 12:14:34 +03:00
value | = ( ch3_setting - 1 ) < < 4 ;
value & = 0xff ;
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_INPUT_CH3 , value ) ;
2009-03-03 12:14:34 +03:00
}
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-22 04:00:20 +03:00
int cx231xx_afe_set_mode ( struct cx231xx * dev , enum AFE_MODE mode )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-11 03:16:26 +03:00
/*
* FIXME : We need to implement the AFE code for LOW IF and for HI IF .
* Currently , only baseband works .
*/
2009-03-03 12:14:34 +03:00
switch ( mode ) {
case AFE_MODE_LOW_IF :
2010-07-07 01:12:25 +04:00
cx231xx_Setup_AFE_for_LowIF ( dev ) ;
2009-03-03 12:14:34 +03:00
break ;
case AFE_MODE_BASEBAND :
2009-03-22 04:00:20 +03:00
status = cx231xx_afe_setup_AFE_for_baseband ( dev ) ;
2009-03-03 12:14:34 +03:00
break ;
case AFE_MODE_EU_HI_IF :
/* SetupAFEforEuHiIF(); */
break ;
case AFE_MODE_US_HI_IF :
/* SetupAFEforUsHiIF(); */
break ;
case AFE_MODE_JAPAN_HI_IF :
/* SetupAFEforJapanHiIF(); */
break ;
}
2009-03-22 04:00:20 +03:00
if ( ( mode ! = dev - > afe_mode ) & &
2009-03-04 23:49:01 +03:00
( dev - > video_input = = CX231XX_VMUX_TELEVISION ) )
2009-03-22 04:00:20 +03:00
status = cx231xx_afe_adjust_ref_count ( dev ,
2009-03-03 12:14:34 +03:00
CX231XX_VMUX_TELEVISION ) ;
2009-03-22 04:00:20 +03:00
dev - > afe_mode = mode ;
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-22 04:00:20 +03:00
int cx231xx_afe_update_power_control ( struct cx231xx * dev ,
2009-03-11 03:16:26 +03:00
enum AV_MODE avmode )
2009-03-03 20:37:50 +03:00
{
2009-03-22 04:00:20 +03:00
u8 afe_power_status = 0 ;
2009-03-03 12:14:34 +03:00
int status = 0 ;
switch ( dev - > model ) {
2010-07-07 01:12:25 +04:00
case CX231XX_BOARD_CNXT_CARRAERA :
2009-03-03 12:14:34 +03:00
case CX231XX_BOARD_CNXT_RDE_250 :
2010-07-07 01:12:25 +04:00
case CX231XX_BOARD_CNXT_SHELBY :
2009-03-03 12:14:34 +03:00
case CX231XX_BOARD_CNXT_RDU_250 :
2010-07-07 01:12:25 +04:00
case CX231XX_BOARD_CNXT_RDE_253S :
case CX231XX_BOARD_CNXT_RDU_253S :
case CX231XX_BOARD_CNXT_VIDEO_GRABBER :
2010-07-07 01:23:53 +04:00
case CX231XX_BOARD_HAUPPAUGE_EXETER :
2010-07-31 07:49:01 +04:00
case CX231XX_BOARD_HAUPPAUGE_USBLIVE2 :
2010-09-27 03:44:31 +04:00
case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID :
2011-06-08 22:54:19 +04:00
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL :
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC :
2013-03-02 02:53:30 +04:00
case CX231XX_BOARD_OTG102 :
2009-03-03 12:14:34 +03:00
if ( avmode = = POLARIS_AVMODE_ANALOGT_TV ) {
2009-03-22 04:00:20 +03:00
while ( afe_power_status ! = ( FLD_PWRDN_TUNING_BIAS |
2009-03-11 03:16:26 +03:00
FLD_PWRDN_ENABLE_PLL ) ) {
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_PWRDN ,
2009-03-11 03:16:26 +03:00
FLD_PWRDN_TUNING_BIAS |
2009-03-22 04:00:20 +03:00
FLD_PWRDN_ENABLE_PLL ) ;
status | = afe_read_byte ( dev , SUP_BLK_PWRDN ,
& afe_power_status ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 )
break ;
}
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH1 ,
0x00 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 ,
0x00 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 ,
0x00 ) ;
2009-03-03 12:14:34 +03:00
} else if ( avmode = = POLARIS_AVMODE_DIGITAL ) {
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH1 ,
0x70 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 ,
0x70 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 ,
0x70 ) ;
status | = afe_read_byte ( dev , SUP_BLK_PWRDN ,
& afe_power_status ) ;
afe_power_status | = FLD_PWRDN_PD_BANDGAP |
2009-03-11 03:16:26 +03:00
FLD_PWRDN_PD_BIAS |
FLD_PWRDN_PD_TUNECK ;
2009-03-22 04:00:20 +03:00
status | = afe_write_byte ( dev , SUP_BLK_PWRDN ,
afe_power_status ) ;
2009-03-03 12:14:34 +03:00
} else if ( avmode = = POLARIS_AVMODE_ENXTERNAL_AV ) {
2009-03-22 04:00:20 +03:00
while ( afe_power_status ! = ( FLD_PWRDN_TUNING_BIAS |
2009-03-11 03:16:26 +03:00
FLD_PWRDN_ENABLE_PLL ) ) {
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_PWRDN ,
2009-03-11 03:16:26 +03:00
FLD_PWRDN_TUNING_BIAS |
2009-03-22 04:00:20 +03:00
FLD_PWRDN_ENABLE_PLL ) ;
status | = afe_read_byte ( dev , SUP_BLK_PWRDN ,
& afe_power_status ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 )
break ;
}
2009-03-22 04:00:20 +03:00
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH1 ,
0x00 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 ,
0x00 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 ,
0x00 ) ;
2009-03-03 12:14:34 +03:00
} else {
cx231xx_info ( " Invalid AV mode input \n " ) ;
status = - 1 ;
}
break ;
default :
if ( avmode = = POLARIS_AVMODE_ANALOGT_TV ) {
2009-03-22 04:00:20 +03:00
while ( afe_power_status ! = ( FLD_PWRDN_TUNING_BIAS |
2009-03-11 03:16:26 +03:00
FLD_PWRDN_ENABLE_PLL ) ) {
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_PWRDN ,
2009-03-11 03:16:26 +03:00
FLD_PWRDN_TUNING_BIAS |
2009-03-22 04:00:20 +03:00
FLD_PWRDN_ENABLE_PLL ) ;
status | = afe_read_byte ( dev , SUP_BLK_PWRDN ,
& afe_power_status ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 )
break ;
}
2009-03-22 04:00:20 +03:00
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH1 ,
0x40 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 ,
0x40 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 ,
0x00 ) ;
2009-03-03 12:14:34 +03:00
} else if ( avmode = = POLARIS_AVMODE_DIGITAL ) {
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH1 ,
0x70 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 ,
0x70 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 ,
0x70 ) ;
status | = afe_read_byte ( dev , SUP_BLK_PWRDN ,
& afe_power_status ) ;
afe_power_status | = FLD_PWRDN_PD_BANDGAP |
2009-03-11 03:16:26 +03:00
FLD_PWRDN_PD_BIAS |
FLD_PWRDN_PD_TUNECK ;
2009-03-22 04:00:20 +03:00
status | = afe_write_byte ( dev , SUP_BLK_PWRDN ,
afe_power_status ) ;
2009-03-03 12:14:34 +03:00
} else if ( avmode = = POLARIS_AVMODE_ENXTERNAL_AV ) {
2009-03-22 04:00:20 +03:00
while ( afe_power_status ! = ( FLD_PWRDN_TUNING_BIAS |
2009-03-11 03:16:26 +03:00
FLD_PWRDN_ENABLE_PLL ) ) {
2009-03-22 04:00:20 +03:00
status = afe_write_byte ( dev , SUP_BLK_PWRDN ,
2009-03-11 03:16:26 +03:00
FLD_PWRDN_TUNING_BIAS |
2009-03-22 04:00:20 +03:00
FLD_PWRDN_ENABLE_PLL ) ;
status | = afe_read_byte ( dev , SUP_BLK_PWRDN ,
& afe_power_status ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 )
break ;
}
2009-03-22 04:00:20 +03:00
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH1 ,
0x00 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH2 ,
0x00 ) ;
status | = afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 ,
0x40 ) ;
2009-03-03 12:14:34 +03:00
} else {
cx231xx_info ( " Invalid AV mode input \n " ) ;
status = - 1 ;
}
} /* switch */
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-22 04:00:20 +03:00
int cx231xx_afe_adjust_ref_count ( struct cx231xx * dev , u32 video_input )
2009-03-03 20:37:50 +03:00
{
2009-03-22 04:00:20 +03:00
u8 input_mode = 0 ;
u8 ntf_mode = 0 ;
2009-03-03 12:14:34 +03:00
int status = 0 ;
dev - > video_input = video_input ;
if ( video_input = = CX231XX_VMUX_TELEVISION ) {
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , ADC_INPUT_CH3 , & input_mode ) ;
status = afe_read_byte ( dev , ADC_NTF_PRECLMP_EN_CH3 ,
& ntf_mode ) ;
2009-03-03 12:14:34 +03:00
} else {
2009-03-22 04:00:20 +03:00
status = afe_read_byte ( dev , ADC_INPUT_CH1 , & input_mode ) ;
status = afe_read_byte ( dev , ADC_NTF_PRECLMP_EN_CH1 ,
& ntf_mode ) ;
2009-03-03 12:14:34 +03:00
}
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
input_mode = ( ntf_mode & 0x3 ) | ( ( input_mode & 0x6 ) < < 1 ) ;
switch ( input_mode ) {
case SINGLE_ENDED :
2009-03-22 04:00:20 +03:00
dev - > afe_ref_count = 0x23C ;
2009-03-03 12:14:34 +03:00
break ;
case LOW_IF :
2009-03-22 04:00:20 +03:00
dev - > afe_ref_count = 0x24C ;
2009-03-03 12:14:34 +03:00
break ;
case EU_IF :
2009-03-22 04:00:20 +03:00
dev - > afe_ref_count = 0x258 ;
2009-03-03 12:14:34 +03:00
break ;
case US_IF :
2009-03-22 04:00:20 +03:00
dev - > afe_ref_count = 0x260 ;
2009-03-03 12:14:34 +03:00
break ;
default :
break ;
}
2009-03-22 04:00:20 +03:00
status = cx231xx_afe_init_super_block ( dev , dev - > afe_ref_count ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
}
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
/******************************************************************************
* V I D E O / A U D I O D E C O D E R C O N T R O L functions *
2009-03-11 03:16:26 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-22 04:00:20 +03:00
static int vid_blk_write_byte ( struct cx231xx * dev , u16 saddr , u8 data )
{
return cx231xx_write_i2c_data ( dev , VID_BLK_I2C_ADDRESS ,
saddr , 2 , data , 1 ) ;
}
static int vid_blk_read_byte ( struct cx231xx * dev , u16 saddr , u8 * data )
{
int status ;
u32 temp = 0 ;
status = cx231xx_read_i2c_data ( dev , VID_BLK_I2C_ADDRESS ,
saddr , 2 , & temp , 1 ) ;
* data = ( u8 ) temp ;
return status ;
}
static int vid_blk_write_word ( struct cx231xx * dev , u16 saddr , u32 data )
{
return cx231xx_write_i2c_data ( dev , VID_BLK_I2C_ADDRESS ,
saddr , 2 , data , 4 ) ;
}
static int vid_blk_read_word ( struct cx231xx * dev , u16 saddr , u32 * data )
{
return cx231xx_read_i2c_data ( dev , VID_BLK_I2C_ADDRESS ,
saddr , 2 , data , 4 ) ;
}
2010-07-07 01:12:25 +04:00
int cx231xx_check_fw ( struct cx231xx * dev )
{
u8 temp = 0 ;
int status = 0 ;
status = vid_blk_read_byte ( dev , DL_CTL_ADDRESS_LOW , & temp ) ;
if ( status < 0 )
return status ;
else
return temp ;
}
2009-03-22 04:00:20 +03:00
2009-03-03 20:37:50 +03:00
int cx231xx_set_video_input_mux ( struct cx231xx * dev , u8 input )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
switch ( INPUT ( input ) - > type ) {
case CX231XX_VMUX_COMPOSITE1 :
case CX231XX_VMUX_SVIDEO :
if ( ( dev - > current_pcb_config . type = = USB_BUS_POWER ) & &
( dev - > power_mode ! = POLARIS_AVMODE_ENXTERNAL_AV ) ) {
2009-03-03 19:31:36 +03:00
/* External AV */
status = cx231xx_set_power_mode ( dev ,
POLARIS_AVMODE_ENXTERNAL_AV ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: set_power_mode : Failed to "
" set Power - errCode [%d]! \n " ,
__func__ , status ) ;
2009-03-03 12:14:34 +03:00
return status ;
}
}
2009-03-03 19:31:36 +03:00
status = cx231xx_set_decoder_video_input ( dev ,
INPUT ( input ) - > type ,
INPUT ( input ) - > vmux ) ;
2009-03-03 12:14:34 +03:00
break ;
case CX231XX_VMUX_TELEVISION :
case CX231XX_VMUX_CABLE :
if ( ( dev - > current_pcb_config . type = = USB_BUS_POWER ) & &
( dev - > power_mode ! = POLARIS_AVMODE_ANALOGT_TV ) ) {
2009-03-03 19:31:36 +03:00
/* Tuner */
status = cx231xx_set_power_mode ( dev ,
POLARIS_AVMODE_ANALOGT_TV ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: set_power_mode:Failed "
" to set Power - errCode [%d]! \n " ,
__func__ , status ) ;
2009-03-03 12:14:34 +03:00
return status ;
}
}
2010-07-07 01:12:25 +04:00
if ( dev - > tuner_type = = TUNER_NXP_TDA18271 )
status = cx231xx_set_decoder_video_input ( dev ,
CX231XX_VMUX_TELEVISION ,
INPUT ( input ) - > vmux ) ;
else
status = cx231xx_set_decoder_video_input ( dev ,
2009-03-03 19:31:36 +03:00
CX231XX_VMUX_COMPOSITE1 ,
INPUT ( input ) - > vmux ) ;
2010-07-07 01:12:25 +04:00
2009-03-03 12:14:34 +03:00
break ;
default :
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: set_power_mode : Unknown Input %d ! \n " ,
2009-03-03 12:14:34 +03:00
__func__ , INPUT ( input ) - > type ) ;
break ;
}
/* save the selection */
dev - > video_input = input ;
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-04 23:49:01 +03:00
int cx231xx_set_decoder_video_input ( struct cx231xx * dev ,
u8 pin_type , u8 input )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
u32 value = 0 ;
if ( pin_type ! = dev - > video_input ) {
2009-03-22 04:00:20 +03:00
status = cx231xx_afe_adjust_ref_count ( dev , pin_type ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: adjust_ref_count :Failed to set "
2009-03-22 04:00:20 +03:00
" AFE input mux - errCode [%d]! \n " ,
2009-03-04 23:49:01 +03:00
__func__ , status ) ;
2009-03-03 12:14:34 +03:00
return status ;
}
}
2009-03-03 20:37:50 +03:00
2009-03-22 04:00:20 +03:00
/* call afe block to set video inputs */
status = cx231xx_afe_set_input_mux ( dev , input ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: set_input_mux :Failed to set "
2009-03-22 04:00:20 +03:00
" AFE input mux - errCode [%d]! \n " ,
2009-03-04 23:49:01 +03:00
__func__ , status ) ;
2009-03-03 12:14:34 +03:00
return status ;
}
switch ( pin_type ) {
case CX231XX_VMUX_COMPOSITE1 :
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , AFE_CTRL , & value ) ;
2009-03-03 19:31:36 +03:00
value | = ( 0 < < 13 ) | ( 1 < < 4 ) ;
value & = ~ ( 1 < < 5 ) ;
2009-03-04 23:49:01 +03:00
/* set [24:23] [22:15] to 0 */
value & = ( ~ ( 0x1ff8000 ) ) ;
/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
value | = 0x1000000 ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AFE_CTRL , value ) ;
2009-03-03 19:31:36 +03:00
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , OUT_CTRL1 , & value ) ;
2009-03-03 19:31:36 +03:00
value | = ( 1 < < 7 ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , OUT_CTRL1 , value ) ;
2009-03-03 19:31:36 +03:00
2010-08-19 00:50:07 +04:00
/* Set output mode */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
OUT_CTRL1 ,
FLD_OUT_MODE ,
2010-08-19 00:50:07 +04:00
dev - > board . output_mode ) ;
2009-03-03 19:31:36 +03:00
/* Tell DIF object to go to baseband mode */
status = cx231xx_dif_set_standard ( dev , DIF_USE_BASEBAND ) ;
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: cx231xx_dif set to By pass "
" mode- errCode [%d]! \n " ,
2009-03-03 19:31:36 +03:00
__func__ , status ) ;
return status ;
}
/* Read the DFE_CTRL1 register */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DFE_CTRL1 , & value ) ;
2009-03-03 19:31:36 +03:00
/* enable the VBI_GATE_EN */
value | = FLD_VBI_GATE_EN ;
/* Enable the auto-VGA enable */
value | = FLD_VGA_AUTO_EN ;
/* Write it back */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DFE_CTRL1 , value ) ;
2009-03-03 19:31:36 +03:00
/* Disable auto config of registers */
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL , FLD_ACFG_DIS ,
cx231xx_set_field ( FLD_ACFG_DIS , 1 ) ) ;
/* Set CVBS input mode */
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL , FLD_INPUT_MODE ,
cx231xx_set_field ( FLD_INPUT_MODE , INPUT_MODE_CVBS_0 ) ) ;
break ;
case CX231XX_VMUX_SVIDEO :
/* Disable the use of DIF */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , AFE_CTRL , & value ) ;
2009-03-03 19:31:36 +03:00
2009-03-04 23:49:01 +03:00
/* set [24:23] [22:15] to 0 */
value & = ( ~ ( 0x1ff8000 ) ) ;
/* set FUNC_MODE[24:23] = 2
IF_MOD [ 22 : 15 ] = 0 DCR_BYP_CH2 [ 4 : 4 ] = 1 ; */
value | = 0x1000010 ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AFE_CTRL , value ) ;
2009-03-03 19:31:36 +03:00
/* Tell DIF object to go to baseband mode */
status = cx231xx_dif_set_standard ( dev , DIF_USE_BASEBAND ) ;
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: cx231xx_dif set to By pass "
" mode- errCode [%d]! \n " ,
2009-03-03 19:31:36 +03:00
__func__ , status ) ;
return status ;
}
/* Read the DFE_CTRL1 register */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DFE_CTRL1 , & value ) ;
2009-03-03 19:31:36 +03:00
/* enable the VBI_GATE_EN */
value | = FLD_VBI_GATE_EN ;
/* Enable the auto-VGA enable */
value | = FLD_VGA_AUTO_EN ;
/* Write it back */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DFE_CTRL1 , value ) ;
2009-03-03 19:31:36 +03:00
/* Disable auto config of registers */
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL , FLD_ACFG_DIS ,
cx231xx_set_field ( FLD_ACFG_DIS , 1 ) ) ;
/* Set YC input mode */
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL ,
FLD_INPUT_MODE ,
cx231xx_set_field ( FLD_INPUT_MODE , INPUT_MODE_YC_1 ) ) ;
/* Chroma to ADC2 */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , AFE_CTRL , & value ) ;
2009-03-03 19:31:36 +03:00
value | = FLD_CHROMA_IN_SEL ; /* set the chroma in select */
/* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8)
This sets them to use video
rather than audio . Only one of the two will be in use . */
value & = ~ ( FLD_VGA_SEL_CH2 | FLD_VGA_SEL_CH3 ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AFE_CTRL , value ) ;
2009-03-03 19:31:36 +03:00
2009-03-22 04:00:20 +03:00
status = cx231xx_afe_set_mode ( dev , AFE_MODE_BASEBAND ) ;
2009-03-03 19:31:36 +03:00
break ;
case CX231XX_VMUX_TELEVISION :
case CX231XX_VMUX_CABLE :
default :
2011-02-01 04:12:15 +03:00
/* TODO: Test if this is also needed for xc2028/xc3028 */
if ( dev - > board . tuner_type = = TUNER_XC5000 ) {
2009-03-03 19:31:36 +03:00
/* Disable the use of DIF */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , AFE_CTRL , & value ) ;
2009-03-03 12:14:34 +03:00
value | = ( 0 < < 13 ) | ( 1 < < 4 ) ;
value & = ~ ( 1 < < 5 ) ;
2009-03-04 23:49:01 +03:00
/* set [24:23] [22:15] to 0 */
value & = ( ~ ( 0x1FF8000 ) ) ;
/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
value | = 0x1000000 ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AFE_CTRL , value ) ;
status = vid_blk_read_word ( dev , OUT_CTRL1 , & value ) ;
2009-03-03 12:14:34 +03:00
value | = ( 1 < < 7 ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , OUT_CTRL1 , value ) ;
2009-03-03 12:14:34 +03:00
2010-08-19 00:50:07 +04:00
/* Set output mode */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
OUT_CTRL1 , FLD_OUT_MODE ,
2010-08-19 00:50:07 +04:00
dev - > board . output_mode ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* Tell DIF object to go to baseband mode */
status = cx231xx_dif_set_standard ( dev ,
DIF_USE_BASEBAND ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: cx231xx_dif set to By pass "
" mode- errCode [%d]! \n " ,
__func__ , status ) ;
2009-03-03 12:14:34 +03:00
return status ;
}
/* Read the DFE_CTRL1 register */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DFE_CTRL1 , & value ) ;
2009-03-03 12:14:34 +03:00
/* enable the VBI_GATE_EN */
value | = FLD_VBI_GATE_EN ;
/* Enable the auto-VGA enable */
value | = FLD_VGA_AUTO_EN ;
/* Write it back */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DFE_CTRL1 , value ) ;
2009-03-03 12:14:34 +03:00
/* Disable auto config of registers */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL , FLD_ACFG_DIS ,
cx231xx_set_field ( FLD_ACFG_DIS , 1 ) ) ;
2009-03-03 12:14:34 +03:00
/* Set CVBS input mode */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL , FLD_INPUT_MODE ,
2009-03-04 23:49:01 +03:00
cx231xx_set_field ( FLD_INPUT_MODE ,
INPUT_MODE_CVBS_0 ) ) ;
2011-02-01 04:12:15 +03:00
} else {
2009-03-03 19:31:36 +03:00
/* Enable the DIF for the tuner */
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* Reinitialize the DIF */
status = cx231xx_dif_set_standard ( dev , dev - > norm ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 ) {
2009-03-04 23:49:01 +03:00
cx231xx_errdev ( " %s: cx231xx_dif set to By pass "
" mode- errCode [%d]! \n " ,
__func__ , status ) ;
2009-03-03 12:14:34 +03:00
return status ;
}
2009-03-03 19:31:36 +03:00
/* Make sure bypass is cleared */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DIF_MISC_CTRL , & value ) ;
2009-03-03 19:31:36 +03:00
/* Clear the bypass bit */
value & = ~ FLD_DIF_DIF_BYPASS ;
/* Enable the use of the DIF block */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_MISC_CTRL , value ) ;
2009-03-03 19:31:36 +03:00
2009-03-03 12:14:34 +03:00
/* Read the DFE_CTRL1 register */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DFE_CTRL1 , & value ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* Disable the VBI_GATE_EN */
value & = ~ FLD_VBI_GATE_EN ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* Enable the auto-VGA enable, AGC, and
set the skip count to 2 */
value | = FLD_VGA_AUTO_EN | FLD_AGC_AUTO_EN | 0x00200000 ;
2009-03-03 12:14:34 +03:00
/* Write it back */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DFE_CTRL1 , value ) ;
2009-03-03 12:14:34 +03:00
2009-03-11 03:16:26 +03:00
/* Wait until AGC locks up */
2009-03-03 19:31:36 +03:00
msleep ( 1 ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* Disable the auto-VGA enable AGC */
value & = ~ ( FLD_VGA_AUTO_EN ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* Write it back */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DFE_CTRL1 , value ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* Enable Polaris B0 AGC output */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , PIN_CTRL , & value ) ;
2009-03-03 19:31:36 +03:00
value | = ( FLD_OEF_AGC_RF ) |
( FLD_OEF_AGC_IFVGA ) |
( FLD_OEF_AGC_IF ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , PIN_CTRL , value ) ;
2009-03-03 19:31:36 +03:00
2010-08-19 00:50:07 +04:00
/* Set output mode */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
OUT_CTRL1 , FLD_OUT_MODE ,
2010-08-19 00:50:07 +04:00
dev - > board . output_mode ) ;
2009-03-03 19:31:36 +03:00
/* Disable auto config of registers */
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL , FLD_ACFG_DIS ,
cx231xx_set_field ( FLD_ACFG_DIS , 1 ) ) ;
/* Set CVBS input mode */
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
MODE_CTRL , FLD_INPUT_MODE ,
2009-03-04 23:49:01 +03:00
cx231xx_set_field ( FLD_INPUT_MODE ,
INPUT_MODE_CVBS_0 ) ) ;
2009-03-03 19:31:36 +03:00
2009-03-04 23:49:01 +03:00
/* Set some bits in AFE_CTRL so that channel 2 or 3
* is ready to receive audio */
2009-03-03 19:31:36 +03:00
/* Clear clamp for channels 2 and 3 (bit 16-17) */
/* Clear droop comp (bit 19-20) */
/* Set VGA_SEL (for audio control) (bit 7-8) */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , AFE_CTRL , & value ) ;
2009-03-03 19:31:36 +03:00
2010-07-07 01:12:25 +04:00
/*Set Func mode:01-DIF 10-baseband 11-YUV*/
value & = ( ~ ( FLD_FUNC_MODE ) ) ;
value | = 0x800000 ;
2009-03-03 19:31:36 +03:00
value | = FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2 ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AFE_CTRL , value ) ;
2010-07-07 01:12:25 +04:00
if ( dev - > tuner_type = = TUNER_NXP_TDA18271 ) {
status = vid_blk_read_word ( dev , PIN_CTRL ,
& value ) ;
status = vid_blk_write_word ( dev , PIN_CTRL ,
( value & 0xFFFFFFEF ) ) ;
}
2009-03-03 19:31:36 +03:00
break ;
2009-03-03 12:14:34 +03:00
}
break ;
}
/* Set raw VBI mode */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
OUT_CTRL1 , FLD_VBIHACTRAW_EN ,
cx231xx_set_field ( FLD_VBIHACTRAW_EN , 1 ) ) ;
2009-03-03 12:14:34 +03:00
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , OUT_CTRL1 , & value ) ;
2009-03-03 12:14:34 +03:00
if ( value & 0x02 ) {
value | = ( 1 < < 19 ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , OUT_CTRL1 , value ) ;
2009-03-03 12:14:34 +03:00
}
return status ;
2009-03-03 20:37:50 +03:00
}
2010-07-07 01:12:25 +04:00
void cx231xx_enable656 ( struct cx231xx * dev )
{
u8 temp = 0 ;
2010-10-07 10:23:25 +04:00
/*enable TS1 data[0:7] as output to export 656*/
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
vid_blk_write_byte ( dev , TS1_PIN_CTL0 , 0xFF ) ;
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
/*enable TS1 clock as output to export 656*/
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
vid_blk_read_byte ( dev , TS1_PIN_CTL1 , & temp ) ;
2010-07-07 01:12:25 +04:00
temp = temp | 0x04 ;
2012-05-14 17:14:53 +04:00
vid_blk_write_byte ( dev , TS1_PIN_CTL1 , temp ) ;
2010-07-07 01:12:25 +04:00
}
EXPORT_SYMBOL_GPL ( cx231xx_enable656 ) ;
void cx231xx_disable656 ( struct cx231xx * dev )
{
u8 temp = 0 ;
2012-05-14 17:14:53 +04:00
vid_blk_write_byte ( dev , TS1_PIN_CTL0 , 0x00 ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
vid_blk_read_byte ( dev , TS1_PIN_CTL1 , & temp ) ;
2010-07-07 01:12:25 +04:00
temp = temp & 0xFB ;
2012-05-14 17:14:53 +04:00
vid_blk_write_byte ( dev , TS1_PIN_CTL1 , temp ) ;
2010-07-07 01:12:25 +04:00
}
EXPORT_SYMBOL_GPL ( cx231xx_disable656 ) ;
2009-03-03 20:37:50 +03:00
/*
2009-03-04 23:49:01 +03:00
* Handle any video - mode specific overrides that are different
* on a per video standards basis after touching the MODE_CTRL
* register which resets many values for autodetect
2009-03-03 20:37:50 +03:00
*/
int cx231xx_do_mode_ctrl_overrides ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
cx231xx_info ( " do_mode_ctrl_overrides : 0x%x \n " ,
( unsigned int ) dev - > norm ) ;
/* Change the DFE_CTRL3 bp_percent to fix flagging */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DFE_CTRL3 , 0xCD3F0280 ) ;
2009-03-03 12:14:34 +03:00
2009-03-11 03:16:26 +03:00
if ( dev - > norm & ( V4L2_STD_NTSC | V4L2_STD_PAL_M ) ) {
2009-03-03 12:14:34 +03:00
cx231xx_info ( " do_mode_ctrl_overrides NTSC \n " ) ;
2009-03-03 19:31:36 +03:00
/* Move the close caption lines out of active video,
adjust the active video start point */
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
VERT_TIM_CTRL ,
FLD_VBLANK_CNT , 0x18 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
VERT_TIM_CTRL ,
FLD_VACTIVE_CNT ,
2010-07-09 20:29:31 +04:00
0x1E7000 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
VERT_TIM_CTRL ,
FLD_V656BLANK_CNT ,
2010-07-07 01:12:25 +04:00
0x1C000000 ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
HORIZ_TIM_CTRL ,
FLD_HBLANK_CNT ,
cx231xx_set_field
( FLD_HBLANK_CNT , 0x79 ) ) ;
2010-07-07 01:12:25 +04:00
2009-03-11 03:16:26 +03:00
} else if ( dev - > norm & V4L2_STD_SECAM ) {
cx231xx_info ( " do_mode_ctrl_overrides SECAM \n " ) ;
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
VERT_TIM_CTRL ,
2010-08-19 22:18:32 +04:00
FLD_VBLANK_CNT , 0x20 ) ;
2010-08-19 20:45:56 +04:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
VID_BLK_I2C_ADDRESS ,
VERT_TIM_CTRL ,
FLD_VACTIVE_CNT ,
cx231xx_set_field
( FLD_VACTIVE_CNT ,
2010-08-19 22:18:32 +04:00
0x244 ) ) ;
2010-07-07 01:12:25 +04:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
VID_BLK_I2C_ADDRESS ,
VERT_TIM_CTRL ,
FLD_V656BLANK_CNT ,
cx231xx_set_field
( FLD_V656BLANK_CNT ,
2010-08-19 22:18:32 +04:00
0x24 ) ) ;
2009-03-03 12:14:34 +03:00
/* Adjust the active video horizontal start point */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
HORIZ_TIM_CTRL ,
FLD_HBLANK_CNT ,
cx231xx_set_field
( FLD_HBLANK_CNT , 0x85 ) ) ;
2009-03-11 03:16:26 +03:00
} else {
cx231xx_info ( " do_mode_ctrl_overrides PAL \n " ) ;
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
VERT_TIM_CTRL ,
2010-08-19 22:18:32 +04:00
FLD_VBLANK_CNT , 0x20 ) ;
2010-08-19 20:45:56 +04:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
VID_BLK_I2C_ADDRESS ,
VERT_TIM_CTRL ,
FLD_VACTIVE_CNT ,
cx231xx_set_field
( FLD_VACTIVE_CNT ,
2010-08-19 22:18:32 +04:00
0x244 ) ) ;
2010-07-07 01:12:25 +04:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
VID_BLK_I2C_ADDRESS ,
VERT_TIM_CTRL ,
FLD_V656BLANK_CNT ,
cx231xx_set_field
( FLD_V656BLANK_CNT ,
2010-08-19 22:18:32 +04:00
0x24 ) ) ;
2009-03-03 12:14:34 +03:00
/* Adjust the active video horizontal start point */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 12:14:34 +03:00
HORIZ_TIM_CTRL ,
FLD_HBLANK_CNT ,
cx231xx_set_field
( FLD_HBLANK_CNT , 0x85 ) ) ;
2010-07-07 01:12:25 +04:00
2009-03-03 12:14:34 +03:00
}
return status ;
2009-03-03 20:37:50 +03:00
}
2010-07-07 01:12:25 +04:00
int cx231xx_unmute_audio ( struct cx231xx * dev )
{
return vid_blk_write_byte ( dev , PATH1_VOL_CTL , 0x24 ) ;
}
EXPORT_SYMBOL_GPL ( cx231xx_unmute_audio ) ;
2012-10-27 21:02:49 +04:00
static int stopAudioFirmware ( struct cx231xx * dev )
2010-07-07 01:12:25 +04:00
{
return vid_blk_write_byte ( dev , DL_CTL_CONTROL , 0x03 ) ;
}
2012-10-27 21:02:49 +04:00
static int restartAudioFirmware ( struct cx231xx * dev )
2010-07-07 01:12:25 +04:00
{
return vid_blk_write_byte ( dev , DL_CTL_CONTROL , 0x13 ) ;
}
2009-03-03 20:37:50 +03:00
int cx231xx_set_audio_input ( struct cx231xx * dev , u8 input )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
enum AUDIO_INPUT ainput = AUDIO_INPUT_LINE ;
switch ( INPUT ( input ) - > amux ) {
case CX231XX_AMUX_VIDEO :
ainput = AUDIO_INPUT_TUNER_TV ;
break ;
case CX231XX_AMUX_LINE_IN :
2009-03-22 04:00:20 +03:00
status = cx231xx_i2s_blk_set_audio_input ( dev , input ) ;
2009-03-03 12:14:34 +03:00
ainput = AUDIO_INPUT_LINE ;
break ;
default :
break ;
}
status = cx231xx_set_audio_decoder_input ( dev , ainput ) ;
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-03 12:14:34 +03:00
int cx231xx_set_audio_decoder_input ( struct cx231xx * dev ,
enum AUDIO_INPUT audio_input )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
u32 dwval ;
int status ;
2009-03-22 04:00:20 +03:00
u8 gen_ctrl ;
2009-03-03 12:14:34 +03:00
u32 value = 0 ;
/* Put it in soft reset */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_byte ( dev , GENERAL_CTL , & gen_ctrl ) ;
2009-03-03 12:14:34 +03:00
gen_ctrl | = 1 ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_byte ( dev , GENERAL_CTL , gen_ctrl ) ;
2009-03-03 12:14:34 +03:00
switch ( audio_input ) {
case AUDIO_INPUT_LINE :
/* setup AUD_IO control from Merlin paralle output */
2009-03-03 19:31:36 +03:00
value = cx231xx_set_field ( FLD_AUD_CHAN1_SRC ,
AUD_CHAN_SRC_PARALLEL ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AUD_IO_CTRL , value ) ;
2009-03-03 12:14:34 +03:00
/* setup input to Merlin, SRC2 connect to AC97
bypass upsample - by - 2 , slave mode , sony mode , left justify
adr 091 c , dat 01000000 */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , AC97_CTL , & dwval ) ;
2009-03-03 12:14:34 +03:00
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AC97_CTL ,
( dwval | FLD_AC97_UP2X_BYPASS ) ) ;
2009-03-03 12:14:34 +03:00
/* select the parallel1 and SRC3 */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , BAND_OUT_SEL ,
2009-03-03 19:31:36 +03:00
cx231xx_set_field ( FLD_SRC3_IN_SEL , 0x0 ) |
cx231xx_set_field ( FLD_SRC3_CLK_SEL , 0x0 ) |
2009-03-22 04:00:20 +03:00
cx231xx_set_field ( FLD_PARALLEL1_SRC_SEL , 0x0 ) ) ;
2009-03-03 12:14:34 +03:00
/* unmute all, AC97 in, independence mode
adr 08 d0 , data 0x00063073 */
2010-07-07 01:12:25 +04:00
status = vid_blk_write_word ( dev , DL_CTL , 0x3000001 ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , PATH1_CTL1 , 0x00063073 ) ;
2009-03-03 12:14:34 +03:00
/* set AVC maximum threshold, adr 08d4, dat ffff0024 */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , PATH1_VOL_CTL , & dwval ) ;
status = vid_blk_write_word ( dev , PATH1_VOL_CTL ,
( dwval | FLD_PATH1_AVC_THRESHOLD ) ) ;
2009-03-03 12:14:34 +03:00
/* set SC maximum threshold, adr 08ec, dat ffffb3a3 */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , PATH1_SC_CTL , & dwval ) ;
status = vid_blk_write_word ( dev , PATH1_SC_CTL ,
( dwval | FLD_PATH1_SC_THRESHOLD ) ) ;
2009-03-03 12:14:34 +03:00
break ;
case AUDIO_INPUT_TUNER_TV :
default :
2010-07-07 01:12:25 +04:00
status = stopAudioFirmware ( dev ) ;
2009-03-03 12:14:34 +03:00
/* Setup SRC sources and clocks */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , BAND_OUT_SEL ,
2009-03-03 19:31:36 +03:00
cx231xx_set_field ( FLD_SRC6_IN_SEL , 0x00 ) |
cx231xx_set_field ( FLD_SRC6_CLK_SEL , 0x01 ) |
cx231xx_set_field ( FLD_SRC5_IN_SEL , 0x00 ) |
cx231xx_set_field ( FLD_SRC5_CLK_SEL , 0x02 ) |
cx231xx_set_field ( FLD_SRC4_IN_SEL , 0x02 ) |
cx231xx_set_field ( FLD_SRC4_CLK_SEL , 0x03 ) |
cx231xx_set_field ( FLD_SRC3_IN_SEL , 0x00 ) |
cx231xx_set_field ( FLD_SRC3_CLK_SEL , 0x00 ) |
cx231xx_set_field ( FLD_BASEBAND_BYPASS_CTL , 0x00 ) |
cx231xx_set_field ( FLD_AC97_SRC_SEL , 0x03 ) |
cx231xx_set_field ( FLD_I2S_SRC_SEL , 0x00 ) |
cx231xx_set_field ( FLD_PARALLEL2_SRC_SEL , 0x02 ) |
2009-03-22 04:00:20 +03:00
cx231xx_set_field ( FLD_PARALLEL1_SRC_SEL , 0x01 ) ) ;
2009-03-03 12:14:34 +03:00
/* Setup the AUD_IO control */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , AUD_IO_CTRL ,
2009-03-03 19:31:36 +03:00
cx231xx_set_field ( FLD_I2S_PORT_DIR , 0x00 ) |
cx231xx_set_field ( FLD_I2S_OUT_SRC , 0x00 ) |
cx231xx_set_field ( FLD_AUD_CHAN3_SRC , 0x00 ) |
cx231xx_set_field ( FLD_AUD_CHAN2_SRC , 0x00 ) |
2009-03-22 04:00:20 +03:00
cx231xx_set_field ( FLD_AUD_CHAN1_SRC , 0x03 ) ) ;
2009-03-03 12:14:34 +03:00
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , PATH1_CTL1 , 0x1F063870 ) ;
2009-03-03 12:14:34 +03:00
/* setAudioStandard(_audio_standard); */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , PATH1_CTL1 , 0x00063870 ) ;
2010-07-07 01:12:25 +04:00
status = restartAudioFirmware ( dev ) ;
2010-08-19 17:55:05 +04:00
switch ( dev - > board . tuner_type ) {
case TUNER_XC5000 :
/* SIF passthrough at 28.6363 MHz sample rate */
2009-03-03 19:31:36 +03:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS ,
2009-03-03 19:31:36 +03:00
CHIP_CTRL ,
FLD_SIF_EN ,
cx231xx_set_field ( FLD_SIF_EN , 1 ) ) ;
2009-03-03 12:14:34 +03:00
break ;
2010-08-19 17:55:05 +04:00
case TUNER_NXP_TDA18271 :
/* Normal mode: SIF passthrough at 14.32 MHz */
2010-07-07 01:12:25 +04:00
status = cx231xx_read_modify_write_i2c_dword ( dev ,
VID_BLK_I2C_ADDRESS ,
CHIP_CTRL ,
FLD_SIF_EN ,
cx231xx_set_field ( FLD_SIF_EN , 0 ) ) ;
break ;
2009-03-03 12:14:34 +03:00
default :
2010-08-19 17:55:05 +04:00
/* This is just a casual suggestion to people adding
new boards in case they use a tuner type we don ' t
currently know about */
printk ( KERN_INFO " Unknown tuner type configuring SIF " ) ;
2009-03-03 12:14:34 +03:00
break ;
}
break ;
case AUDIO_INPUT_TUNER_FM :
/* use SIF for FM radio
setupFM ( ) ;
setAudioStandard ( _audio_standard ) ;
*/
break ;
case AUDIO_INPUT_MUTE :
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , PATH1_CTL1 , 0x1F011012 ) ;
2009-03-03 12:14:34 +03:00
break ;
}
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* Take it out of soft reset */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_byte ( dev , GENERAL_CTL , & gen_ctrl ) ;
2009-03-03 12:14:34 +03:00
gen_ctrl & = ~ 1 ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_byte ( dev , GENERAL_CTL , gen_ctrl ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
}
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
/******************************************************************************
* C H I P Specific C O N T R O L functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-03 20:37:50 +03:00
int cx231xx_init_ctrl_pin_status ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
u32 value ;
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , PIN_CTRL , & value ) ;
2009-03-03 12:14:34 +03:00
value | = ( ~ dev - > board . ctl_pin_status_mask ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , PIN_CTRL , value ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-03 12:14:34 +03:00
int cx231xx_set_agc_analog_digital_mux_select ( struct cx231xx * dev ,
u8 analog_or_digital )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* first set the direction to output */
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_direction ( dev ,
dev - > board .
agc_analog_digital_select_gpio , 1 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* 0 - demod ; 1 - Analog mode */
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_value ( dev ,
2009-03-03 12:14:34 +03:00
dev - > board . agc_analog_digital_select_gpio ,
analog_or_digital ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2010-09-27 03:38:24 +04:00
int cx231xx_enable_i2c_port_3 ( struct cx231xx * dev , bool is_port_3 )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
u8 value [ 4 ] = { 0 , 0 , 0 , 0 } ;
int status = 0 ;
2010-09-27 03:38:24 +04:00
bool current_is_port_3 ;
2009-03-03 20:37:50 +03:00
2011-01-31 22:25:39 +03:00
if ( dev - > board . dont_use_port_3 )
is_port_3 = false ;
2009-03-03 19:31:36 +03:00
status = cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 )
return status ;
2009-03-03 20:37:50 +03:00
2010-09-27 03:38:24 +04:00
current_is_port_3 = value [ 0 ] & I2C_DEMOD_EN ? true : false ;
/* Just return, if already using the right port */
if ( current_is_port_3 = = is_port_3 )
return 0 ;
if ( is_port_3 )
value [ 0 ] | = I2C_DEMOD_EN ;
else
value [ 0 ] & = ~ I2C_DEMOD_EN ;
cx231xx_info ( " Changing the i2c master port to %d \n " ,
is_port_3 ? 3 : 1 ) ;
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
2010-07-07 01:12:25 +04:00
}
2010-09-27 03:38:24 +04:00
EXPORT_SYMBOL_GPL ( cx231xx_enable_i2c_port_3 ) ;
2010-07-07 01:12:25 +04:00
void update_HH_register_after_set_DIF ( struct cx231xx * dev )
{
/*
u8 status = 0 ;
u32 value = 0 ;
vid_blk_write_word ( dev , PIN_CTRL , 0xA0FFF82F ) ;
vid_blk_write_word ( dev , DIF_MISC_CTRL , 0x0A203F11 ) ;
vid_blk_write_word ( dev , DIF_SRC_PHASE_INC , 0x1BEFBF06 ) ;
status = vid_blk_read_word ( dev , AFE_CTRL_C2HH_SRC_CTRL , & value ) ;
vid_blk_write_word ( dev , AFE_CTRL_C2HH_SRC_CTRL , 0x4485D390 ) ;
status = vid_blk_read_word ( dev , AFE_CTRL_C2HH_SRC_CTRL , & value ) ;
*/
}
void cx231xx_dump_HH_reg ( struct cx231xx * dev )
{
u32 value = 0 ;
u16 i = 0 ;
value = 0x45005390 ;
2012-05-14 17:14:53 +04:00
vid_blk_write_word ( dev , 0x104 , value ) ;
2010-07-07 01:12:25 +04:00
for ( i = 0x100 ; i < 0x140 ; i + + ) {
2012-05-14 17:14:53 +04:00
vid_blk_read_word ( dev , i , & value ) ;
2010-07-07 01:12:25 +04:00
cx231xx_info ( " reg0x%x=0x%x \n " , i , value ) ;
i = i + 3 ;
}
for ( i = 0x300 ; i < 0x400 ; i + + ) {
2012-05-14 17:14:53 +04:00
vid_blk_read_word ( dev , i , & value ) ;
2010-07-07 01:12:25 +04:00
cx231xx_info ( " reg0x%x=0x%x \n " , i , value ) ;
i = i + 3 ;
}
for ( i = 0x400 ; i < 0x440 ; i + + ) {
2012-05-14 17:14:53 +04:00
vid_blk_read_word ( dev , i , & value ) ;
2010-07-07 01:12:25 +04:00
cx231xx_info ( " reg0x%x=0x%x \n " , i , value ) ;
i = i + 3 ;
}
2012-05-14 17:14:53 +04:00
vid_blk_read_word ( dev , AFE_CTRL_C2HH_SRC_CTRL , & value ) ;
2010-10-07 10:23:25 +04:00
cx231xx_info ( " AFE_CTRL_C2HH_SRC_CTRL=0x%x \n " , value ) ;
vid_blk_write_word ( dev , AFE_CTRL_C2HH_SRC_CTRL , 0x4485D390 ) ;
2012-05-14 17:14:53 +04:00
vid_blk_read_word ( dev , AFE_CTRL_C2HH_SRC_CTRL , & value ) ;
2010-10-07 10:23:25 +04:00
cx231xx_info ( " AFE_CTRL_C2HH_SRC_CTRL=0x%x \n " , value ) ;
2010-07-07 01:12:25 +04:00
}
2010-10-07 10:23:25 +04:00
2010-07-07 01:12:25 +04:00
void cx231xx_dump_SC_reg ( struct cx231xx * dev )
{
u8 value [ 4 ] = { 0 , 0 , 0 , 0 } ;
2011-04-01 14:41:20 +04:00
cx231xx_info ( " cx231xx_dump_SC_reg! \n " ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , BOARD_CFG_STAT ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , BOARD_CFG_STAT , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , TS_MODE_REG ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , TS_MODE_REG , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , TS1_CFG_REG ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , TS1_CFG_REG , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , TS1_LENGTH_REG ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , TS1_LENGTH_REG , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , TS2_CFG_REG ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , TS2_CFG_REG , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , TS2_LENGTH_REG ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , TS2_LENGTH_REG , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , EP_MODE_SET ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , EP_MODE_SET , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_PWR_PTN1 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_PWR_PTN1 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_PWR_PTN2 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_PWR_PTN2 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_PWR_PTN3 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_PWR_PTN3 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_PWR_MASK0 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_PWR_MASK0 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_PWR_MASK1 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_PWR_MASK1 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_PWR_MASK2 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_PWR_MASK2 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_GAIN ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_GAIN , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_CAR_REG ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_CAR_REG , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_OT_CFG1 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_OT_CFG1 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , CIR_OT_CFG2 ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , CIR_OT_CFG2 , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
2012-05-14 17:14:53 +04:00
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , PWR_CTL_EN ,
2010-07-07 01:12:25 +04:00
value , 4 ) ;
cx231xx_info ( " reg0x%x=0x%x 0x%x 0x%x 0x%x \n " , PWR_CTL_EN , value [ 0 ] ,
value [ 1 ] , value [ 2 ] , value [ 3 ] ) ;
}
void cx231xx_Setup_AFE_for_LowIF ( struct cx231xx * dev )
{
u8 value = 0 ;
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_STATUS2_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xFE ) | 0x01 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_STATUS2_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_STATUS2_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xFE ) | 0x00 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_STATUS2_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
/*
2010-10-07 10:23:25 +04:00
config colibri to lo - if mode
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
FIXME : ntf_mode = 2 ' b00 by default . But set 0x1 would reduce
the diff IF input by half ,
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
for low - if agc defect
2010-07-07 01:12:25 +04:00
*/
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_NTF_PRECLMP_EN_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xFC ) | 0x00 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_NTF_PRECLMP_EN_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_INPUT_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xF9 ) | 0x02 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_INPUT_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_FB_FRCRST_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xFB ) | 0x04 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_FB_FRCRST_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_DCSERVO_DEM_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xFC ) | 0x03 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_DCSERVO_DEM_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_CTRL_DAC1_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xFB ) | 0x04 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_CTRL_DAC1_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_CTRL_DAC23_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xF8 ) | 0x06 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_CTRL_DAC23_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_CTRL_DAC23_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0x8F ) | 0x40 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_CTRL_DAC23_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
2012-05-14 17:14:53 +04:00
afe_read_byte ( dev , ADC_PWRDN_CLAMP_CH3 , & value ) ;
2010-07-07 01:12:25 +04:00
value = ( value & 0xDF ) | 0x20 ;
2012-05-14 17:14:53 +04:00
afe_write_byte ( dev , ADC_PWRDN_CLAMP_CH3 , value ) ;
2010-07-07 01:12:25 +04:00
}
void cx231xx_set_Colibri_For_LowIF ( struct cx231xx * dev , u32 if_freq ,
u8 spectral_invert , u32 mode )
{
2010-08-19 18:09:28 +04:00
u32 colibri_carrier_offset = 0 ;
u32 func_mode = 0x01 ; /* Device has a DIF if this function is called */
u32 standard = 0 ;
2010-07-07 01:12:25 +04:00
u8 value [ 4 ] = { 0 , 0 , 0 , 0 } ;
cx231xx_info ( " Enter cx231xx_set_Colibri_For_LowIF() \n " ) ;
2010-08-19 18:09:28 +04:00
value [ 0 ] = ( u8 ) 0x6F ;
value [ 1 ] = ( u8 ) 0x6F ;
value [ 2 ] = ( u8 ) 0x6F ;
value [ 3 ] = ( u8 ) 0x6F ;
2012-05-14 17:14:53 +04:00
cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
2010-08-19 18:09:28 +04:00
PWR_CTL_EN , value , 4 ) ;
2010-07-07 01:12:25 +04:00
/*Set colibri for low IF*/
2012-05-14 17:14:53 +04:00
cx231xx_afe_set_mode ( dev , AFE_MODE_LOW_IF ) ;
2010-07-07 01:12:25 +04:00
/* Set C2HH for low IF operation.*/
standard = dev - > norm ;
2012-05-14 17:14:53 +04:00
cx231xx_dif_configure_C2HH_for_low_IF ( dev , dev - > active_mode ,
2010-08-19 18:09:28 +04:00
func_mode , standard ) ;
2010-07-07 01:12:25 +04:00
/* Get colibri offsets.*/
colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset ( mode ,
2010-08-19 18:09:28 +04:00
standard ) ;
2010-07-07 01:12:25 +04:00
cx231xx_info ( " colibri_carrier_offset=%d, standard=0x%x \n " ,
2010-08-19 18:09:28 +04:00
colibri_carrier_offset , standard ) ;
2010-07-07 01:12:25 +04:00
/* Set the band Pass filter for DIF*/
2010-08-19 18:09:28 +04:00
cx231xx_set_DIF_bandpass ( dev , ( if_freq + colibri_carrier_offset ) ,
spectral_invert , mode ) ;
2010-07-07 01:12:25 +04:00
}
u32 cx231xx_Get_Colibri_CarrierOffset ( u32 mode , u32 standerd )
{
2010-10-07 10:23:25 +04:00
u32 colibri_carrier_offset = 0 ;
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
if ( mode = = TUNER_MODE_FM_RADIO ) {
2010-07-07 01:12:25 +04:00
colibri_carrier_offset = 1100000 ;
2010-10-09 19:04:25 +04:00
} else if ( standerd & ( V4L2_STD_MN | V4L2_STD_NTSC_M_JP ) ) {
2010-07-07 01:12:25 +04:00
colibri_carrier_offset = 4832000 ; /*4.83MHz */
} else if ( standerd & ( V4L2_STD_PAL_B | V4L2_STD_PAL_G ) ) {
colibri_carrier_offset = 2700000 ; /*2.70MHz */
} else if ( standerd & ( V4L2_STD_PAL_D | V4L2_STD_PAL_I
| V4L2_STD_SECAM ) ) {
colibri_carrier_offset = 2100000 ; /*2.10MHz */
}
2010-10-07 10:23:25 +04:00
return colibri_carrier_offset ;
2010-07-07 01:12:25 +04:00
}
void cx231xx_set_DIF_bandpass ( struct cx231xx * dev , u32 if_freq ,
u8 spectral_invert , u32 mode )
{
2010-10-07 10:23:25 +04:00
unsigned long pll_freq_word ;
u32 dif_misc_ctrl_value = 0 ;
u64 pll_freq_u64 = 0 ;
u32 i = 0 ;
2010-07-07 01:12:25 +04:00
cx231xx_info ( " if_freq=%d;spectral_invert=0x%x;mode=0x%x \n " ,
if_freq , spectral_invert , mode ) ;
2010-10-07 10:23:25 +04:00
if ( mode = = TUNER_MODE_FM_RADIO ) {
pll_freq_word = 0x905A1CAC ;
2012-05-14 17:14:53 +04:00
vid_blk_write_word ( dev , DIF_PLL_FREQ_WORD , pll_freq_word ) ;
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
} else /*KSPROPERTY_TUNER_MODE_TV*/ {
/* Calculate the PLL frequency word based on the adjusted if_freq*/
pll_freq_word = if_freq ;
pll_freq_u64 = ( u64 ) pll_freq_word < < 28L ;
do_div ( pll_freq_u64 , 50000000 ) ;
pll_freq_word = ( u32 ) pll_freq_u64 ;
/*pll_freq_word = 0x3463497;*/
2012-05-14 17:14:53 +04:00
vid_blk_write_word ( dev , DIF_PLL_FREQ_WORD , pll_freq_word ) ;
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
if ( spectral_invert ) {
if_freq - = 400000 ;
/* Enable Spectral Invert*/
2012-05-14 17:14:53 +04:00
vid_blk_read_word ( dev , DIF_MISC_CTRL ,
2010-10-07 10:23:25 +04:00
& dif_misc_ctrl_value ) ;
dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000 ;
2012-05-14 17:14:53 +04:00
vid_blk_write_word ( dev , DIF_MISC_CTRL ,
2010-10-07 10:23:25 +04:00
dif_misc_ctrl_value ) ;
} else {
if_freq + = 400000 ;
/* Disable Spectral Invert*/
2012-05-14 17:14:53 +04:00
vid_blk_read_word ( dev , DIF_MISC_CTRL ,
2010-10-07 10:23:25 +04:00
& dif_misc_ctrl_value ) ;
dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF ;
2012-05-14 17:14:53 +04:00
vid_blk_write_word ( dev , DIF_MISC_CTRL ,
2010-10-07 10:23:25 +04:00
dif_misc_ctrl_value ) ;
}
if_freq = ( if_freq / 100000 ) * 100000 ;
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
if ( if_freq < 3000000 )
if_freq = 3000000 ;
2010-07-07 01:12:25 +04:00
2010-10-07 10:23:25 +04:00
if ( if_freq > 16000000 )
if_freq = 16000000 ;
2010-07-07 01:12:25 +04:00
}
2010-10-07 10:23:25 +04:00
cx231xx_info ( " Enter IF=%zd \n " ,
2012-04-11 03:55:40 +04:00
ARRAY_SIZE ( Dif_set_array ) ) ;
for ( i = 0 ; i < ARRAY_SIZE ( Dif_set_array ) ; i + + ) {
2010-10-07 10:23:25 +04:00
if ( Dif_set_array [ i ] . if_freq = = if_freq ) {
2012-05-14 17:14:53 +04:00
vid_blk_write_word ( dev ,
2010-10-07 10:23:25 +04:00
Dif_set_array [ i ] . register_address , Dif_set_array [ i ] . value ) ;
}
}
2009-03-03 20:37:50 +03:00
}
2009-03-03 19:31:36 +03:00
/******************************************************************************
* D I F - B L O C K C O N T R O L functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-03 20:37:50 +03:00
int cx231xx_dif_configure_C2HH_for_low_IF ( struct cx231xx * dev , u32 mode ,
2009-03-03 12:14:34 +03:00
u32 function_mode , u32 standard )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2010-07-07 01:12:25 +04:00
2009-03-03 12:14:34 +03:00
if ( mode = = V4L2_TUNER_RADIO ) {
/* C2HH */
2009-03-04 23:49:01 +03:00
/* lo if big signal */
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 30 , 31 , 0x1 ) ;
/* FUNC_MODE = DIF */
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 23 , 24 , function_mode ) ;
/* IF_MODE */
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 15 , 22 , 0xFF ) ;
/* no inv */
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 9 , 9 , 0x1 ) ;
2009-03-11 03:16:26 +03:00
} else if ( standard ! = DIF_USE_BASEBAND ) {
if ( standard & V4L2_STD_MN ) {
2009-03-04 23:49:01 +03:00
/* lo if big signal */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 30 , 31 , 0x1 ) ;
/* FUNC_MODE = DIF */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 19:31:36 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 23 , 24 ,
2009-03-04 23:49:01 +03:00
function_mode ) ;
/* IF_MODE */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 15 , 22 , 0xb ) ;
/* no inv */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 9 , 9 , 0x1 ) ;
/* 0x124, AUD_CHAN1_SRC = 0x3 */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AUD_IO_CTRL , 0 , 31 , 0x00000003 ) ;
2009-03-11 03:16:26 +03:00
} else if ( ( standard = = V4L2_STD_PAL_I ) |
2010-07-07 01:12:25 +04:00
( standard & V4L2_STD_PAL_D ) |
2009-03-11 03:16:26 +03:00
( standard & V4L2_STD_SECAM ) ) {
2009-03-03 12:14:34 +03:00
/* C2HH setup */
2009-03-04 23:49:01 +03:00
/* lo if big signal */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 30 , 31 , 0x1 ) ;
/* FUNC_MODE = DIF */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 19:31:36 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 23 , 24 ,
2009-03-04 23:49:01 +03:00
function_mode ) ;
/* IF_MODE */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 15 , 22 , 0xF ) ;
2009-03-04 23:49:01 +03:00
/* no inv */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 9 , 9 , 0x1 ) ;
2009-03-11 03:16:26 +03:00
} else {
/* default PAL BG */
2009-03-03 12:14:34 +03:00
/* C2HH setup */
2009-03-04 23:49:01 +03:00
/* lo if big signal */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 30 , 31 , 0x1 ) ;
/* FUNC_MODE = DIF */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 19:31:36 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 23 , 24 ,
2009-03-04 23:49:01 +03:00
function_mode ) ;
/* IF_MODE */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 15 , 22 , 0xE ) ;
2009-03-04 23:49:01 +03:00
/* no inv */
2009-03-03 19:31:36 +03:00
status = cx231xx_reg_mask_write ( dev ,
2009-03-22 04:00:20 +03:00
VID_BLK_I2C_ADDRESS , 32 ,
2009-03-04 23:49:01 +03:00
AFE_CTRL_C2HH_SRC_CTRL , 9 , 9 , 0x1 ) ;
2009-03-03 12:14:34 +03:00
}
}
return status ;
2009-03-03 20:37:50 +03:00
}
int cx231xx_dif_set_standard ( struct cx231xx * dev , u32 standard )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
u32 dif_misc_ctrl_value = 0 ;
u32 func_mode = 0 ;
cx231xx_info ( " %s: setStandard to %x \n " , __func__ , standard ) ;
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DIF_MISC_CTRL , & dif_misc_ctrl_value ) ;
2009-03-03 12:14:34 +03:00
if ( standard ! = DIF_USE_BASEBAND )
dev - > norm = standard ;
switch ( dev - > model ) {
2010-07-07 01:12:25 +04:00
case CX231XX_BOARD_CNXT_CARRAERA :
2009-03-03 12:14:34 +03:00
case CX231XX_BOARD_CNXT_RDE_250 :
2010-07-07 01:12:25 +04:00
case CX231XX_BOARD_CNXT_SHELBY :
2009-03-03 12:14:34 +03:00
case CX231XX_BOARD_CNXT_RDU_250 :
2010-07-07 01:12:25 +04:00
case CX231XX_BOARD_CNXT_VIDEO_GRABBER :
2010-07-07 01:23:53 +04:00
case CX231XX_BOARD_HAUPPAUGE_EXETER :
2013-03-02 02:53:30 +04:00
case CX231XX_BOARD_OTG102 :
2009-03-03 12:14:34 +03:00
func_mode = 0x03 ;
break ;
2010-07-07 01:12:25 +04:00
case CX231XX_BOARD_CNXT_RDE_253S :
case CX231XX_BOARD_CNXT_RDU_253S :
2011-06-08 22:54:19 +04:00
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL :
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC :
2010-07-07 01:12:25 +04:00
func_mode = 0x01 ;
break ;
2009-03-03 12:14:34 +03:00
default :
func_mode = 0x01 ;
}
2009-03-03 19:31:36 +03:00
status = cx231xx_dif_configure_C2HH_for_low_IF ( dev , dev - > active_mode ,
2009-03-03 12:14:34 +03:00
func_mode , standard ) ;
if ( standard = = DIF_USE_BASEBAND ) { /* base band */
2009-03-03 19:31:36 +03:00
/* There is a different SRC_PHASE_INC value
for baseband vs . DIF */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_SRC_PHASE_INC , 0xDF7DF83 ) ;
status = vid_blk_read_word ( dev , DIF_MISC_CTRL ,
& dif_misc_ctrl_value ) ;
2009-03-03 12:14:34 +03:00
dif_misc_ctrl_value | = FLD_DIF_DIF_BYPASS ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_MISC_CTRL ,
dif_misc_ctrl_value ) ;
2009-03-03 12:14:34 +03:00
} else if ( standard & V4L2_STD_PAL_D ) {
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL , 0 , 31 , 0x6503bc0c ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL1 , 0 , 31 , 0xbd038c85 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL2 , 0 , 31 , 0x1db4640a ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL3 , 0 , 31 , 0x00008800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_REF , 0 , 31 , 0x444C1380 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_IF , 0 , 31 , 0xDA302600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_INT , 0 , 31 , 0xDA261700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_RF , 0 , 31 , 0xDA262600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_INT_CURRENT , 0 , 31 ,
0x26001700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_RF_CURRENT , 0 , 31 ,
0x00002660 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VIDEO_AGC_CTRL , 0 , 31 ,
0x72500800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VID_AUD_OVERRIDE , 0 , 31 ,
0x27000100 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AV_SEP_CTRL , 0 , 31 , 0x3F3934EA ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_COMP_FLT_CTRL , 0 , 31 ,
0x00000000 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_PHASE_INC , 0 , 31 ,
0x1befbf06 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_GAIN_CONTROL , 0 , 31 ,
0x000035e8 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_RPT_VARIANCE , 0 , 31 , 0x00000000 ) ;
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value | = 0x3a023F11 ;
} else if ( standard & V4L2_STD_PAL_I ) {
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL , 0 , 31 , 0x6503bc0c ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL1 , 0 , 31 , 0xbd038c85 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL2 , 0 , 31 , 0x1db4640a ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL3 , 0 , 31 , 0x00008800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_REF , 0 , 31 , 0x444C1380 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_IF , 0 , 31 , 0xDA302600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_INT , 0 , 31 , 0xDA261700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_RF , 0 , 31 , 0xDA262600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_INT_CURRENT , 0 , 31 ,
0x26001700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_RF_CURRENT , 0 , 31 ,
0x00002660 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VIDEO_AGC_CTRL , 0 , 31 ,
0x72500800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VID_AUD_OVERRIDE , 0 , 31 ,
0x27000100 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AV_SEP_CTRL , 0 , 31 , 0x5F39A934 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_COMP_FLT_CTRL , 0 , 31 ,
0x00000000 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_PHASE_INC , 0 , 31 ,
0x1befbf06 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_GAIN_CONTROL , 0 , 31 ,
0x000035e8 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_RPT_VARIANCE , 0 , 31 , 0x00000000 ) ;
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value | = 0x3a033F11 ;
} else if ( standard & V4L2_STD_PAL_M ) {
/* improved Low Frequency Phase Noise */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_PLL_CTRL , 0xFF01FF0C ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL1 , 0xbd038c85 ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL2 , 0x1db4640a ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL3 , 0x00008800 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_IF_REF , 0x444C1380 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_IF_INT_CURRENT ,
0x26001700 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_RF_CURRENT ,
0x00002660 ) ;
status = vid_blk_write_word ( dev , DIF_VIDEO_AGC_CTRL ,
0x72500800 ) ;
status = vid_blk_write_word ( dev , DIF_VID_AUD_OVERRIDE ,
0x27000100 ) ;
status = vid_blk_write_word ( dev , DIF_AV_SEP_CTRL , 0x012c405d ) ;
status = vid_blk_write_word ( dev , DIF_COMP_FLT_CTRL ,
0x009f50c1 ) ;
status = vid_blk_write_word ( dev , DIF_SRC_PHASE_INC ,
0x1befbf06 ) ;
status = vid_blk_write_word ( dev , DIF_SRC_GAIN_CONTROL ,
0x000035e8 ) ;
status = vid_blk_write_word ( dev , DIF_SOFT_RST_CTRL_REVB ,
0x00000000 ) ;
2009-03-03 12:14:34 +03:00
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value | = 0x3A0A3F10 ;
} else if ( standard & ( V4L2_STD_PAL_N | V4L2_STD_PAL_Nc ) ) {
/* improved Low Frequency Phase Noise */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_PLL_CTRL , 0xFF01FF0C ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL1 , 0xbd038c85 ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL2 , 0x1db4640a ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL3 , 0x00008800 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_IF_REF , 0x444C1380 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_IF_INT_CURRENT ,
0x26001700 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_RF_CURRENT ,
0x00002660 ) ;
status = vid_blk_write_word ( dev , DIF_VIDEO_AGC_CTRL ,
0x72500800 ) ;
status = vid_blk_write_word ( dev , DIF_VID_AUD_OVERRIDE ,
0x27000100 ) ;
status = vid_blk_write_word ( dev , DIF_AV_SEP_CTRL ,
0x012c405d ) ;
status = vid_blk_write_word ( dev , DIF_COMP_FLT_CTRL ,
0x009f50c1 ) ;
status = vid_blk_write_word ( dev , DIF_SRC_PHASE_INC ,
0x1befbf06 ) ;
status = vid_blk_write_word ( dev , DIF_SRC_GAIN_CONTROL ,
0x000035e8 ) ;
status = vid_blk_write_word ( dev , DIF_SOFT_RST_CTRL_REVB ,
0x00000000 ) ;
2009-03-03 12:14:34 +03:00
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value = 0x3A093F10 ;
} else if ( standard &
2009-03-11 03:16:26 +03:00
( V4L2_STD_SECAM_B | V4L2_STD_SECAM_D | V4L2_STD_SECAM_G |
V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1 ) ) {
2009-03-03 12:14:34 +03:00
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL , 0 , 31 , 0x6503bc0c ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL1 , 0 , 31 , 0xbd038c85 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL2 , 0 , 31 , 0x1db4640a ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL3 , 0 , 31 , 0x00008800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_REF , 0 , 31 , 0x888C0380 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_IF , 0 , 31 , 0xe0262600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_INT , 0 , 31 , 0xc2171700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_RF , 0 , 31 , 0xc2262600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_INT_CURRENT , 0 , 31 ,
0x26001700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_RF_CURRENT , 0 , 31 ,
0x00002660 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VID_AUD_OVERRIDE , 0 , 31 ,
0x27000100 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AV_SEP_CTRL , 0 , 31 , 0x3F3530ec ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_COMP_FLT_CTRL , 0 , 31 ,
0x00000000 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_PHASE_INC , 0 , 31 ,
0x1befbf06 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_GAIN_CONTROL , 0 , 31 ,
0x000035e8 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_RPT_VARIANCE , 0 , 31 , 0x00000000 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VIDEO_AGC_CTRL , 0 , 31 ,
0xf4000000 ) ;
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value | = 0x3a023F11 ;
} else if ( standard & ( V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC ) ) {
/* Is it SECAM_L1? */
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL , 0 , 31 , 0x6503bc0c ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL1 , 0 , 31 , 0xbd038c85 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL2 , 0 , 31 , 0x1db4640a ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_PLL_CTRL3 , 0 , 31 , 0x00008800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_REF , 0 , 31 , 0x888C0380 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_IF , 0 , 31 , 0xe0262600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_INT , 0 , 31 , 0xc2171700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_CTRL_RF , 0 , 31 , 0xc2262600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_IF_INT_CURRENT , 0 , 31 ,
0x26001700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AGC_RF_CURRENT , 0 , 31 ,
0x00002660 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VID_AUD_OVERRIDE , 0 , 31 ,
0x27000100 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_AV_SEP_CTRL , 0 , 31 , 0x3F3530ec ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_COMP_FLT_CTRL , 0 , 31 ,
0x00000000 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_PHASE_INC , 0 , 31 ,
0x1befbf06 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_SRC_GAIN_CONTROL , 0 , 31 ,
0x000035e8 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_RPT_VARIANCE , 0 , 31 , 0x00000000 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-03 12:14:34 +03:00
DIF_VIDEO_AGC_CTRL , 0 , 31 ,
0xf2560000 ) ;
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value | = 0x3a023F11 ;
2009-03-11 03:16:26 +03:00
} else if ( standard & V4L2_STD_NTSC_M ) {
2009-03-03 19:31:36 +03:00
/* V4L2_STD_NTSC_M (75 IRE Setup) Or
V4L2_STD_NTSC_M_JP ( Japan , 0 IRE Setup ) */
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
/* For NTSC the centre frequency of video coming out of
sidewinder is around 7.1 MHz or 3.6 MHz depending on the
spectral inversion . so for a non spectrally inverted channel
the pll freq word is 0x03420c49
2009-03-03 12:14:34 +03:00
*/
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_PLL_CTRL , 0x6503BC0C ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL1 , 0xBD038C85 ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL2 , 0x1DB4640A ) ;
status = vid_blk_write_word ( dev , DIF_PLL_CTRL3 , 0x00008800 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_IF_REF , 0x444C0380 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_IF_INT_CURRENT ,
0x26001700 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_RF_CURRENT ,
0x00002660 ) ;
status = vid_blk_write_word ( dev , DIF_VIDEO_AGC_CTRL ,
0x04000800 ) ;
status = vid_blk_write_word ( dev , DIF_VID_AUD_OVERRIDE ,
0x27000100 ) ;
status = vid_blk_write_word ( dev , DIF_AV_SEP_CTRL , 0x01296e1f ) ;
status = vid_blk_write_word ( dev , DIF_COMP_FLT_CTRL ,
0x009f50c1 ) ;
status = vid_blk_write_word ( dev , DIF_SRC_PHASE_INC ,
0x1befbf06 ) ;
status = vid_blk_write_word ( dev , DIF_SRC_GAIN_CONTROL ,
0x000035e8 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_CTRL_IF , 0xC2262600 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_CTRL_INT ,
0xC2262600 ) ;
status = vid_blk_write_word ( dev , DIF_AGC_CTRL_RF , 0xC2262600 ) ;
2009-03-03 12:14:34 +03:00
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value | = 0x3a003F10 ;
2009-03-11 03:16:26 +03:00
} else {
/* default PAL BG */
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_PLL_CTRL , 0 , 31 , 0x6503bc0c ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_PLL_CTRL1 , 0 , 31 , 0xbd038c85 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_PLL_CTRL2 , 0 , 31 , 0x1db4640a ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_PLL_CTRL3 , 0 , 31 , 0x00008800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_AGC_IF_REF , 0 , 31 , 0x444C1380 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_AGC_CTRL_IF , 0 , 31 , 0xDA302600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_AGC_CTRL_INT , 0 , 31 , 0xDA261700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_AGC_CTRL_RF , 0 , 31 , 0xDA262600 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_AGC_IF_INT_CURRENT , 0 , 31 ,
0x26001700 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_AGC_RF_CURRENT , 0 , 31 ,
0x00002660 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_VIDEO_AGC_CTRL , 0 , 31 ,
0x72500800 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_VID_AUD_OVERRIDE , 0 , 31 ,
0x27000100 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_AV_SEP_CTRL , 0 , 31 , 0x3F3530EC ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_COMP_FLT_CTRL , 0 , 31 ,
0x00A653A8 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_SRC_PHASE_INC , 0 , 31 ,
0x1befbf06 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_SRC_GAIN_CONTROL , 0 , 31 ,
0x000035e8 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_reg_mask_write ( dev , VID_BLK_I2C_ADDRESS , 32 ,
2009-03-11 03:16:26 +03:00
DIF_RPT_VARIANCE , 0 , 31 , 0x00000000 ) ;
/* Save the Spec Inversion value */
dif_misc_ctrl_value & = FLD_DIF_SPEC_INV ;
dif_misc_ctrl_value | = 0x3a013F11 ;
2009-03-03 12:14:34 +03:00
}
/* The AGC values should be the same for all standards,
AUD_SRC_SEL [ 19 ] should always be disabled */
dif_misc_ctrl_value & = ~ FLD_DIF_AUD_SRC_SEL ;
2009-03-03 19:31:36 +03:00
/* It is still possible to get Set Standard calls even when we
are in FM mode .
2009-03-03 12:14:34 +03:00
This is done to override the value for FM . */
if ( dev - > active_mode = = V4L2_TUNER_RADIO )
dif_misc_ctrl_value = 0x7a080000 ;
/* Write the calculated value for misc ontrol register */
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_MISC_CTRL , dif_misc_ctrl_value ) ;
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
int cx231xx_tuner_pre_channel_change ( struct cx231xx * dev )
{
int status = 0 ;
u32 dwval ;
/* Set the RF and IF k_agc values to 3 */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DIF_AGC_IF_REF , & dwval ) ;
2009-03-03 20:37:50 +03:00
dwval & = ~ ( FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF ) ;
dwval | = 0x33000000 ;
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_AGC_IF_REF , dwval ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
int cx231xx_tuner_post_channel_change ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
u32 dwval ;
2010-10-07 10:23:25 +04:00
cx231xx_info ( " cx231xx_tuner_post_channel_change dev->tuner_type =0%d \n " ,
dev - > tuner_type ) ;
2009-03-11 03:16:26 +03:00
/* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for
* SECAM L / B / D standards */
2009-03-22 04:00:20 +03:00
status = vid_blk_read_word ( dev , DIF_AGC_IF_REF , & dwval ) ;
2009-03-03 12:14:34 +03:00
dwval & = ~ ( FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
if ( dev - > norm & ( V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
2010-07-07 01:12:25 +04:00
V4L2_STD_SECAM_D ) ) {
if ( dev - > tuner_type = = TUNER_NXP_TDA18271 ) {
dwval & = ~ FLD_DIF_IF_REF ;
dwval | = 0x88000300 ;
} else
dwval | = 0x88000000 ;
} else {
if ( dev - > tuner_type = = TUNER_NXP_TDA18271 ) {
dwval & = ~ FLD_DIF_IF_REF ;
dwval | = 0xCC000300 ;
} else
dwval | = 0x44000000 ;
}
2009-03-03 20:37:50 +03:00
2009-03-22 04:00:20 +03:00
status = vid_blk_write_word ( dev , DIF_AGC_IF_REF , dwval ) ;
2009-03-03 20:37:50 +03:00
2012-09-13 19:54:36 +04:00
return status = = sizeof ( dwval ) ? 0 : - EIO ;
2009-03-03 20:37:50 +03:00
}
2009-03-03 19:31:36 +03:00
/******************************************************************************
2009-03-22 04:00:20 +03:00
* I 2 S - B L O C K C O N T R O L functions *
2009-03-03 19:31:36 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-22 04:00:20 +03:00
int cx231xx_i2s_blk_initialize ( struct cx231xx * dev )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
u32 value ;
2009-03-22 04:00:20 +03:00
status = cx231xx_read_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 19:31:36 +03:00
CH_PWR_CTRL1 , 1 , & value , 1 ) ;
2009-03-03 12:14:34 +03:00
/* enables clock to delta-sigma and decimation filter */
value | = 0x80 ;
2009-03-22 04:00:20 +03:00
status = cx231xx_write_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 12:14:34 +03:00
CH_PWR_CTRL1 , 1 , value , 1 ) ;
/* power up all channel */
2009-03-22 04:00:20 +03:00
status = cx231xx_write_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 12:14:34 +03:00
CH_PWR_CTRL2 , 1 , 0x00 , 1 ) ;
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-22 04:00:20 +03:00
int cx231xx_i2s_blk_update_power_control ( struct cx231xx * dev ,
2009-03-11 03:16:26 +03:00
enum AV_MODE avmode )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
u32 value = 0 ;
if ( avmode ! = POLARIS_AVMODE_ENXTERNAL_AV ) {
2009-03-22 04:00:20 +03:00
status = cx231xx_read_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 12:14:34 +03:00
CH_PWR_CTRL2 , 1 , & value , 1 ) ;
value | = 0xfe ;
2009-03-22 04:00:20 +03:00
status = cx231xx_write_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 12:14:34 +03:00
CH_PWR_CTRL2 , 1 , value , 1 ) ;
} else {
2009-03-22 04:00:20 +03:00
status = cx231xx_write_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 12:14:34 +03:00
CH_PWR_CTRL2 , 1 , 0x00 , 1 ) ;
}
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-22 04:00:20 +03:00
/* set i2s_blk for audio input types */
int cx231xx_i2s_blk_set_audio_input ( struct cx231xx * dev , u8 audio_input )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
switch ( audio_input ) {
case CX231XX_AMUX_LINE_IN :
2009-03-22 04:00:20 +03:00
status = cx231xx_write_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 12:14:34 +03:00
CH_PWR_CTRL2 , 1 , 0x00 , 1 ) ;
2009-03-22 04:00:20 +03:00
status = cx231xx_write_i2c_data ( dev , I2S_BLK_DEVICE_ADDRESS ,
2009-03-03 12:14:34 +03:00
CH_PWR_CTRL1 , 1 , 0x80 , 1 ) ;
break ;
case CX231XX_AMUX_VIDEO :
default :
break ;
}
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
dev - > ctl_ainput = audio_input ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-03 19:31:36 +03:00
/******************************************************************************
* P O W E R C O N T R O L functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-11 03:16:26 +03:00
int cx231xx_set_power_mode ( struct cx231xx * dev , enum AV_MODE mode )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
u8 value [ 4 ] = { 0 , 0 , 0 , 0 } ;
u32 tmp = 0 ;
int status = 0 ;
if ( dev - > power_mode ! = mode )
dev - > power_mode = mode ;
else {
cx231xx_info ( " setPowerMode::mode = %d, No Change req. \n " ,
mode ) ;
return 0 ;
}
2009-03-03 19:31:36 +03:00
status = cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , PWR_CTL_EN , value ,
4 ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 )
return status ;
2013-02-07 22:28:53 +04:00
tmp = le32_to_cpu ( * ( ( u32 * ) value ) ) ;
2009-03-03 12:14:34 +03:00
switch ( mode ) {
case POLARIS_AVMODE_ENXTERNAL_AV :
tmp & = ( ~ PWR_MODE_MASK ) ;
tmp | = PWR_AV_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
tmp | = PWR_ISO_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
status =
cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER , PWR_CTL_EN ,
value , 4 ) ;
msleep ( PWR_SLEEP_INTERVAL ) ;
tmp | = POLARIS_AVMODE_ENXTERNAL_AV ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
2009-03-04 23:49:01 +03:00
/* reset state of xceive tuner */
dev - > xc_fw_load_done = 0 ;
2009-03-03 12:14:34 +03:00
break ;
case POLARIS_AVMODE_ANALOGT_TV :
2010-07-07 01:12:25 +04:00
tmp | = PWR_DEMOD_EN ;
2009-03-03 12:14:34 +03:00
tmp | = ( I2C_DEMOD_EN ) ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
if ( ! ( tmp & PWR_TUNER_EN ) ) {
tmp | = ( PWR_TUNER_EN ) ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
if ( ! ( tmp & PWR_AV_EN ) ) {
tmp | = PWR_AV_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
if ( ! ( tmp & PWR_ISO_EN ) ) {
tmp | = PWR_ISO_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
if ( ! ( tmp & POLARIS_AVMODE_ANALOGT_TV ) ) {
tmp | = POLARIS_AVMODE_ANALOGT_TV ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
2010-09-27 03:38:24 +04:00
if ( dev - > board . tuner_type ! = TUNER_ABSENT ) {
/* Enable tuner */
cx231xx_enable_i2c_port_3 ( dev , true ) ;
2009-03-03 12:14:34 +03:00
2010-07-07 01:12:25 +04:00
/* reset the Tuner */
2010-09-27 03:38:24 +04:00
if ( dev - > board . tuner_gpio )
cx231xx_gpio_set ( dev , dev - > board . tuner_gpio ) ;
2010-07-07 01:12:25 +04:00
2009-03-03 12:14:34 +03:00
if ( dev - > cx231xx_reset_analog_tuner )
dev - > cx231xx_reset_analog_tuner ( dev ) ;
}
2010-07-07 01:12:25 +04:00
2009-03-03 12:14:34 +03:00
break ;
case POLARIS_AVMODE_DIGITAL :
if ( ! ( tmp & PWR_TUNER_EN ) ) {
tmp | = ( PWR_TUNER_EN ) ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
if ( ! ( tmp & PWR_AV_EN ) ) {
tmp | = PWR_AV_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
if ( ! ( tmp & PWR_ISO_EN ) ) {
tmp | = PWR_ISO_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
2010-07-12 22:31:56 +04:00
tmp & = ( ~ PWR_AV_MODE ) ;
2009-03-03 12:14:34 +03:00
tmp | = POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
if ( ! ( tmp & PWR_DEMOD_EN ) ) {
tmp | = PWR_DEMOD_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
2010-09-27 03:38:24 +04:00
if ( dev - > board . tuner_type ! = TUNER_ABSENT ) {
/*
* Enable tuner
* Hauppauge Exeter seems to need to do something different !
*/
if ( dev - > model = = CX231XX_BOARD_HAUPPAUGE_EXETER )
cx231xx_enable_i2c_port_3 ( dev , false ) ;
else
cx231xx_enable_i2c_port_3 ( dev , true ) ;
2009-03-03 12:14:34 +03:00
2010-07-07 01:12:25 +04:00
/* reset the Tuner */
2010-09-27 03:38:24 +04:00
if ( dev - > board . tuner_gpio )
cx231xx_gpio_set ( dev , dev - > board . tuner_gpio ) ;
2010-07-07 01:23:53 +04:00
2009-03-03 12:14:34 +03:00
if ( dev - > cx231xx_reset_analog_tuner )
dev - > cx231xx_reset_analog_tuner ( dev ) ;
}
break ;
default :
break ;
}
msleep ( PWR_SLEEP_INTERVAL ) ;
2009-03-03 19:31:36 +03:00
/* For power saving, only enable Pwr_resetout_n
when digital TV is selected . */
2009-03-03 12:14:34 +03:00
if ( mode = = POLARIS_AVMODE_DIGITAL ) {
tmp | = PWR_RESETOUT_EN ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
PWR_CTL_EN , value , 4 ) ;
2009-03-03 12:14:34 +03:00
msleep ( PWR_SLEEP_INTERVAL ) ;
}
2009-03-22 04:00:20 +03:00
/* update power control for afe */
status = cx231xx_afe_update_power_control ( dev , mode ) ;
2009-03-03 12:14:34 +03:00
2009-03-22 04:00:20 +03:00
/* update power control for i2s_blk */
status = cx231xx_i2s_blk_update_power_control ( dev , mode ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
status = cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , PWR_CTL_EN , value ,
4 ) ;
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
int cx231xx_power_suspend ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
u8 value [ 4 ] = { 0 , 0 , 0 , 0 } ;
u32 tmp = 0 ;
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
status = cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , PWR_CTL_EN ,
value , 4 ) ;
2009-03-03 12:14:34 +03:00
if ( status > 0 )
return status ;
2009-03-03 20:37:50 +03:00
2013-02-07 22:28:53 +04:00
tmp = le32_to_cpu ( * ( ( u32 * ) value ) ) ;
2009-03-03 12:14:34 +03:00
tmp & = ( ~ PWR_MODE_MASK ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER , PWR_CTL_EN ,
value , 4 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-03 19:31:36 +03:00
/******************************************************************************
* S T R E A M C O N T R O L functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-03 20:37:50 +03:00
int cx231xx_start_stream ( struct cx231xx * dev , u32 ep_mask )
{
2009-03-03 12:14:34 +03:00
u8 value [ 4 ] = { 0x0 , 0x0 , 0x0 , 0x0 } ;
u32 tmp = 0 ;
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
cx231xx_info ( " cx231xx_start_stream():: ep_mask = %x \n " , ep_mask ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , EP_MODE_SET ,
value , 4 ) ;
2009-03-03 12:14:34 +03:00
if ( status < 0 )
return status ;
2009-03-03 20:37:50 +03:00
2013-02-07 22:28:53 +04:00
tmp = le32_to_cpu ( * ( ( u32 * ) value ) ) ;
2009-03-03 12:14:34 +03:00
tmp | = ep_mask ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER , EP_MODE_SET ,
value , 4 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
int cx231xx_stop_stream ( struct cx231xx * dev , u32 ep_mask )
{
2009-03-03 12:14:34 +03:00
u8 value [ 4 ] = { 0x0 , 0x0 , 0x0 , 0x0 } ;
u32 tmp = 0 ;
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
cx231xx_info ( " cx231xx_stop_stream():: ep_mask = %x \n " , ep_mask ) ;
status =
cx231xx_read_ctrl_reg ( dev , VRT_GET_REGISTER , EP_MODE_SET , value , 4 ) ;
if ( status < 0 )
return status ;
2009-03-03 20:37:50 +03:00
2013-02-07 22:28:53 +04:00
tmp = le32_to_cpu ( * ( ( u32 * ) value ) ) ;
2009-03-03 12:14:34 +03:00
tmp & = ( ~ ep_mask ) ;
value [ 0 ] = ( u8 ) tmp ;
value [ 1 ] = ( u8 ) ( tmp > > 8 ) ;
value [ 2 ] = ( u8 ) ( tmp > > 16 ) ;
value [ 3 ] = ( u8 ) ( tmp > > 24 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER , EP_MODE_SET ,
value , 4 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
int cx231xx_initialize_stream_xfer ( struct cx231xx * dev , u32 media_type )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2010-07-07 01:12:25 +04:00
u32 value = 0 ;
u8 val [ 4 ] = { 0 , 0 , 0 , 0 } ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
if ( dev - > udev - > speed = = USB_SPEED_HIGH ) {
switch ( media_type ) {
2012-06-18 07:20:06 +04:00
case Audio :
2009-03-03 12:14:34 +03:00
cx231xx_info ( " %s: Audio enter HANC \n " , __func__ ) ;
status =
cx231xx_mode_register ( dev , TS_MODE_REG , 0x9300 ) ;
break ;
2012-06-18 07:20:06 +04:00
case Vbi :
2009-03-03 12:14:34 +03:00
cx231xx_info ( " %s: set vanc registers \n " , __func__ ) ;
status = cx231xx_mode_register ( dev , TS_MODE_REG , 0x300 ) ;
break ;
2012-06-18 07:20:06 +04:00
case Sliced_cc :
2009-03-03 12:14:34 +03:00
cx231xx_info ( " %s: set hanc registers \n " , __func__ ) ;
status =
cx231xx_mode_register ( dev , TS_MODE_REG , 0x1300 ) ;
break ;
2012-06-18 07:20:06 +04:00
case Raw_Video :
2009-03-03 12:14:34 +03:00
cx231xx_info ( " %s: set video registers \n " , __func__ ) ;
status = cx231xx_mode_register ( dev , TS_MODE_REG , 0x100 ) ;
break ;
2012-06-18 07:20:06 +04:00
case TS1_serial_mode :
2010-07-07 01:12:25 +04:00
cx231xx_info ( " %s: set ts1 registers " , __func__ ) ;
2011-02-01 04:12:15 +03:00
if ( dev - > board . has_417 ) {
2010-07-07 01:12:25 +04:00
cx231xx_info ( " MPEG \n " ) ;
value & = 0xFFFFFFFC ;
value | = 0x3 ;
status = cx231xx_mode_register ( dev , TS_MODE_REG , value ) ;
val [ 0 ] = 0x04 ;
val [ 1 ] = 0xA3 ;
val [ 2 ] = 0x3B ;
val [ 3 ] = 0x00 ;
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
TS1_CFG_REG , val , 4 ) ;
val [ 0 ] = 0x00 ;
val [ 1 ] = 0x08 ;
val [ 2 ] = 0x00 ;
val [ 3 ] = 0x08 ;
status = cx231xx_write_ctrl_reg ( dev , VRT_SET_REGISTER ,
TS1_LENGTH_REG , val , 4 ) ;
} else {
cx231xx_info ( " BDA \n " ) ;
2009-03-03 12:14:34 +03:00
status = cx231xx_mode_register ( dev , TS_MODE_REG , 0x101 ) ;
2010-07-07 01:12:25 +04:00
status = cx231xx_mode_register ( dev , TS1_CFG_REG , 0x010 ) ;
}
2009-03-03 12:14:34 +03:00
break ;
2010-07-07 01:12:25 +04:00
2012-06-18 07:20:06 +04:00
case TS1_parallel_mode :
2011-03-31 05:57:33 +04:00
cx231xx_info ( " %s: set ts1 parallel mode registers \n " ,
2009-03-03 12:14:34 +03:00
__func__ ) ;
status = cx231xx_mode_register ( dev , TS_MODE_REG , 0x100 ) ;
status = cx231xx_mode_register ( dev , TS1_CFG_REG , 0x400 ) ;
break ;
}
} else {
status = cx231xx_mode_register ( dev , TS_MODE_REG , 0x101 ) ;
}
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
}
2009-03-03 20:37:50 +03:00
int cx231xx_capture_start ( struct cx231xx * dev , int start , u8 media_type )
{
2009-06-20 16:21:37 +04:00
int rc = - 1 ;
2009-03-03 12:14:34 +03:00
u32 ep_mask = - 1 ;
2009-03-04 23:49:01 +03:00
struct pcb_config * pcb_config ;
2009-03-03 12:14:34 +03:00
/* get EP for media type */
2009-03-04 23:49:01 +03:00
pcb_config = ( struct pcb_config * ) & dev - > current_pcb_config ;
2009-03-03 12:14:34 +03:00
2012-06-18 07:20:06 +04:00
if ( pcb_config - > config_num ) {
2009-03-03 12:14:34 +03:00
switch ( media_type ) {
2012-06-18 07:20:06 +04:00
case Raw_Video :
2009-03-03 12:14:34 +03:00
ep_mask = ENABLE_EP4 ; /* ep4 [00:1000] */
break ;
2012-06-18 07:20:06 +04:00
case Audio :
2009-03-03 12:14:34 +03:00
ep_mask = ENABLE_EP3 ; /* ep3 [00:0100] */
break ;
2012-06-18 07:20:06 +04:00
case Vbi :
2009-03-03 12:14:34 +03:00
ep_mask = ENABLE_EP5 ; /* ep5 [01:0000] */
break ;
2012-06-18 07:20:06 +04:00
case Sliced_cc :
2009-03-03 12:14:34 +03:00
ep_mask = ENABLE_EP6 ; /* ep6 [10:0000] */
break ;
2012-06-18 07:20:06 +04:00
case TS1_serial_mode :
case TS1_parallel_mode :
2009-03-03 12:14:34 +03:00
ep_mask = ENABLE_EP1 ; /* ep1 [00:0001] */
break ;
2012-06-18 07:20:06 +04:00
case TS2 :
2009-03-03 12:14:34 +03:00
ep_mask = ENABLE_EP2 ; /* ep2 [00:0010] */
break ;
}
}
if ( start ) {
rc = cx231xx_initialize_stream_xfer ( dev , media_type ) ;
2009-03-03 19:31:36 +03:00
if ( rc < 0 )
2009-03-03 12:14:34 +03:00
return rc ;
/* enable video capture */
if ( ep_mask > 0 )
rc = cx231xx_start_stream ( dev , ep_mask ) ;
} else {
/* disable video capture */
if ( ep_mask > 0 )
rc = cx231xx_stop_stream ( dev , ep_mask ) ;
}
2009-03-03 20:37:50 +03:00
return rc ;
}
2009-03-03 12:14:34 +03:00
EXPORT_SYMBOL_GPL ( cx231xx_capture_start ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
/*****************************************************************************
* G P I O B I T control functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-02-08 20:13:12 +04:00
static int cx231xx_set_gpio_bit ( struct cx231xx * dev , u32 gpio_bit , u32 gpio_val )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
2013-02-08 20:13:12 +04:00
gpio_val = cpu_to_le32 ( gpio_val ) ;
status = cx231xx_send_gpio_cmd ( dev , gpio_bit , ( u8 * ) & gpio_val , 4 , 0 , 0 ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2013-02-08 20:13:12 +04:00
static int cx231xx_get_gpio_bit ( struct cx231xx * dev , u32 gpio_bit , u32 * gpio_val )
2009-03-03 20:37:50 +03:00
{
2013-02-08 20:13:12 +04:00
u32 tmp ;
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
2013-02-08 20:13:12 +04:00
status = cx231xx_send_gpio_cmd ( dev , gpio_bit , ( u8 * ) & tmp , 4 , 0 , 1 ) ;
* gpio_val = le32_to_cpu ( tmp ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
/*
* cx231xx_set_gpio_direction
* Sets the direction of the GPIO pin to input or output
*
* Parameters :
* pin_number : The GPIO Pin number to program the direction for
* from 0 to 31
* pin_value : The Direction of the GPIO Pin under reference .
* 0 = Input direction
* 1 = Output direction
*/
int cx231xx_set_gpio_direction ( struct cx231xx * dev ,
2009-03-03 12:14:34 +03:00
int pin_number , int pin_value )
2009-03-03 20:37:50 +03:00
{
int status = 0 ;
2009-03-03 12:14:34 +03:00
u32 value = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* Check for valid pin_number - if 32 , bail out */
2009-03-03 19:31:36 +03:00
if ( pin_number > = 32 )
2009-03-03 12:14:34 +03:00
return - EINVAL ;
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
/* input */
if ( pin_value = = 0 )
2009-03-03 12:14:34 +03:00
value = dev - > gpio_dir & ( ~ ( 1 < < pin_number ) ) ; /* clear */
2009-03-03 19:31:36 +03:00
else
2009-03-03 12:14:34 +03:00
value = dev - > gpio_dir | ( 1 < < pin_number ) ;
2009-03-03 20:37:50 +03:00
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , value , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* cache the value for future */
2009-03-03 20:37:50 +03:00
dev - > gpio_dir = value ;
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
/*
2009-03-11 03:16:26 +03:00
* cx231xx_set_gpio_value
2009-03-03 20:37:50 +03:00
* Sets the value of the GPIO pin to Logic high or low . The Pin under
* reference should ALREADY BE SET IN OUTPUT MODE ! ! ! ! ! ! ! ! !
*
* Parameters :
* pin_number : The GPIO Pin number to program the direction for
* pin_value : The value of the GPIO Pin under reference .
* 0 = set it to 0
* 1 = set it to 1
*/
2009-03-03 12:14:34 +03:00
int cx231xx_set_gpio_value ( struct cx231xx * dev , int pin_number , int pin_value )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
u32 value = 0 ;
/* Check for valid pin_number - if 0xFF , bail out */
if ( pin_number > = 32 )
return - EINVAL ;
/* first do a sanity check - if the Pin is not output, make it output */
if ( ( dev - > gpio_dir & ( 1 < < pin_number ) ) = = 0x00 ) {
/* It was in input mode */
value = dev - > gpio_dir | ( 1 < < pin_number ) ;
dev - > gpio_dir = value ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
value = 0 ;
2009-03-03 12:14:34 +03:00
}
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
if ( pin_value = = 0 )
2009-03-03 12:14:34 +03:00
value = dev - > gpio_val & ( ~ ( 1 < < pin_number ) ) ;
2009-03-03 19:31:36 +03:00
else
2009-03-03 12:14:34 +03:00
value = dev - > gpio_val | ( 1 < < pin_number ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* store the value */
dev - > gpio_val = value ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* toggle bit0 of GP_IO */
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
return status ;
2009-03-03 20:37:50 +03:00
}
2009-03-03 19:31:36 +03:00
/*****************************************************************************
* G P I O I2C related functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-03 20:37:50 +03:00
int cx231xx_gpio_i2c_start ( struct cx231xx * dev )
{
int status = 0 ;
/* set SCL to output 1 ; set SDA to output 1 */
2009-03-03 12:14:34 +03:00
dev - > gpio_dir | = 1 < < dev - > board . tuner_scl_gpio ;
dev - > gpio_dir | = 1 < < dev - > board . tuner_sda_gpio ;
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
dev - > gpio_val | = 1 < < dev - > board . tuner_sda_gpio ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 19:31:36 +03:00
if ( status < 0 )
2009-03-03 20:37:50 +03:00
return - EINVAL ;
/* set SCL to output 1; set SDA to output 0 */
2009-03-03 12:14:34 +03:00
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 20:37:50 +03:00
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 19:31:36 +03:00
if ( status < 0 )
2009-03-03 20:37:50 +03:00
return - EINVAL ;
2009-03-03 12:14:34 +03:00
/* set SCL to output 0; set SDA to output 0 */
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 20:37:50 +03:00
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 19:31:36 +03:00
if ( status < 0 )
2009-03-03 20:37:50 +03:00
return - EINVAL ;
return status ;
}
int cx231xx_gpio_i2c_end ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* set SCL to output 0; set SDA to output 0 */
dev - > gpio_dir | = 1 < < dev - > board . tuner_scl_gpio ;
dev - > gpio_dir | = 1 < < dev - > board . tuner_sda_gpio ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 20:37:50 +03:00
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 19:31:36 +03:00
if ( status < 0 )
2009-03-03 20:37:50 +03:00
return - EINVAL ;
2009-03-03 12:14:34 +03:00
/* set SCL to output 1; set SDA to output 0 */
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 20:37:50 +03:00
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 19:31:36 +03:00
if ( status < 0 )
2009-03-03 20:37:50 +03:00
return - EINVAL ;
/* set SCL to input ,release SCL cable control
set SDA to input , release SDA cable control */
2009-03-03 12:14:34 +03:00
dev - > gpio_dir & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
dev - > gpio_dir & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
status =
2013-02-08 20:13:12 +04:00
cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 19:31:36 +03:00
if ( status < 0 )
2009-03-03 20:37:50 +03:00
return - EINVAL ;
2009-03-03 19:31:36 +03:00
2009-03-03 20:37:50 +03:00
return status ;
}
int cx231xx_gpio_i2c_write_byte ( struct cx231xx * dev , u8 data )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
u8 i ;
2009-03-03 20:37:50 +03:00
/* set SCL to output ; set SDA to output */
2009-03-03 12:14:34 +03:00
dev - > gpio_dir | = 1 < < dev - > board . tuner_scl_gpio ;
dev - > gpio_dir | = 1 < < dev - > board . tuner_sda_gpio ;
for ( i = 0 ; i < 8 ; i + + ) {
if ( ( ( data < < i ) & 0x80 ) = = 0 ) {
/* set SCL to output 0; set SDA to output 0 */
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 12:14:34 +03:00
/* set SCL to output 1; set SDA to output 0 */
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 12:14:34 +03:00
/* set SCL to output 0; set SDA to output 0 */
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
} else {
2009-03-03 12:14:34 +03:00
/* set SCL to output 0; set SDA to output 1 */
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
dev - > gpio_val | = 1 < < dev - > board . tuner_sda_gpio ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 12:14:34 +03:00
/* set SCL to output 1; set SDA to output 1 */
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 12:14:34 +03:00
/* set SCL to output 0; set SDA to output 1 */
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 12:14:34 +03:00
}
2009-03-03 20:37:50 +03:00
}
return status ;
}
2010-07-07 01:12:25 +04:00
int cx231xx_gpio_i2c_read_byte ( struct cx231xx * dev , u8 * buf )
2009-03-03 20:37:50 +03:00
{
u8 value = 0 ;
2009-03-03 12:14:34 +03:00
int status = 0 ;
u32 gpio_logic_value = 0 ;
u8 i ;
2009-03-03 20:37:50 +03:00
/* read byte */
2009-03-03 12:14:34 +03:00
for ( i = 0 ; i < 8 ; i + + ) { /* send write I2c addr */
2009-03-03 20:37:50 +03:00
/* set SCL to output 0; set SDA to input */
2009-03-03 12:14:34 +03:00
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* set SCL to output 1; set SDA to input */
2009-03-03 12:14:34 +03:00
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
2009-03-03 19:31:36 +03:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* get SDA data bit */
gpio_logic_value = dev - > gpio_val ;
2009-03-03 19:31:36 +03:00
status = cx231xx_get_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
& dev - > gpio_val ) ;
2009-03-03 19:31:36 +03:00
if ( ( dev - > gpio_val & ( 1 < < dev - > board . tuner_sda_gpio ) ) ! = 0 )
2009-03-03 12:14:34 +03:00
value | = ( 1 < < ( 8 - i - 1 ) ) ;
2009-03-03 20:37:50 +03:00
dev - > gpio_val = gpio_logic_value ;
}
/* set SCL to output 0,finish the read latest SCL signal.
2009-03-03 19:31:36 +03:00
! ! ! set SDA to input , never to modify SDA direction at
the same times */
2009-03-03 12:14:34 +03:00
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* store the value */
* buf = value & 0xff ;
2009-03-03 20:37:50 +03:00
return status ;
}
int cx231xx_gpio_i2c_read_ack ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
u32 gpio_logic_value = 0 ;
2009-03-03 12:14:34 +03:00
int nCnt = 10 ;
int nInit = nCnt ;
2009-03-03 20:37:50 +03:00
2009-03-03 19:31:36 +03:00
/* clock stretch; set SCL to input; set SDA to input;
get SCL value till SCL = 1 */
2009-03-03 12:14:34 +03:00
dev - > gpio_dir & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
dev - > gpio_dir & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2009-03-03 20:37:50 +03:00
gpio_logic_value = dev - > gpio_val ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
do {
2009-03-03 20:37:50 +03:00
msleep ( 2 ) ;
2009-03-03 19:31:36 +03:00
status = cx231xx_get_gpio_bit ( dev , dev - > gpio_dir ,
2013-02-08 20:13:12 +04:00
& dev - > gpio_val ) ;
2009-03-03 12:14:34 +03:00
nCnt - - ;
2009-03-04 23:49:01 +03:00
} while ( ( ( dev - > gpio_val &
( 1 < < dev - > board . tuner_scl_gpio ) ) = = 0 ) & &
( nCnt > 0 ) ) ;
2009-03-03 12:14:34 +03:00
2009-03-03 19:31:36 +03:00
if ( nCnt = = 0 )
2009-03-04 23:49:01 +03:00
cx231xx_info ( " No ACK after %d msec -GPIO I2C failed! " ,
2009-03-03 19:31:36 +03:00
nInit * 10 ) ;
2009-03-03 20:37:50 +03:00
tree-wide: fix assorted typos all over the place
That is "success", "unknown", "through", "performance", "[re|un]mapping"
, "access", "default", "reasonable", "[con]currently", "temperature"
, "channel", "[un]used", "application", "example","hierarchy", "therefore"
, "[over|under]flow", "contiguous", "threshold", "enough" and others.
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2009-11-14 18:09:05 +03:00
/*
* readAck
* through clock stretch , slave has given a SCL signal ,
* so the SDA data can be directly read .
*/
2013-02-08 20:13:12 +04:00
status = cx231xx_get_gpio_bit ( dev , dev - > gpio_dir , & dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
if ( ( dev - > gpio_val & 1 < < dev - > board . tuner_sda_gpio ) = = 0 ) {
2009-03-03 20:37:50 +03:00
dev - > gpio_val = gpio_logic_value ;
2009-03-03 12:14:34 +03:00
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 20:37:50 +03:00
status = 0 ;
} else {
dev - > gpio_val = gpio_logic_value ;
2009-03-03 12:14:34 +03:00
dev - > gpio_val | = ( 1 < < dev - > board . tuner_sda_gpio ) ;
2009-03-03 20:37:50 +03:00
}
2009-03-03 19:31:36 +03:00
/* read SDA end, set the SCL to output 0, after this operation,
SDA direction can be changed . */
2009-03-03 20:37:50 +03:00
dev - > gpio_val = gpio_logic_value ;
2009-03-03 12:14:34 +03:00
dev - > gpio_dir | = ( 1 < < dev - > board . tuner_scl_gpio ) ;
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
return status ;
}
int cx231xx_gpio_i2c_write_ack ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
/* set SDA to ouput */
2009-03-03 12:14:34 +03:00
dev - > gpio_dir | = 1 < < dev - > board . tuner_sda_gpio ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* set SCL = 0 (output); set SDA = 0 (output) */
2009-03-03 12:14:34 +03:00
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* set SCL = 1 (output); set SDA = 0 (output) */
2009-03-03 12:14:34 +03:00
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* set SCL = 0 (output); set SDA = 0 (output) */
2009-03-03 12:14:34 +03:00
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* set SDA to input,and then the slave will read data from SDA. */
2009-03-03 12:14:34 +03:00
dev - > gpio_dir & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
return status ;
}
int cx231xx_gpio_i2c_write_nak ( struct cx231xx * dev )
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
2009-03-03 20:37:50 +03:00
/* set scl to output ; set sda to input */
2009-03-03 12:14:34 +03:00
dev - > gpio_dir | = 1 < < dev - > board . tuner_scl_gpio ;
dev - > gpio_dir & = ~ ( 1 < < dev - > board . tuner_sda_gpio ) ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* set scl to output 0; set sda to input */
2009-03-03 12:14:34 +03:00
dev - > gpio_val & = ~ ( 1 < < dev - > board . tuner_scl_gpio ) ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
/* set scl to output 1; set sda to input */
2009-03-03 12:14:34 +03:00
dev - > gpio_val | = 1 < < dev - > board . tuner_scl_gpio ;
2013-02-08 20:13:12 +04:00
status = cx231xx_set_gpio_bit ( dev , dev - > gpio_dir , dev - > gpio_val ) ;
2009-03-03 20:37:50 +03:00
return status ;
}
2009-03-03 19:31:36 +03:00
/*****************************************************************************
* G P I O I2C related functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-03 20:37:50 +03:00
/* cx231xx_gpio_i2c_read
* Function to read data from gpio based I2C interface
*/
2010-07-07 01:12:25 +04:00
int cx231xx_gpio_i2c_read ( struct cx231xx * dev , u8 dev_addr , u8 * buf , u8 len )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int status = 0 ;
int i = 0 ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* get the lock */
2009-03-03 20:37:50 +03:00
mutex_lock ( & dev - > gpio_i2c_lock ) ;
/* start */
status = cx231xx_gpio_i2c_start ( dev ) ;
/* write dev_addr */
2009-03-03 12:14:34 +03:00
status = cx231xx_gpio_i2c_write_byte ( dev , ( dev_addr < < 1 ) + 1 ) ;
2009-03-03 20:37:50 +03:00
/* readAck */
status = cx231xx_gpio_i2c_read_ack ( dev ) ;
2009-03-03 12:14:34 +03:00
/* read data */
for ( i = 0 ; i < len ; i + + ) {
/* read data */
buf [ i ] = 0 ;
status = cx231xx_gpio_i2c_read_byte ( dev , & buf [ i ] ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
if ( ( i + 1 ) ! = len ) {
/* only do write ack if we more length */
status = cx231xx_gpio_i2c_write_ack ( dev ) ;
}
}
2009-03-03 20:37:50 +03:00
/* write NAK - inform reads are complete */
status = cx231xx_gpio_i2c_write_nak ( dev ) ;
/* write end */
status = cx231xx_gpio_i2c_end ( dev ) ;
/* release the lock */
mutex_unlock ( & dev - > gpio_i2c_lock ) ;
return status ;
}
/* cx231xx_gpio_i2c_write
* Function to write data to gpio based I2C interface
*/
2010-07-07 01:12:25 +04:00
int cx231xx_gpio_i2c_write ( struct cx231xx * dev , u8 dev_addr , u8 * buf , u8 len )
2009-03-03 20:37:50 +03:00
{
2009-03-03 12:14:34 +03:00
int i = 0 ;
2009-03-03 20:37:50 +03:00
/* get the lock */
mutex_lock ( & dev - > gpio_i2c_lock ) ;
/* start */
2012-05-14 17:14:53 +04:00
cx231xx_gpio_i2c_start ( dev ) ;
2009-03-03 20:37:50 +03:00
/* write dev_addr */
2012-05-14 17:14:53 +04:00
cx231xx_gpio_i2c_write_byte ( dev , dev_addr < < 1 ) ;
2009-03-03 20:37:50 +03:00
/* read Ack */
2012-05-14 17:14:53 +04:00
cx231xx_gpio_i2c_read_ack ( dev ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
for ( i = 0 ; i < len ; i + + ) {
2009-03-03 20:37:50 +03:00
/* Write data */
2012-05-14 17:14:53 +04:00
cx231xx_gpio_i2c_write_byte ( dev , buf [ i ] ) ;
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* read Ack */
2012-05-14 17:14:53 +04:00
cx231xx_gpio_i2c_read_ack ( dev ) ;
2009-03-03 12:14:34 +03:00
}
2009-03-03 20:37:50 +03:00
2009-03-03 12:14:34 +03:00
/* write End */
2012-05-14 17:14:53 +04:00
cx231xx_gpio_i2c_end ( dev ) ;
2009-03-03 20:37:50 +03:00
/* release the lock */
mutex_unlock ( & dev - > gpio_i2c_lock ) ;
return 0 ;
}