summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx231xx/cx231xx-avcore.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx231xx/cx231xx-avcore.c')
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c687
1 files changed, 617 insertions, 70 deletions
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index c217441..cf50faf 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -31,13 +31,16 @@
#include <linux/i2c.h>
#include <linux/mm.h>
#include <linux/mutex.h>
+#include <media/tuner.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>
#include "cx231xx.h"
+#include "cx231xx-dif.h"
+#define TUNER_MODE_FM_RADIO 0
/******************************************************************************
-: BLOCK ARRANGEMENT :-
I2S block ----------------------|
@@ -50,6 +53,57 @@
[Video]
*******************************************************************************/
+/******************************************************************************
+ * VERVE REGISTER *
+ * *
+ ******************************************************************************/
+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);
+
+ cx231xx_capture_start(dev, 1, 2);
+
+ 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 };
+
+ cx231xx_capture_start(dev, 0, 2);
+ verve_write_byte(dev, 0x07, 0x14);
+ cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ 0x68, value, 4);
+}
/******************************************************************************
* A F E - B L O C K C O N T R O L functions *
@@ -258,7 +312,7 @@ int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode)
switch (mode) {
case AFE_MODE_LOW_IF:
- /* SetupAFEforLowIF(); */
+ cx231xx_Setup_AFE_for_LowIF(dev);
break;
case AFE_MODE_BASEBAND:
status = cx231xx_afe_setup_AFE_for_baseband(dev);
@@ -291,8 +345,15 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev,
int status = 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_RDE_253S:
+ case CX231XX_BOARD_CNXT_RDU_253S:
+ case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
+ case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
FLD_PWRDN_ENABLE_PLL)) {
@@ -483,6 +544,17 @@ 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);
}
+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;
+
+}
int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
{
@@ -521,9 +593,15 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
return status;
}
}
- status = cx231xx_set_decoder_video_input(dev,
+ 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,
CX231XX_VMUX_COMPOSITE1,
INPUT(input)->vmux);
+
break;
default:
cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n",
@@ -578,12 +656,12 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
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);
@@ -681,7 +759,9 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
case CX231XX_VMUX_CABLE:
default:
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:
/* Disable the use of DIF */
@@ -699,11 +779,11 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
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,
@@ -790,11 +870,11 @@ int cx231xx_set_decoder_video_input(struct cx231xx *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,
@@ -816,9 +896,21 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
/* Set VGA_SEL (for audio control) (bit 7-8) */
status = vid_blk_read_word(dev, AFE_CTRL, &value);
+ /*Set Func mode:01-DIF 10-baseband 11-YUV*/
+ value &= (~(FLD_FUNC_MODE));
+ value |= 0x800000;
+
value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2;
status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+ 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));
+ }
+
break;
}
@@ -840,6 +932,39 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
return status;
}
+void cx231xx_enable656(struct cx231xx *dev)
+{
+ u8 temp = 0;
+ int status;
+ /*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*/
+
+ status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
+ temp = temp|0x04;
+
+ status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);
+
+}
+EXPORT_SYMBOL_GPL(cx231xx_enable656);
+
+void cx231xx_disable656(struct cx231xx *dev)
+{
+ u8 temp = 0;
+ int status;
+
+
+ status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0x00);
+
+ status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
+ temp = temp&0xFB;
+
+ status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);
+}
+EXPORT_SYMBOL_GPL(cx231xx_disable656);
+
/*
* Handle any video-mode specific overrides that are different
* on a per video standards basis after touching the MODE_CTRL
@@ -868,12 +993,12 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
FLD_VACTIVE_CNT,
- 0x1E6000);
+ 0x1E7000);
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
FLD_V656BLANK_CNT,
- 0x1E000000);
+ 0x1C000000);
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
@@ -881,12 +1006,27 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
FLD_HBLANK_CNT,
cx231xx_set_field
(FLD_HBLANK_CNT, 0x79));
+
} else if (dev->norm & V4L2_STD_SECAM) {
cx231xx_info("do_mode_ctrl_overrides SECAM\n");
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,
+ 0x24));
/* Adjust the active video horizontal start point */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
@@ -899,7 +1039,21 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
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,
+ 0x24));
/* Adjust the active video horizontal start point */
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
@@ -907,11 +1061,28 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
FLD_HBLANK_CNT,
cx231xx_set_field
(FLD_HBLANK_CNT, 0x85));
+
}
return status;
}
+int cx231xx_unmute_audio(struct cx231xx *dev)
+{
+ return vid_blk_write_byte(dev, PATH1_VOL_CTL, 0x24);
+}
+EXPORT_SYMBOL_GPL(cx231xx_unmute_audio);
+
+int stopAudioFirmware(struct cx231xx *dev)
+{
+ return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x03);
+}
+
+int restartAudioFirmware(struct cx231xx *dev)
+{
+ return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x13);
+}
+
int cx231xx_set_audio_input(struct cx231xx *dev, u8 input)
{
int status = 0;
@@ -970,6 +1141,7 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
/* unmute all, AC97 in, independence mode
adr 08d0, data 0x00063073 */
+ status = vid_blk_write_word(dev, DL_CTL, 0x3000001);
status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073);
/* set AVC maximum threshold, adr 08d4, dat ffff0024 */
@@ -985,7 +1157,7 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
case AUDIO_INPUT_TUNER_TV:
default:
-
+ status = stopAudioFirmware(dev);
/* Setup SRC sources and clocks */
status = vid_blk_write_word(dev, BAND_OUT_SEL,
cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00) |
@@ -1013,18 +1185,32 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870);
/* setAudioStandard(_audio_standard); */
-
status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870);
- switch (dev->model) {
- case CX231XX_BOARD_CNXT_RDE_250:
- case CX231XX_BOARD_CNXT_RDU_250:
+
+ status = restartAudioFirmware(dev);
+
+ 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 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,
+ FLD_SIF_EN,
+ 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;
@@ -1049,18 +1235,6 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
return status;
}
-/* Set resolution of the video */
-int cx231xx_resolution_set(struct cx231xx *dev)
-{
- /* set horzontal scale */
- int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale);
- if (status)
- return status;
-
- /* set vertical scale */
- return vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale);
-}
-
/******************************************************************************
* C H I P Specific C O N T R O L functions *
******************************************************************************/
@@ -1094,34 +1268,350 @@ int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
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);
- }
+ 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_port_3);
+
+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)
+{
+ u8 status = 0;
+ u32 value = 0;
+ u16 i = 0;
+
+ value = 0x45005390;
+ status = vid_blk_write_word(dev, 0x104, value);
+
+ for (i = 0x100; i < 0x140; i++) {
+ status = vid_blk_read_word(dev, i, &value);
+ cx231xx_info("reg0x%x=0x%x\n", i, value);
+ i = i+3;
+ }
+
+ for (i = 0x300; i < 0x400; i++) {
+ status = vid_blk_read_word(dev, i, &value);
+ cx231xx_info("reg0x%x=0x%x\n", i, value);
+ i = i+3;
+ }
+
+ for (i = 0x400; i < 0x440; i++) {
+ status = vid_blk_read_word(dev, i, &value);
+ cx231xx_info("reg0x%x=0x%x\n", i, value);
+ 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);
+}
+
+void cx231xx_dump_SC_reg(struct cx231xx *dev)
+{
+ u8 value[4] = { 0, 0, 0, 0 };
+ int status = 0;
+ cx231xx_info("cx231xx_dump_SC_reg %s!\n", __TIME__);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG,
+ 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]);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1,
+ 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]);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1,
+ 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]);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1,
+ 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]);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2,
+ 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]);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
+ 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 status = 0;
+ u8 value = 0;
+
+
+
+ status = afe_read_byte(dev, ADC_STATUS2_CH3, &value);
+ value = (value & 0xFE)|0x01;
+ status = afe_write_byte(dev, ADC_STATUS2_CH3, value);
+
+ status = afe_read_byte(dev, ADC_STATUS2_CH3, &value);
+ value = (value & 0xFE)|0x00;
+ status = afe_write_byte(dev, ADC_STATUS2_CH3, value);
+
+
+/*
+ config colibri to lo-if mode
+
+ FIXME: ntf_mode = 2'b00 by default. But set 0x1 would reduce
+ the diff IF input by half,
+
+ for low-if agc defect
+*/
+
+ status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3, &value);
+ value = (value & 0xFC)|0x00;
+ status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, value);
+
+ status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
+ value = (value & 0xF9)|0x02;
+ status = afe_write_byte(dev, ADC_INPUT_CH3, value);
+
+ status = afe_read_byte(dev, ADC_FB_FRCRST_CH3, &value);
+ value = (value & 0xFB)|0x04;
+ status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, value);
+
+ status = afe_read_byte(dev, ADC_DCSERVO_DEM_CH3, &value);
+ value = (value & 0xFC)|0x03;
+ status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, value);
+
+ status = afe_read_byte(dev, ADC_CTRL_DAC1_CH3, &value);
+ value = (value & 0xFB)|0x04;
+ status = afe_write_byte(dev, ADC_CTRL_DAC1_CH3, value);
+
+ status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
+ value = (value & 0xF8)|0x06;
+ status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);
+
+ status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
+ value = (value & 0x8F)|0x40;
+ status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);
+
+ status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH3, &value);
+ value = (value & 0xDF)|0x20;
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_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 = 0x01; /* Device has a DIF if this function is called */
+ u32 standard = 0;
+ u8 value[4] = { 0, 0, 0, 0 };
+
+ 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);
+
+ /*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);
+
+ /* Get colibri offsets.*/
+ colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode,
+ standard);
+
+ cx231xx_info("colibri_carrier_offset=%d, standard=0x%x\n",
+ colibri_carrier_offset, standard);
+
+ /* Set the band Pass filter for DIF*/
+ 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;
+
+ if (mode == TUNER_MODE_FM_RADIO) {
+ colibri_carrier_offset = 1100000;
+ } 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 */
+ } else if (standerd & (V4L2_STD_PAL_D | V4L2_STD_PAL_I
+ | V4L2_STD_SECAM)) {
+ colibri_carrier_offset = 2100000; /*2.10MHz */
+ }
+
+ 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;
+
+ 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 (!(value[0] & I2C_DEMOD_EN)) {
- value[0] |= I2C_DEMOD_EN;
- status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
- PWR_CTL_EN, value, 4);
- }
+ 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);
}
- return status;
+ if_freq = (if_freq/100000)*100000;
+ if (if_freq < 3000000)
+ if_freq = 3000000;
+
+ 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);
+ }
+ }
}
/******************************************************************************
@@ -1132,6 +1622,7 @@ int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
{
int status = 0;
+
if (mode == V4L2_TUNER_RADIO) {
/* C2HH */
/* lo if big signal */
@@ -1174,6 +1665,7 @@ int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
VID_BLK_I2C_ADDRESS, 32,
AUD_IO_CTRL, 0, 31, 0x00000003);
} else if ((standard == V4L2_STD_PAL_I) |
+ (standard & V4L2_STD_PAL_D) |
(standard & V4L2_STD_SECAM)) {
/* C2HH setup */
/* lo if big signal */
@@ -1232,10 +1724,18 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard)
dev->norm = standard;
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:
+ case CX231XX_BOARD_HAUPPAUGE_EXETER:
func_mode = 0x03;
break;
+ case CX231XX_BOARD_CNXT_RDE_253S:
+ case CX231XX_BOARD_CNXT_RDU_253S:
+ func_mode = 0x01;
+ break;
default:
func_mode = 0x01;
}
@@ -1617,17 +2117,27 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
{
int status = 0;
u32 dwval;
-
+ 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);
dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
- V4L2_STD_SECAM_D))
- dwval |= 0x88000000;
- else
- dwval |= 0x44000000;
+ 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;
+ }
status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
@@ -1714,8 +2224,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
return 0;
}
- cx231xx_info(" setPowerMode::mode = %d\n", mode);
-
status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
4);
if (status < 0)
@@ -1761,7 +2269,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
case POLARIS_AVMODE_ANALOGT_TV:
- tmp &= (~PWR_DEMOD_EN);
+ tmp |= PWR_DEMOD_EN;
tmp |= (I2C_DEMOD_EN);
value[0] = (u8) tmp;
value[1] = (u8) (tmp >> 8);
@@ -1814,14 +2322,18 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
msleep(PWR_SLEEP_INTERVAL);
}
- if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
- (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 */
+ 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;
case POLARIS_AVMODE_DIGITAL:
@@ -1856,6 +2368,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
msleep(PWR_SLEEP_INTERVAL);
}
+ tmp &= (~PWR_AV_MODE);
tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN;
value[0] = (u8) tmp;
value[1] = (u8) (tmp >> 8);
@@ -1876,10 +2389,19 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
msleep(PWR_SLEEP_INTERVAL);
}
- if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
- (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 */
+ 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);
@@ -1913,9 +2435,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
4);
- cx231xx_info(" The data of PWR_CTL_EN register 0x74"
- "=0x%0x,0x%0x,0x%0x,0x%0x\n",
- value[0], value[1], value[2], value[3]);
return status;
}
@@ -2000,6 +2519,8 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask)
int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
{
int status = 0;
+ u32 value = 0;
+ u8 val[4] = { 0, 0, 0, 0 };
if (dev->udev->speed == USB_SPEED_HIGH) {
switch (media_type) {
@@ -2026,10 +2547,36 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
break;
case 4: /* ts1 */
- cx231xx_info("%s: set ts1 registers\n", __func__);
+ cx231xx_info("%s: set ts1 registers", __func__);
+
+ if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) {
+ 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");
status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
- status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
+ status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x010);
+ }
break;
+
case 6: /* ts1 parallel mode */
cx231xx_info("%s: set ts1 parrallel mode registers\n",
__func__);
@@ -2128,7 +2675,7 @@ EXPORT_SYMBOL_GPL(cx231xx_capture_start);
/*****************************************************************************
* G P I O B I T control functions *
******************************************************************************/
-int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
+int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val)
{
int status = 0;
@@ -2137,7 +2684,7 @@ int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
return status;
}
-int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
+int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val)
{
int status = 0;
@@ -2344,7 +2891,7 @@ int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data)
return status;
}
-int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 * buf)
+int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf)
{
u8 value = 0;
int status = 0;
@@ -2494,7 +3041,7 @@ int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev)
/* cx231xx_gpio_i2c_read
* Function to read data from gpio based I2C interface
*/
-int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
+int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
{
int status = 0;
int i = 0;
@@ -2538,7 +3085,7 @@ int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
/* cx231xx_gpio_i2c_write
* Function to write data to gpio based I2C interface
*/
-int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
+int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
{
int status = 0;
int i = 0;
OpenPOWER on IntegriCloud