*******************************************************************************/
/******************************************************************************
* VERVE REGISTER *
- * *
+ * *
******************************************************************************/
static int verve_write_byte(struct cx231xx *dev, u8 saddr, u8 data)
{
if (ch1_setting != 0) {
status = afe_read_byte(dev, ADC_INPUT_CH1, &value);
- value &= (!INPUT_SEL_MASK);
+ value &= ~INPUT_SEL_MASK;
value |= (ch1_setting - 1) << 4;
value &= 0xff;
status = afe_write_byte(dev, ADC_INPUT_CH1, value);
if (ch2_setting != 0) {
status = afe_read_byte(dev, ADC_INPUT_CH2, &value);
- value &= (!INPUT_SEL_MASK);
+ value &= ~INPUT_SEL_MASK;
value |= (ch2_setting - 1) << 4;
value &= 0xff;
status = afe_write_byte(dev, ADC_INPUT_CH2, value);
7 less than the input number */
if (ch3_setting != 0) {
status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
- value &= (!INPUT_SEL_MASK);
+ value &= ~INPUT_SEL_MASK;
value |= (ch3_setting - 1) << 4;
value &= 0xff;
status = afe_write_byte(dev, ADC_INPUT_CH3, value);
case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
FLD_PWRDN_ENABLE_PLL)) {
value |= (1 << 7);
status = vid_blk_write_word(dev, OUT_CTRL1, value);
- /* Set vip 1.1 output mode */
+ /* Set output mode */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
OUT_CTRL1,
FLD_OUT_MODE,
- OUT_MODE_VIP11);
+ dev->board.output_mode);
/* Tell DIF object to go to baseband mode */
status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
value |= (1 << 7);
status = vid_blk_write_word(dev, OUT_CTRL1, value);
- /* Set vip 1.1 output mode */
+ /* Set output mode */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
OUT_CTRL1, FLD_OUT_MODE,
- OUT_MODE_VIP11);
+ dev->board.output_mode);
/* Tell DIF object to go to baseband mode */
status = cx231xx_dif_set_standard(dev,
(FLD_OEF_AGC_IF);
status = vid_blk_write_word(dev, PIN_CTRL, value);
- /* Set vip 1.1 output mode */
+ /* Set output mode */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
OUT_CTRL1, FLD_OUT_MODE,
- OUT_MODE_VIP11);
+ dev->board.output_mode);
/* Disable auto config of registers */
status = cx231xx_read_modify_write_i2c_dword(dev,
{
u8 temp = 0;
int status;
- /*enable TS1 data[0:7] as output to export 656*/
+ /*enable TS1 data[0:7] as output to export 656*/
status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0xFF);
- /*enable TS1 clock as output to export 656*/
+ /*enable TS1 clock as output to export 656*/
status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
temp = temp|0x04;
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
- FLD_VBLANK_CNT, 0x24);
+ FLD_VBLANK_CNT, 0x20);
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ VERT_TIM_CTRL,
+ FLD_VACTIVE_CNT,
+ cx231xx_set_field
+ (FLD_VACTIVE_CNT,
+ 0x244));
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
FLD_V656BLANK_CNT,
cx231xx_set_field
(FLD_V656BLANK_CNT,
- 0x28));
+ 0x24));
/* Adjust the active video horizontal start point */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
- FLD_VBLANK_CNT, 0x24);
+ FLD_VBLANK_CNT, 0x20);
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ VERT_TIM_CTRL,
+ FLD_VACTIVE_CNT,
+ cx231xx_set_field
+ (FLD_VACTIVE_CNT,
+ 0x244));
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
FLD_V656BLANK_CNT,
cx231xx_set_field
(FLD_V656BLANK_CNT,
- 0x28));
+ 0x24));
/* Adjust the active video horizontal start point */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
status = restartAudioFirmware(dev);
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
- case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
+ switch (dev->board.tuner_type) {
+ case TUNER_XC5000:
+ /* SIF passthrough at 28.6363 MHz sample rate */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
CHIP_CTRL,
FLD_SIF_EN,
cx231xx_set_field(FLD_SIF_EN, 1));
break;
- case CX231XX_BOARD_CNXT_RDE_253S:
- case CX231XX_BOARD_CNXT_RDU_253S:
- case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case TUNER_NXP_TDA18271:
+ /* Normal mode: SIF passthrough at 14.32 MHz */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
CHIP_CTRL,
cx231xx_set_field(FLD_SIF_EN, 0));
break;
default:
+ /* 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");
break;
}
break;
return status;
}
-int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex)
+int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
{
u8 value[4] = { 0, 0, 0, 0 };
int status = 0;
-
- cx231xx_info("Changing the i2c port for tuner to %d\n", I2CIndex);
+ bool current_is_port_3;
status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
PWR_CTL_EN, value, 4);
if (status < 0)
return status;
- if (I2CIndex == I2C_1) {
- if (value[0] & I2C_DEMOD_EN) {
- value[0] &= ~I2C_DEMOD_EN;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- }
- } else {
- if (!(value[0] & I2C_DEMOD_EN)) {
- value[0] |= I2C_DEMOD_EN;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- }
- }
+ 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);
return status;
}
-EXPORT_SYMBOL_GPL(cx231xx_enable_i2c_for_tuner);
+EXPORT_SYMBOL_GPL(cx231xx_enable_i2c_port_3);
+
void update_HH_register_after_set_DIF(struct cx231xx *dev)
{
/*
i = i+3;
}
- status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
- cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
- vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390);
- status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
- cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
-
+ status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
+ cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
+ vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390);
+ status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
+ cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
}
+
void cx231xx_dump_SC_reg(struct cx231xx *dev)
{
u8 value[4] = { 0, 0, 0, 0 };
/*
- config colibri to lo-if mode
+ config colibri to lo-if mode
- FIXME: ntf_mode = 2'b00 by default. But set 0x1 would reduce
- the diff IF input by half,
+ FIXME: ntf_mode = 2'b00 by default. But set 0x1 would reduce
+ the diff IF input by half,
- for low-if agc defect
+ for low-if agc defect
*/
status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3, &value);
void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq,
u8 spectral_invert, u32 mode)
{
-
- u32 colibri_carrier_offset = 0;
- u8 status = 0;
- u32 func_mode = 0;
- u32 standard = 0;
+ u32 colibri_carrier_offset = 0;
+ u8 status = 0;
+ u32 func_mode = 0x01; /* Device has a DIF if this function is called */
+ u32 standard = 0;
u8 value[4] = { 0, 0, 0, 0 };
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_CARRAERA:
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_SHELBY:
- case CX231XX_BOARD_CNXT_RDU_250:
- case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
- func_mode = 0x03;
- break;
- case CX231XX_BOARD_CNXT_RDE_253S:
- case CX231XX_BOARD_CNXT_RDU_253S:
- func_mode = 0x01;
- break;
-
- default:
- func_mode = 0x01;
- }
-
cx231xx_info("Enter cx231xx_set_Colibri_For_LowIF()\n");
- value[0] = (u8) 0x6F;
- value[1] = (u8) 0x6F;
- value[2] = (u8) 0x6F;
- value[3] = (u8) 0x6F;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- if (1) {
+ value[0] = (u8) 0x6F;
+ value[1] = (u8) 0x6F;
+ value[2] = (u8) 0x6F;
+ value[3] = (u8) 0x6F;
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
/*Set colibri for low IF*/
status = cx231xx_afe_set_mode(dev, AFE_MODE_LOW_IF);
-
/* Set C2HH for low IF operation.*/
standard = dev->norm;
status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
- func_mode, standard);
-
+ func_mode, standard);
/* Get colibri offsets.*/
colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode,
- standard);
+ standard);
cx231xx_info("colibri_carrier_offset=%d, standard=0x%x\n",
- colibri_carrier_offset, standard);
+ colibri_carrier_offset, standard);
/* Set the band Pass filter for DIF*/
- cx231xx_set_DIF_bandpass(dev, (if_freq+colibri_carrier_offset)
- , spectral_invert, mode);
- }
+ cx231xx_set_DIF_bandpass(dev, (if_freq+colibri_carrier_offset),
+ spectral_invert, mode);
}
u32 cx231xx_Get_Colibri_CarrierOffset(u32 mode, u32 standerd)
{
- u32 colibri_carrier_offset = 0;
+ u32 colibri_carrier_offset = 0;
-
- if (mode == TUNER_MODE_FM_RADIO) {
+ if (mode == TUNER_MODE_FM_RADIO) {
colibri_carrier_offset = 1100000;
- } else if (standerd & (V4L2_STD_NTSC | V4L2_STD_NTSC_M_JP)) {
+ } else if (standerd & (V4L2_STD_MN | V4L2_STD_NTSC_M_JP)) {
colibri_carrier_offset = 4832000; /*4.83MHz */
} else if (standerd & (V4L2_STD_PAL_B | V4L2_STD_PAL_G)) {
colibri_carrier_offset = 2700000; /*2.70MHz */
colibri_carrier_offset = 2100000; /*2.10MHz */
}
-
- return colibri_carrier_offset;
+ return colibri_carrier_offset;
}
void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
u8 spectral_invert, u32 mode)
{
-
- unsigned long pll_freq_word;
- int status = 0;
- u32 dif_misc_ctrl_value = 0;
- u64 pll_freq_u64 = 0;
- u32 i = 0;
-
+ unsigned long pll_freq_word;
+ int status = 0;
+ u32 dif_misc_ctrl_value = 0;
+ u64 pll_freq_u64 = 0;
+ u32 i = 0;
cx231xx_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n",
if_freq, spectral_invert, mode);
- if (mode == TUNER_MODE_FM_RADIO) {
- pll_freq_word = 0x905A1CAC;
- status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
-
- } 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;*/
- status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
-
- if (spectral_invert) {
- if_freq -= 400000;
- /* Enable Spectral Invert*/
- status = vid_blk_read_word(dev, DIF_MISC_CTRL,
- &dif_misc_ctrl_value);
- dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000;
- status = vid_blk_write_word(dev, DIF_MISC_CTRL,
- dif_misc_ctrl_value);
- } else {
- if_freq += 400000;
- /* Disable Spectral Invert*/
- status = vid_blk_read_word(dev, DIF_MISC_CTRL,
- &dif_misc_ctrl_value);
- dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF;
- status = vid_blk_write_word(dev, DIF_MISC_CTRL,
- dif_misc_ctrl_value);
- }
+ if (mode == TUNER_MODE_FM_RADIO) {
+ pll_freq_word = 0x905A1CAC;
+ status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
- if_freq = (if_freq/100000)*100000;
+ } 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;*/
+ status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
+
+ if (spectral_invert) {
+ if_freq -= 400000;
+ /* Enable Spectral Invert*/
+ status = vid_blk_read_word(dev, DIF_MISC_CTRL,
+ &dif_misc_ctrl_value);
+ dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000;
+ status = vid_blk_write_word(dev, DIF_MISC_CTRL,
+ dif_misc_ctrl_value);
+ } else {
+ if_freq += 400000;
+ /* Disable Spectral Invert*/
+ status = vid_blk_read_word(dev, DIF_MISC_CTRL,
+ &dif_misc_ctrl_value);
+ dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF;
+ status = vid_blk_write_word(dev, DIF_MISC_CTRL,
+ dif_misc_ctrl_value);
+ }
- if (if_freq < 3000000)
- if_freq = 3000000;
+ if_freq = (if_freq/100000)*100000;
- if (if_freq > 16000000)
- if_freq = 16000000;
- }
+ if (if_freq < 3000000)
+ if_freq = 3000000;
- cx231xx_info("Enter IF=%d\n",
- sizeof(Dif_set_array)/sizeof(struct dif_settings));
- for (i = 0; i < sizeof(Dif_set_array)/sizeof(struct dif_settings); i++) {
- if (Dif_set_array[i].if_freq == if_freq) {
- status = vid_blk_write_word(dev,
- Dif_set_array[i].register_address, Dif_set_array[i].value);
+ if (if_freq > 16000000)
+ if_freq = 16000000;
}
- }
+ cx231xx_info("Enter IF=%zd\n",
+ sizeof(Dif_set_array)/sizeof(struct dif_settings));
+ for (i = 0; i < sizeof(Dif_set_array)/sizeof(struct dif_settings); i++) {
+ if (Dif_set_array[i].if_freq == if_freq) {
+ status = vid_blk_write_word(dev,
+ Dif_set_array[i].register_address, Dif_set_array[i].value);
+ }
+ }
}
/******************************************************************************
{
int status = 0;
u32 dwval;
- cx231xx_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n",
- dev->tuner_type);
+ cx231xx_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n",
+ dev->tuner_type);
/* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for
* SECAM L/B/D standards */
status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
msleep(PWR_SLEEP_INTERVAL);
}
- if ((dev->model == CX231XX_BOARD_CNXT_CARRAERA) ||
- (dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
- (dev->model == CX231XX_BOARD_CNXT_SHELBY) ||
- (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
- /* tuner path to channel 1 from port 3 */
- cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ /* Enable tuner */
+ cx231xx_enable_i2c_port_3(dev, true);
/* reset the Tuner */
- cx231xx_gpio_set(dev, dev->board.tuner_gpio);
+ if (dev->board.tuner_gpio)
+ cx231xx_gpio_set(dev, dev->board.tuner_gpio);
- if (dev->cx231xx_reset_analog_tuner)
- dev->cx231xx_reset_analog_tuner(dev);
- } else if ((dev->model == CX231XX_BOARD_CNXT_RDE_253S) ||
- (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) ||
- (dev->model == CX231XX_BOARD_CNXT_RDU_253S) ||
- (dev->model == CX231XX_BOARD_HAUPPAUGE_EXETER)) {
- /* tuner path to channel 1 from port 3 */
- cx231xx_enable_i2c_for_tuner(dev, I2C_3);
if (dev->cx231xx_reset_analog_tuner)
dev->cx231xx_reset_analog_tuner(dev);
}
msleep(PWR_SLEEP_INTERVAL);
}
- if ((dev->model == CX231XX_BOARD_CNXT_CARRAERA) ||
- (dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
- (dev->model == CX231XX_BOARD_CNXT_SHELBY) ||
- (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
- /* tuner path to channel 1 from port 3 */
- cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+ 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);
/* reset the Tuner */
- cx231xx_gpio_set(dev, dev->board.tuner_gpio);
-
- if (dev->cx231xx_reset_analog_tuner)
- dev->cx231xx_reset_analog_tuner(dev);
- } else if ((dev->model == CX231XX_BOARD_CNXT_RDE_253S) ||
- (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) ||
- (dev->model == CX231XX_BOARD_CNXT_RDU_253S)) {
- /* tuner path to channel 1 from port 3 */
- cx231xx_enable_i2c_for_tuner(dev, I2C_3);
- if (dev->cx231xx_reset_analog_tuner)
- dev->cx231xx_reset_analog_tuner(dev);
- } else if (dev->model == CX231XX_BOARD_HAUPPAUGE_EXETER) {
- /* tuner path to channel 1 from port 1 ?? */
- cx231xx_enable_i2c_for_tuner(dev, I2C_1);
+ if (dev->board.tuner_gpio)
+ cx231xx_gpio_set(dev, dev->board.tuner_gpio);
if (dev->cx231xx_reset_analog_tuner)
dev->cx231xx_reset_analog_tuner(dev);
}
-
break;
default: