in dvb-frontends/drx39xyj/drxj.c [9919:10417]
static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
{
int rc;
s32 freq = 0; /* KHz */
struct i2c_device_addr *dev_addr = NULL;
struct drxj_data *ext_attr = NULL;
u16 i = 0;
bool mirror_freq_spect_oob = false;
u16 trk_filter_value = 0;
struct drxjscu_cmd scu_cmd;
u16 set_param_parameters[3];
u16 cmd_result[2] = { 0, 0 };
s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
};
u8 mode_val[4] = { 2, 2, 0, 1 };
u8 pfi_coeffs[4][6] = {
{DRXJ_16TO8(-92), DRXJ_16TO8(-108), DRXJ_16TO8(100)}, /* TARGET_MODE = 0: PFI_A = -23/32; PFI_B = -54/32; PFI_C = 25/32; fg = 0.5 MHz (Att=26dB) */
{DRXJ_16TO8(-64), DRXJ_16TO8(-80), DRXJ_16TO8(80)}, /* TARGET_MODE = 1: PFI_A = -16/32; PFI_B = -40/32; PFI_C = 20/32; fg = 1.0 MHz (Att=28dB) */
{DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}, /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
{DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)} /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
};
u16 mode_index;
dev_addr = demod->my_i2c_dev_addr;
ext_attr = (struct drxj_data *) demod->my_ext_attr;
mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
/* Check parameters */
if (oob_param == NULL) {
/* power off oob module */
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_STOP;
scu_cmd.parameter_len = 0;
scu_cmd.result_len = 1;
scu_cmd.result = cmd_result;
rc = scu_command(dev_addr, &scu_cmd);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = set_orx_nsu_aox(demod, false);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
ext_attr->oob_power_on = false;
return 0;
}
freq = oob_param->frequency;
if ((freq < 70000) || (freq > 130000))
return -EIO;
freq = (freq - 50000) / 50;
{
u16 index = 0;
u16 remainder = 0;
u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
index = (u16) ((freq - 400) / 200);
remainder = (u16) ((freq - 400) % 200);
trk_filter_value =
trk_filtercfg[index] - (trk_filtercfg[index] -
trk_filtercfg[index +
1]) / 10 * remainder /
20;
}
/********/
/* Stop */
/********/
rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_STOP;
scu_cmd.parameter_len = 0;
scu_cmd.result_len = 1;
scu_cmd.result = cmd_result;
rc = scu_command(dev_addr, &scu_cmd);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/********/
/* Reset */
/********/
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_RESET;
scu_cmd.parameter_len = 0;
scu_cmd.result_len = 1;
scu_cmd.result = cmd_result;
rc = scu_command(dev_addr, &scu_cmd);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/**********/
/* SET_ENV */
/**********/
/* set frequency, spectrum inversion and data rate */
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
scu_cmd.parameter_len = 3;
/* 1-data rate;2-frequency */
switch (oob_param->standard) {
case DRX_OOB_MODE_A:
if (
/* signal is transmitted inverted */
((oob_param->spectrum_inverted == true) &&
/* and tuner is not mirroring the signal */
(!mirror_freq_spect_oob)) |
/* or */
/* signal is transmitted noninverted */
((oob_param->spectrum_inverted == false) &&
/* and tuner is mirroring the signal */
(mirror_freq_spect_oob))
)
set_param_parameters[0] =
SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
else
set_param_parameters[0] =
SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
break;
case DRX_OOB_MODE_B_GRADE_A:
if (
/* signal is transmitted inverted */
((oob_param->spectrum_inverted == true) &&
/* and tuner is not mirroring the signal */
(!mirror_freq_spect_oob)) |
/* or */
/* signal is transmitted noninverted */
((oob_param->spectrum_inverted == false) &&
/* and tuner is mirroring the signal */
(mirror_freq_spect_oob))
)
set_param_parameters[0] =
SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
else
set_param_parameters[0] =
SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
break;
case DRX_OOB_MODE_B_GRADE_B:
default:
if (
/* signal is transmitted inverted */
((oob_param->spectrum_inverted == true) &&
/* and tuner is not mirroring the signal */
(!mirror_freq_spect_oob)) |
/* or */
/* signal is transmitted noninverted */
((oob_param->spectrum_inverted == false) &&
/* and tuner is mirroring the signal */
(mirror_freq_spect_oob))
)
set_param_parameters[0] =
SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
else
set_param_parameters[0] =
SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
break;
}
set_param_parameters[1] = (u16) (freq & 0xFFFF);
set_param_parameters[2] = trk_filter_value;
scu_cmd.parameter = set_param_parameters;
scu_cmd.result_len = 1;
scu_cmd.result = cmd_result;
mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
rc = scu_command(dev_addr, &scu_cmd);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
} /* Write magic word to enable pdr reg write */
rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
} /* Write magic word to disable pdr reg write */
rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* ddc */
rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* nsu */
rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* initialization for target mode */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* Reset bits for timing and freq. recovery */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* PRE-Filter coefficients (PFI) */
rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/* NYQUIST-Filter coefficients (NYQ) */
for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
}
rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
/********/
/* Start */
/********/
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_START;
scu_cmd.parameter_len = 0;
scu_cmd.result_len = 1;
scu_cmd.result = cmd_result;
rc = scu_command(dev_addr, &scu_cmd);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = set_orx_nsu_aox(demod, true);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
ext_attr->oob_power_on = true;
return 0;
rw_error:
return rc;
}