- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->phase_correction_bypass = false;
- ext_attr->enable_cvbs_output = true;
- break;
- case DRX_STANDARD_FM:
- /* FM */
- cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_FM;
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2994, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re), ((u8 *)fm_taps_re), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im), ((u8 *)fm_taps_im), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM | ATV_TOP_STD_VID_POL_FM), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_MOD_CONTROL__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_CONT__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW | SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->phase_correction_bypass = true;
- ext_attr->enable_cvbs_output = false;
- break;
- case DRX_STANDARD_PAL_SECAM_BG:
- /* PAL/SECAM B/G */
- cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_B;
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 1820, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- } /* TODO check with IS */
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re), ((u8 *)bg_taps_re), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im), ((u8 *)bg_taps_im), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_BG | ATV_TOP_CR_CONT_CR_D_BG | ATV_TOP_CR_CONT_CR_I_BG), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG | ATV_TOP_STD_VID_POL_BG), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->phase_correction_bypass = false;
- ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
- ext_attr->enable_cvbs_output = true;
- break;
- case DRX_STANDARD_PAL_SECAM_DK:
- /* PAL/SECAM D/K */
- cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_DK;
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- } /* TODO check with IS */
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_DK | ATV_TOP_CR_CONT_CR_D_DK | ATV_TOP_CR_CONT_CR_I_DK), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK | ATV_TOP_STD_VID_POL_DK), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_DK, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->phase_correction_bypass = false;
- ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
- ext_attr->enable_cvbs_output = true;
- break;
- case DRX_STANDARD_PAL_SECAM_I:
- /* PAL/SECAM I */
- cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_I;
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- } /* TODO check with IS */
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_I | ATV_TOP_CR_CONT_CR_D_I | ATV_TOP_CR_CONT_CR_I_I), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I | ATV_TOP_STD_VID_POL_I), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_I, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->phase_correction_bypass = false;
- ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
- ext_attr->enable_cvbs_output = true;
- break;
- case DRX_STANDARD_PAL_SECAM_L:
- /* PAL/SECAM L with negative modulation */
- cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_L;
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- } /* TODO check with IS */
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- } /* TODO check with IS */
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_L | ATV_TOP_CR_CONT_CR_D_L | ATV_TOP_CR_CONT_CR_I_L), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L | ATV_TOP_STD_VID_POL_L), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM | SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE | SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->phase_correction_bypass = false;
- ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
- ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
- ext_attr->enable_cvbs_output = true;
- break;
- case DRX_STANDARD_PAL_SECAM_LP:
- /* PAL/SECAM L with positive modulation */
- cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_LP;
-
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_LP, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- } /* TODO check with IS */
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- } /* TODO check with IS */
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_LP | ATV_TOP_CR_CONT_CR_D_LP | ATV_TOP_CR_CONT_CR_I_LP), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP | ATV_TOP_STD_VID_POL_LP), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM | SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE | SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW), 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->phase_correction_bypass = false;
- ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
- ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
- ext_attr->enable_cvbs_output = true;
- break;
- default:
- return -EIO;
- }
-
- /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
- if (!ext_attr->has_lna) {
- rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x01, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_STANDARD__A, 0x002, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, 10248, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- ext_attr->iqm_rc_rate_ofs = 0x00200000L;
- rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON | IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- /* default: SIF in standby */
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, 0x080, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_FAGC_TH_RED__A, 10, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AAGC_CNT__A, 7, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_KI_CHANGE_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_ATV_LOCK__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BPC_KI_MIN__A, 531, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BP_REF_MIN__A, 100, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BP_REF_MAX__A, 260, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BP_LVL__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MIN__A, 2047, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* Override reset values with current shadow settings */
- rc = atv_update_config(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* Configure/restore AGC settings */
- rc = init_agc(demod);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = set_agc_if(demod, &(ext_attr->atv_if_agc_cfg), false);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = set_agc_rf(demod, &(ext_attr->atv_rf_agc_cfg), false);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
- cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
- SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
- cmd_scu.parameter_len = 1;
- cmd_scu.result_len = 1;
- cmd_scu.parameter = &cmd_param;
- cmd_scu.result = &cmd_result;
- rc = scu_command(dev_addr, &cmd_scu);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
- if (ext_attr->mfx == 0x03) {
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- } else {
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_IIR_CRIT__A, 225, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/* -------------------------------------------------------------------------- */
-
-/**
-* \fn int set_atv_channel ()
-* \brief Set ATV channel.
-* \param demod: instance of demod.
-* \return int.
-*
-* Not much needs to be done here, only start the SCU for NTSC/FM.
-* Mirrored channels are not expected in the RF domain, so IQM FS setting
-* doesn't need to be remembered.
-* The channel->mirror parameter is therefor ignored.
-*
-*/
-static int
-set_atv_channel(struct drx_demod_instance *demod,
- s32 tuner_freq_offset,
- struct drx_channel *channel, enum drx_standard standard)
-{
- struct drxjscu_cmd cmd_scu = { /* command */ 0,
- /* parameter_len */ 0,
- /* result_len */ 0,
- /* parameter */ NULL,
- /* result */ NULL
- };
- u16 cmd_result = 0;
- struct drxj_data *ext_attr = NULL;
- struct i2c_device_addr *dev_addr = NULL;
- int rc;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /*
- Program frequency shifter
- No need to account for mirroring on RF
- */
- if (channel->mirror == DRX_MIRROR_AUTO)
- ext_attr->mirror = DRX_MIRROR_NO;
- else
- ext_attr->mirror = channel->mirror;
-
- rc = set_frequency(demod, channel, tuner_freq_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* Start ATV SCU */
- cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
- SCU_RAM_COMMAND_CMD_DEMOD_START;
- cmd_scu.parameter_len = 0;
- cmd_scu.result_len = 1;
- cmd_scu.parameter = NULL;
- cmd_scu.result = &cmd_result;
- rc = scu_command(dev_addr, &cmd_scu);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
-/* if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
- {
- ext_attr->detectedRDS = (bool)false;
- }*/
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/* -------------------------------------------------------------------------- */
-
-/**
-* \fn int get_atv_channel ()
-* \brief Set ATV channel.
-* \param demod: instance of demod.
-* \param channel: pointer to channel data.
-* \param standard: NTSC or FM.
-* \return int.
-*
-* Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
-* Computes the frequency offset in te RF domain and adds it to
-* channel->frequency. Determines the value for channel->bandwidth.
-*
-*/
-static int
-get_atv_channel(struct drx_demod_instance *demod,
- struct drx_channel *channel, enum drx_standard standard)
-{
- s32 offset = 0;
- struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
- int rc;
-
- /* Bandwidth */
- channel->bandwidth = ((struct drxj_data *) demod->my_ext_attr)->curr_bandwidth;
-
- switch (standard) {
- case DRX_STANDARD_NTSC:
- case DRX_STANDARD_PAL_SECAM_BG:
- case DRX_STANDARD_PAL_SECAM_DK:
- case DRX_STANDARD_PAL_SECAM_I:
- case DRX_STANDARD_PAL_SECAM_L:
- {
- u16 measured_offset = 0;
-
- /* get measured frequency offset */
- rc = drxj_dap_read_reg16(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- /* Signed 8 bit register => sign extension needed */
- if ((measured_offset & 0x0080) != 0)
- measured_offset |= 0xFF80;
- offset +=
- (s32) (((s16) measured_offset) * 10);
- break;
- }
- case DRX_STANDARD_PAL_SECAM_LP:
- {
- u16 measured_offset = 0;
-
- /* get measured frequency offset */
- rc = drxj_dap_read_reg16(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- /* Signed 8 bit register => sign extension needed */
- if ((measured_offset & 0x0080) != 0)
- measured_offset |= 0xFF80;
- offset -=
- (s32) (((s16) measured_offset) * 10);
- }
- break;
- case DRX_STANDARD_FM:
- /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
- AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
- */
- /* No bandwidth know for FM */
- channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
- break;
- default:
- return -EIO;
- }
-
- channel->frequency -= offset;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/* -------------------------------------------------------------------------- */
-/**
-* \fn int get_atv_sig_strength()
-* \brief Retrieve signal strength for ATV & FM.
-* \param devmod Pointer to demodulator instance.
-* \param sig_quality Pointer to signal strength data; range 0, .. , 100.
-* \return int.
-* \retval 0 sig_strength contains valid data.
-* \retval -EIO Erroneous data, sig_strength equals 0.
-*
-* Taking into account:
-* * digital gain
-* * IF gain (not implemented yet, waiting for IF gain control by ucode)
-* * RF gain
-*
-* All weights (digital, if, rf) must add up to 100.
-*
-* TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
-* is not used ?
-*/
-static int
-get_atv_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- /* All weights must add up to 100 (%)
- TODO: change weights when IF ctrl is available */
- u32 digital_weight = 50; /* 0 .. 100 */
- u32 rf_weight = 50; /* 0 .. 100 */
- u32 if_weight = 0; /* 0 .. 100 */
-
- u16 digital_curr_gain = 0;
- u32 digital_max_gain = 0;
- u32 digital_min_gain = 0;
- u16 rf_curr_gain = 0;
- u32 rf_max_gain = 0x800; /* taken from ucode */
- u32 rf_min_gain = 0x7fff;
- u16 if_curr_gain = 0;
- u32 if_max_gain = 0x800; /* taken from ucode */
- u32 if_min_gain = 0x7fff;
-
- u32 digital_strength = 0; /* 0.. 100 */
- u32 rf_strength = 0; /* 0.. 100 */
- u32 if_strength = 0; /* 0.. 100 */
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- *sig_strength = 0;
-
- switch (ext_attr->standard) {
- case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
- case DRX_STANDARD_NTSC:
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &digital_curr_gain, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- digital_max_gain = 22512; /* taken from ucode */
- digital_min_gain = 2400; /* taken from ucode */
- break;
- case DRX_STANDARD_FM:
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &digital_curr_gain, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- digital_max_gain = 0x4ff; /* taken from ucode */
- digital_min_gain = 0; /* taken from ucode */
- break;
- default:
- return -EIO;
- break;
- }
- rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_curr_gain, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_curr_gain, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* clipping */
- if (digital_curr_gain >= digital_max_gain)
- digital_curr_gain = (u16)digital_max_gain;
- if (digital_curr_gain <= digital_min_gain)
- digital_curr_gain = (u16)digital_min_gain;
- if (if_curr_gain <= if_max_gain)
- if_curr_gain = (u16)if_max_gain;
- if (if_curr_gain >= if_min_gain)
- if_curr_gain = (u16)if_min_gain;
- if (rf_curr_gain <= rf_max_gain)
- rf_curr_gain = (u16)rf_max_gain;
- if (rf_curr_gain >= rf_min_gain)
- rf_curr_gain = (u16)rf_min_gain;
-
- /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
- of clipping at ADC */
-
- /* Compute signal strength (in %) per "gain domain" */
-
- /* Digital gain */
- /* TODO: ADC clipping not handled */
- digital_strength = (100 * (digital_max_gain - (u32) digital_curr_gain)) /
- (digital_max_gain - digital_min_gain);
-
- /* TODO: IF gain not implemented yet in microcode, check after impl. */
- if_strength = (100 * ((u32) if_curr_gain - if_max_gain)) /
- (if_min_gain - if_max_gain);
-
- /* Rf gain */
- /* TODO: ADC clipping not handled */
- rf_strength = (100 * ((u32) rf_curr_gain - rf_max_gain)) /
- (rf_min_gain - rf_max_gain);
-
- /* Compute a weighted signal strength (in %) */
- *sig_strength = (u16) (digital_weight * digital_strength +
- rf_weight * rf_strength + if_weight * if_strength);
- *sig_strength /= 100;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/* -------------------------------------------------------------------------- */
-/**
-* \fn int atv_sig_quality()
-* \brief Retrieve signal quality indication for ATV.
-* \param devmod Pointer to demodulator instance.
-* \param sig_quality Pointer to signal quality structure.
-* \return int.
-* \retval 0 sig_quality contains valid data.
-* \retval -EIO Erroneous data, sig_quality indicator equals 0.
-*
-*
-*/
-static int
-atv_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
-{
- struct i2c_device_addr *dev_addr = NULL;
- u16 quality_indicator = 0;
- int rc;
-
- dev_addr = demod->my_i2c_dev_addr;
-
- /* defined values for fields not used */
- sig_quality->MER = 0;
- sig_quality->pre_viterbi_ber = 0;
- sig_quality->post_viterbi_ber = 0;
- sig_quality->scale_factor_ber = 1;
- sig_quality->packet_error = 0;
- sig_quality->post_reed_solomon_ber = 0;
-
- /*
- Mapping:
- 0x000..0x080: strong signal => 80% .. 100%
- 0x080..0x700: weak signal => 30% .. 80%
- 0x700..0x7ff: no signal => 0% .. 30%
- */
-
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_CR_LOCK__A, &quality_indicator, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- quality_indicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
- if (quality_indicator <= 0x80) {
- sig_quality->indicator =
- 80 + ((20 * (0x80 - quality_indicator)) / 0x80);
- } else if (quality_indicator <= 0x700)
- sig_quality->indicator = 30 + ((50 * (0x700 - quality_indicator)) / (0x700 - 0x81));
- else
- sig_quality->indicator = (30 * (0x7FF - quality_indicator)) / (0x7FF - 0x701);
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/*== END ATV DATAPATH FUNCTIONS ==*/
-/*============================================================================*/
-
-/*===========================================================================*/
-/*===========================================================================*/
-/*== AUDIO DATAPATH FUNCTIONS ==*/
-/*===========================================================================*/
-/*===========================================================================*/
-
-/*
-* \brief Power up AUD.
-* \param demod instance of demodulator
-* \return int.
-*
-*/
-static int power_up_aud(struct drx_demod_instance *demod, bool set_standard)
-{
- enum drx_aud_standard aud_standard = DRX_AUD_STANDARD_AUTO;
- struct i2c_device_addr *dev_addr = NULL;
- int rc;
-
- dev_addr = demod->my_i2c_dev_addr;
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- /* setup TR interface: R/W mode, fifosize=8 */
- rc = drxj_dap_write_reg16(dev_addr, AUD_TOP_TR_MDE__A, 8, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if (set_standard) {
- rc = aud_ctrl_set_standard(demod, &aud_standard);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-#endif
-
-/*============================================================================*/
-
-/**
-* \brief Power up AUD.
-* \param demod instance of demodulator
-* \return int.
-*
-*/
-static int power_down_aud(struct drx_demod_instance *demod)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- ext_attr->aud_data.audio_is_active = false;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-#if 0
-/*============================================================================*/
-/**
-* \brief Get Modus data from audio RAM
-* \param demod instance of demodulator
-* \param pointer to modus
-* \return int.
-*
-*/
-static int aud_get_modus(struct drx_demod_instance *demod, u16 *modus)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- u16 r_modus = 0;
- u16 r_modus_hi = 0;
- u16 r_modus_lo = 0;
-
- if (modus == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* Modus register is combined in to RAM location */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_MODUS_HI__A, &r_modus_hi, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_MODUS_LO__A, &r_modus_lo, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- r_modus = ((r_modus_hi << 12) & AUD_DEM_RAM_MODUS_HI__M)
- | (((r_modus_lo & AUD_DEM_RAM_MODUS_LO__M)));
-
- *modus = r_modus;
-
- return 0;
-rw_error:
- return -EIO;
-
-}
-
-/*============================================================================*/
-/**
-* \brief Get audio RDS dat
-* \param demod instance of demodulator
-* \param pointer to struct drx_cfg_aud_rds * \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_rds(struct drx_demod_instance *demod, struct drx_cfg_aud_rds *status)
-{
- struct i2c_device_addr *addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- u16 r_rds_array_cnt_init = 0;
- u16 r_rds_array_cnt_check = 0;
- u16 r_rds_data = 0;
- u16 rds_data_cnt = 0;
-
- addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- if (status == NULL)
- return -EINVAL;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- status->valid = false;
-
- rc = drxj_dap_read_reg16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_init, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if (r_rds_array_cnt_init ==
- AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
- /* invalid data */
- return 0;
- }
-
- if (ext_attr->aud_data.rds_data_counter == r_rds_array_cnt_init) {
- /* no new data */
- return 0;
- }
-
- /* RDS is detected, as long as FM radio is selected assume
- RDS will be available */
- ext_attr->aud_data.rds_data_present = true;
-
- /* new data */
- /* read the data */
- for (rds_data_cnt = 0; rds_data_cnt < AUD_RDS_ARRAY_SIZE; rds_data_cnt++) {
- rc = drxj_dap_read_reg16(addr, AUD_DEM_RD_RDS_DATA__A, &r_rds_data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- status->data[rds_data_cnt] = r_rds_data;
- }
-
- rc = drxj_dap_read_reg16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_check, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if (r_rds_array_cnt_check == r_rds_array_cnt_init) {
- status->valid = true;
- ext_attr->aud_data.rds_data_counter = r_rds_array_cnt_check;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the current audio carrier detection status
-* \param demod instance of demodulator
-* \param pointer to aud_ctrl_get_status
-* \return int.
-*
-*/
-static int
-aud_ctrl_get_carrier_detect_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
-{
- struct drxj_data *ext_attr = NULL;
- struct i2c_device_addr *dev_addr = NULL;
- int rc;
- u16 r_data = 0;
-
- if (status == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* initialize the variables */
- status->carrier_a = false;
- status->carrier_b = false;
- status->nicam_status = DRX_AUD_NICAM_NOT_DETECTED;
- status->sap = false;
- status->stereo = false;
-
- /* read stereo sound mode indication */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RD_STATUS__A, &r_data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* carrier a detected */
- if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_A__M) == AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED)
- status->carrier_a = true;
-
- /* carrier b detected */
- if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_B__M) == AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED)
- status->carrier_b = true;
- /* nicam detected */
- if ((r_data & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
- AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
- if ((r_data & AUD_DEM_RD_STATUS_BAD_NICAM__M) == AUD_DEM_RD_STATUS_BAD_NICAM_OK)
- status->nicam_status = DRX_AUD_NICAM_DETECTED;
- else
- status->nicam_status = DRX_AUD_NICAM_BAD;
- }
-
- /* audio mode bilingual or SAP detected */
- if ((r_data & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) == AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP)
- status->sap = true;
-
- /* stereo detected */
- if ((r_data & AUD_DEM_RD_STATUS_STAT_STEREO__M) == AUD_DEM_RD_STATUS_STAT_STEREO_STEREO)
- status->stereo = true;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the current audio status parameters
-* \param demod instance of demodulator
-* \param pointer to aud_ctrl_get_status
-* \return int.
-*
-*/
-static int
-aud_ctrl_get_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
-{
- struct drxj_data *ext_attr = NULL;
- struct i2c_device_addr *dev_addr = NULL;
- struct drx_cfg_aud_rds rds = { false, {0} };
- int rc;
- u16 r_data = 0;
-
- if (status == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* carrier detection */
- rc = aud_ctrl_get_carrier_detect_status(demod, status);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* rds data */
- status->rds = false;
- rc = aud_ctrl_get_cfg_rds(demod, &rds);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- status->rds = ext_attr->aud_data.rds_data_present;
-
- /* fm_ident */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_FM_IDENT_VALUE__A, &r_data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- r_data >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
- status->fm_ident = (s8) r_data;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the current volume settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_cfg_aud_volume * \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- u16 r_volume = 0;
- u16 r_avc = 0;
- u16 r_strength_left = 0;
- u16 r_strength_right = 0;
-
- if (volume == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* volume */
- volume->mute = ext_attr->aud_data.volume.mute;
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, &r_volume, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- if (r_volume == 0) {
- volume->mute = true;
- volume->volume = ext_attr->aud_data.volume.volume;
- } else {
- volume->mute = false;
- volume->volume = ((r_volume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
- AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
- AUD_VOLUME_ZERO_DB;
- if (volume->volume < AUD_VOLUME_DB_MIN)
- volume->volume = AUD_VOLUME_DB_MIN;
- if (volume->volume > AUD_VOLUME_DB_MAX)
- volume->volume = AUD_VOLUME_DB_MAX;
- }
-
- /* automatic volume control */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AVC__A, &r_avc, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if ((r_avc & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF) {
- volume->avc_mode = DRX_AUD_AVC_OFF;
- } else {
- switch (r_avc & AUD_DSP_WR_AVC_AVC_DECAY__M) {
- case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
- volume->avc_mode = DRX_AUD_AVC_DECAYTIME_20MS;
- break;
- case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
- volume->avc_mode = DRX_AUD_AVC_DECAYTIME_8S;
- break;
- case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
- volume->avc_mode = DRX_AUD_AVC_DECAYTIME_4S;
- break;
- case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
- volume->avc_mode = DRX_AUD_AVC_DECAYTIME_2S;
- break;
- default:
- return -EIO;
- break;
- }
- }
-
- /* max attenuation */
- switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
- case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
- volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_12DB;
- break;
- case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
- volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_18DB;
- break;
- case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
- volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_24DB;
- break;
- default:
- return -EIO;
- break;
- }
-
- /* max gain */
- switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
- case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
- volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_0DB;
- break;
- case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
- volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_6DB;
- break;
- case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
- volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_12DB;
- break;
- default:
- return -EIO;
- break;
- }
-
- /* reference level */
- volume->avc_ref_level = (u16) ((r_avc & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
- AUD_DSP_WR_AVC_AVC_REF_LEV__B);
-
- /* read qpeak registers and calculate strength of left and right carrier */
- /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
- /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
- /* left carrier */
-
- /* QP vaues */
- /* left carrier */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_QPEAK_L__A, &r_strength_left, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- volume->strength_left = (((s16) log1_times100(r_strength_left)) -
- AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
-
- /* right carrier */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_QPEAK_R__A, &r_strength_right, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- volume->strength_right = (((s16) log1_times100(r_strength_right)) -
- AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set the current volume settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_cfg_aud_volume * \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- u16 w_volume = 0;
- u16 w_avc = 0;
-
- if (volume == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* volume */
- /* volume range from -60 to 12 (expressed in dB) */
- if ((volume->volume < AUD_VOLUME_DB_MIN) ||
- (volume->volume > AUD_VOLUME_DB_MAX))
- return -EINVAL;
-
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, &w_volume, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* clear the volume mask */
- w_volume &= (u16) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
- if (volume->mute == true)
- w_volume |= (u16)(0);
- else
- w_volume |= (u16)((volume->volume + AUD_VOLUME_ZERO_DB) << AUD_DSP_WR_VOLUME_VOL_MAIN__B);
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* automatic volume control */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AVC__A, &w_avc, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* clear masks that require writing */
- w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_ON__M;
- w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
-
- if (volume->avc_mode == DRX_AUD_AVC_OFF) {
- w_avc |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
- } else {
-
- w_avc |= (AUD_DSP_WR_AVC_AVC_ON_ON);
-
- /* avc decay */
- switch (volume->avc_mode) {
- case DRX_AUD_AVC_DECAYTIME_20MS:
- w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
- break;
- case DRX_AUD_AVC_DECAYTIME_8S:
- w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
- break;
- case DRX_AUD_AVC_DECAYTIME_4S:
- w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
- break;
- case DRX_AUD_AVC_DECAYTIME_2S:
- w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
- break;
- default:
- return -EINVAL;
- }
- }
-
- /* max attenuation */
- w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
- switch (volume->avc_max_atten) {
- case DRX_AUD_AVC_MAX_ATTEN_12DB:
- w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
- break;
- case DRX_AUD_AVC_MAX_ATTEN_18DB:
- w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
- break;
- case DRX_AUD_AVC_MAX_ATTEN_24DB:
- w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
- break;
- default:
- return -EINVAL;
- }
-
- /* max gain */
- w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
- switch (volume->avc_max_gain) {
- case DRX_AUD_AVC_MAX_GAIN_0DB:
- w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
- break;
- case DRX_AUD_AVC_MAX_GAIN_6DB:
- w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
- break;
- case DRX_AUD_AVC_MAX_GAIN_12DB:
- w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
- break;
- default:
- return -EINVAL;
- }
-
- /* avc reference level */
- if (volume->avc_ref_level > AUD_MAX_AVC_REF_LEVEL)
- return -EINVAL;
-
- w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
- w_avc |= (u16) (volume->avc_ref_level << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_AVC__A, w_avc, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* all done, store config in data structure */
- ext_attr->aud_data.volume = *volume;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the I2S settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_cfg_i2s_output * \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
- u16 w_i2s_config = 0;
- u16 r_i2s_freq = 0;
-
- if (output == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, &r_i2s_freq, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* I2S mode */
- switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
- case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
- output->mode = DRX_I2S_MODE_MASTER;
- break;
- case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
- output->mode = DRX_I2S_MODE_SLAVE;
- break;
- default:
- return -EIO;
- }
-
- /* I2S format */
- switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
- case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
- output->format = DRX_I2S_FORMAT_WS_ADVANCED;
- break;
- case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
- output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
- break;
- default:
- return -EIO;
- }
-
- /* I2S word length */
- switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
- case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
- output->word_length = DRX_I2S_WORDLENGTH_16;
- break;
- case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
- output->word_length = DRX_I2S_WORDLENGTH_32;
- break;
- default:
- return -EIO;
- }
-
- /* I2S polarity */
- switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
- case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
- output->polarity = DRX_I2S_POLARITY_LEFT;
- break;
- case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
- output->polarity = DRX_I2S_POLARITY_RIGHT;
- break;
- default:
- return -EIO;
- }
-
- /* I2S output enabled */
- if ((w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M) == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE)
- output->output_enable = true;
- else
- output->output_enable = false;
-
- if (r_i2s_freq > 0) {
- output->frequency = 6144UL * 48000 / r_i2s_freq;
- if (output->word_length == DRX_I2S_WORDLENGTH_16)
- output->frequency *= 2;
- } else {
- output->frequency = AUD_I2S_FREQUENCY_MAX;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set the I2S settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_cfg_i2s_output * \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
- u16 w_i2s_config = 0;
- u16 w_i2s_pads_data_da = 0;
- u16 w_i2s_pads_data_cl = 0;
- u16 w_i2s_pads_data_ws = 0;
- u32 w_i2s_freq = 0;
-
- if (output == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* I2S mode */
- w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
-
- switch (output->mode) {
- case DRX_I2S_MODE_MASTER:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
- break;
- case DRX_I2S_MODE_SLAVE:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
- break;
- default:
- return -EINVAL;
- }
-
- /* I2S format */
- w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
-
- switch (output->format) {
- case DRX_I2S_FORMAT_WS_ADVANCED:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
- break;
- case DRX_I2S_FORMAT_WS_WITH_DATA:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
- break;
- default:
- return -EINVAL;
- }
-
- /* I2S word length */
- w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
-
- switch (output->word_length) {
- case DRX_I2S_WORDLENGTH_16:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
- break;
- case DRX_I2S_WORDLENGTH_32:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
- break;
- default:
- return -EINVAL;
- }
-
- /* I2S polarity */
- w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
- switch (output->polarity) {
- case DRX_I2S_POLARITY_LEFT:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
- break;
- case DRX_I2S_POLARITY_RIGHT:
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
- break;
- default:
- return -EINVAL;
- }
-
- /* I2S output enabled */
- w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
- if (output->output_enable == true)
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
- else
- w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
-
- /*
- I2S frequency
-
- w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
-
- 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
- 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
- */
- if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
- output->frequency < AUD_I2S_FREQUENCY_MIN) {
- return -EINVAL;
- }
-
- w_i2s_freq = (6144UL * 48000UL) + (output->frequency >> 1);
- w_i2s_freq /= output->frequency;
-
- if (output->word_length == DRX_I2S_WORDLENGTH_16)
- w_i2s_freq *= 2;
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_I2S_CONFIG2__A, w_i2s_config, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, (u16)w_i2s_freq, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* configure I2S output pads for master or slave mode */
- rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if (output->mode == DRX_I2S_MODE_MASTER) {
- w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
- SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
- w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
- SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
- w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
- SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
- } else {
- w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
- SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
- w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
- SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
- w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
- SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_DA_CFG__A, w_i2s_pads_data_da, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_CL_CFG__A, w_i2s_pads_data_cl, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_WS_CFG__A, w_i2s_pads_data_ws, 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, SIO_TOP_COMM_KEY__PRE, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* all done, store config in data structure */
- ext_attr->aud_data.i2sdata = *output;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the Automatic Standard Select (ASS)
-* and Automatic Sound Change (ASC)
-* \param demod instance of demodulator
-* \param pointer to pDRXAudAutoSound_t
-* \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_auto_sound(struct drx_demod_instance *demod,
- enum drx_cfg_aud_auto_sound *auto_sound)
-{
- struct drxj_data *ext_attr = NULL;
- int rc;
- u16 r_modus = 0;
-
- if (auto_sound == NULL)
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = aud_get_modus(demod, &r_modus);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- switch (r_modus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
- AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
- case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
- case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
- *auto_sound =
- DRX_AUD_AUTO_SOUND_OFF;
- break;
- case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
- *auto_sound =
- DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
- break;
- case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
- *auto_sound =
- DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
- break;
- default:
- return -EIO;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set the Automatic Standard Select (ASS)
-* and Automatic Sound Change (ASC)
-* \param demod instance of demodulator
-* \param pointer to pDRXAudAutoSound_t
-* \return int.
-*
-*/
-static int
-aud_ctr_setl_cfg_auto_sound(struct drx_demod_instance *demod,
- enum drx_cfg_aud_auto_sound *auto_sound)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 r_modus = 0;
- u16 w_modus = 0;
-
- if (auto_sound == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = aud_get_modus(demod, &r_modus);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- w_modus = r_modus;
- /* clear ASS & ASC bits */
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_ASS__M;
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
-
- switch (*auto_sound) {
- case DRX_AUD_AUTO_SOUND_OFF:
- w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
- w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
- break;
- case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
- w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
- w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
- break;
- case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
- w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
- w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
- break;
- default:
- return -EINVAL;
- }
-
- if (w_modus != r_modus) {
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
- /* copy to data structure */
- ext_attr->aud_data.auto_sound = *auto_sound;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the Automatic Standard Select thresholds
-* \param demod instance of demodulator
-* \param pointer to pDRXAudASSThres_t
-* \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 thres_a2 = 0;
- u16 thres_btsc = 0;
- u16 thres_nicam = 0;
-
- if (thres == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_A2_THRSHLD__A, &thres_a2, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thres_btsc, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thres_nicam, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- thres->a2 = thres_a2;
- thres->btsc = thres_btsc;
- thres->nicam = thres_nicam;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the Automatic Standard Select thresholds
-* \param demod instance of demodulator
-* \param pointer to pDRXAudASSThres_t
-* \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- if (thres == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* update DRXK data structure with hardware values */
- ext_attr->aud_data.ass_thresholds = *thres;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get Audio Carrier settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_aud_carrier ** \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 w_modus = 0;
-
- u16 dco_a_hi = 0;
- u16 dco_a_lo = 0;
- u16 dco_b_hi = 0;
- u16 dco_b_lo = 0;
-
- u32 valA = 0;
- u32 valB = 0;
-
- u16 dc_lvl_a = 0;
- u16 dc_lvl_b = 0;
-
- u16 cm_thes_a = 0;
- u16 cm_thes_b = 0;
-
- if (carriers == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = aud_get_modus(demod, &w_modus);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* Behaviour of primary audio channel */
- switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
- case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
- carriers->a.opt = DRX_NO_CARRIER_MUTE;
- break;
- case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
- carriers->a.opt = DRX_NO_CARRIER_NOISE;
- break;
- default:
- return -EIO;
- break;
- }
-
- /* Behaviour of secondary audio channel */
- switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
- case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
- carriers->b.opt = DRX_NO_CARRIER_MUTE;
- break;
- case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
- carriers->b.opt = DRX_NO_CARRIER_NOISE;
- break;
- default:
- return -EIO;
- break;
- }
-
- /* frequency adjustment for primary & secondary audio channel */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_A_HI__A, &dco_a_hi, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_A_LO__A, &dco_a_lo, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_B_HI__A, &dco_b_hi, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_B_LO__A, &dco_b_lo, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- valA = (((u32) dco_a_hi) << 12) | ((u32) dco_a_lo & 0xFFF);
- valB = (((u32) dco_b_hi) << 12) | ((u32) dco_b_lo & 0xFFF);
-
- /* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
- carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
- carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
-
- /* DC level of the incoming FM signal on the primary
- & seconday sound channel */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dc_lvl_a, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dc_lvl_b, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* offset (kHz) = (dcLvl / 322) */
- carriers->a.shift = (DRX_U16TODRXFREQ(dc_lvl_a) / 322L);
- carriers->b.shift = (DRX_U16TODRXFREQ(dc_lvl_b) / 322L);
-
- /* Carrier detetcion threshold for primary & secondary channel */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cm_thes_a, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cm_thes_b, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- carriers->a.thres = cm_thes_a;
- carriers->b.thres = cm_thes_b;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set Audio Carrier settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_aud_carrier ** \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 w_modus = 0;
- u16 r_modus = 0;
- u16 dco_a_hi = 0;
- u16 dco_a_lo = 0;
- u16 dco_b_hi = 0;
- u16 dco_b_lo = 0;
- s32 valA = 0;
- s32 valB = 0;
-
- if (carriers == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- rc = aud_get_modus(demod, &r_modus);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- w_modus = r_modus;
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_A__M;
- /* Behaviour of primary audio channel */
- switch (carriers->a.opt) {
- case DRX_NO_CARRIER_MUTE:
- w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
- break;
- case DRX_NO_CARRIER_NOISE:
- w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
- break;
- default:
- return -EINVAL;
- break;
- }
-
- /* Behaviour of secondary audio channel */
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_B__M;
- switch (carriers->b.opt) {
- case DRX_NO_CARRIER_MUTE:
- w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
- break;
- case DRX_NO_CARRIER_NOISE:
- w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
- break;
- default:
- return -EINVAL;
- break;
- }
-
- /* now update the modus register */
- if (w_modus != r_modus) {
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-
- /* frequency adjustment for primary & secondary audio channel */
- valA = (s32) ((carriers->a.dco) * 1657L / 2);
- valB = (s32) ((carriers->b.dco) * 1657L / 2);
-
- dco_a_hi = (u16) ((valA >> 12) & 0xFFF);
- dco_a_lo = (u16) (valA & 0xFFF);
- dco_b_hi = (u16) ((valB >> 12) & 0xFFF);
- dco_b_lo = (u16) (valB & 0xFFF);
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_A_HI__A, dco_a_hi, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_A_LO__A, dco_a_lo, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_B_HI__A, dco_b_hi, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_B_LO__A, dco_b_lo, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* Carrier detetcion threshold for primary & secondary channel */
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* update DRXK data structure */
- ext_attr->aud_data.carriers = *carriers;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get I2S Source, I2S matrix and FM matrix
-* \param demod instance of demodulator
-* \param pointer to pDRXAudmixer_t
-* \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 src_i2s_matr = 0;
- u16 fm_matr = 0;
-
- if (mixer == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* Source Selctor */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
- case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
- mixer->source_i2s = DRX_AUD_SRC_MONO;
- break;
- case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
- mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_AB;
- break;
- case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
- mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_A;
- break;
- case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
- mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_B;
- break;
- default:
- return -EIO;
- }
-
- /* Matrix */
- switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
- case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
- mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_MONO;
- break;
- case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
- mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_STEREO;
- break;
- case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
- mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_A_MONO;
- break;
- case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
- mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_B_MONO;
- break;
- default:
- return -EIO;
- }
-
- /* FM Matrix */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- switch (fm_matr & AUD_DEM_WR_FM_MATRIX__M) {
- case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
- mixer->matrix_fm = DRX_AUD_FM_MATRIX_NO_MATRIX;
- break;
- case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
- mixer->matrix_fm = DRX_AUD_FM_MATRIX_GERMAN;
- break;
- case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
- mixer->matrix_fm = DRX_AUD_FM_MATRIX_KOREAN;
- break;
- case AUD_DEM_WR_FM_MATRIX_SOUND_A:
- mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_A;
- break;
- case AUD_DEM_WR_FM_MATRIX_SOUND_B:
- mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_B;
- break;
- default:
- return -EIO;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set I2S Source, I2S matrix and FM matrix
-* \param demod instance of demodulator
-* \param pointer to DRXAudmixer_t
-* \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 src_i2s_matr = 0;
- u16 fm_matr = 0;
-
- if (mixer == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* Source Selctor */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
-
- switch (mixer->source_i2s) {
- case DRX_AUD_SRC_MONO:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
- break;
- case DRX_AUD_SRC_STEREO_OR_AB:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
- break;
- case DRX_AUD_SRC_STEREO_OR_A:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
- break;
- case DRX_AUD_SRC_STEREO_OR_B:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
- break;
- default:
- return -EINVAL;
- }
-
- /* Matrix */
- src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
- switch (mixer->matrix_i2s) {
- case DRX_AUD_I2S_MATRIX_MONO:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
- break;
- case DRX_AUD_I2S_MATRIX_STEREO:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
- break;
- case DRX_AUD_I2S_MATRIX_A_MONO:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
- break;
- case DRX_AUD_I2S_MATRIX_B_MONO:
- src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
- break;
- default:
- return -EINVAL;
- }
- /* write the result */
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, src_i2s_matr, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* FM Matrix */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- fm_matr &= (u16) ~AUD_DEM_WR_FM_MATRIX__M;
- switch (mixer->matrix_fm) {
- case DRX_AUD_FM_MATRIX_NO_MATRIX:
- fm_matr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
- break;
- case DRX_AUD_FM_MATRIX_GERMAN:
- fm_matr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
- break;
- case DRX_AUD_FM_MATRIX_KOREAN:
- fm_matr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
- break;
- case DRX_AUD_FM_MATRIX_SOUND_A:
- fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
- break;
- case DRX_AUD_FM_MATRIX_SOUND_B:
- fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
- break;
- default:
- return -EINVAL;
- }
-
- /* Only write if ASS is off */
- if (ext_attr->aud_data.auto_sound == DRX_AUD_AUTO_SOUND_OFF) {
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, fm_matr, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-
- /* update the data structure with hardware state */
- ext_attr->aud_data.mixer = *mixer;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set AV Sync settings
-* \param demod instance of demodulator
-* \param pointer to DRXICfgAVSync_t
-* \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 w_aud_vid_sync = 0;
-
- if (av_sync == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* audio/video synchronisation */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_ON__M;
-
- if (*av_sync == DRX_AUD_AVSYNC_OFF)
- w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
- else
- w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
-
- w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
-
- switch (*av_sync) {
- case DRX_AUD_AVSYNC_NTSC:
- w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
- break;
- case DRX_AUD_AVSYNC_MONOCHROME:
- w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
- break;
- case DRX_AUD_AVSYNC_PAL_SECAM:
- w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
- break;
- case DRX_AUD_AVSYNC_OFF:
- /* OK */
- break;
- default:
- return -EINVAL;
- }
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_AV_SYNC__A, w_aud_vid_sync, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get AV Sync settings
-* \param demod instance of demodulator
-* \param pointer to DRXICfgAVSync_t
-* \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 w_aud_vid_sync = 0;
-
- if (av_sync == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* audio/video synchronisation */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if ((w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
- AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
- *av_sync = DRX_AUD_AVSYNC_OFF;
- return 0;
- }
-
- switch (w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
- case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
- *av_sync = DRX_AUD_AVSYNC_NTSC;
- break;
- case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
- *av_sync = DRX_AUD_AVSYNC_MONOCHROME;
- break;
- case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
- *av_sync = DRX_AUD_AVSYNC_PAL_SECAM;
- break;
- default:
- return -EIO;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get deviation mode
-* \param demod instance of demodulator
-* \param pointer to enum drx_cfg_aud_deviation * \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
-{
- u16 r_modus = 0;
- int rc;
-
- if (dev == NULL)
- return -EINVAL;
-
- rc = aud_get_modus(demod, &r_modus);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- switch (r_modus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
- case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
- *dev = DRX_AUD_DEVIATION_NORMAL;
- break;
- case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
- *dev = DRX_AUD_DEVIATION_HIGH;
- break;
- default:
- return -EIO;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get deviation mode
-* \param demod instance of demodulator
-* \param pointer to enum drx_cfg_aud_deviation * \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 w_modus = 0;
- u16 r_modus = 0;
-
- if (dev == NULL)
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- dev_addr = demod->my_i2c_dev_addr;
-
- rc = aud_get_modus(demod, &r_modus);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- w_modus = r_modus;
-
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
-
- switch (*dev) {
- case DRX_AUD_DEVIATION_NORMAL:
- w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
- break;
- case DRX_AUD_DEVIATION_HIGH:
- w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
- break;
- default:
- return -EINVAL;
- }
-
- /* now update the modus register */
- if (w_modus != r_modus) {
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
- /* store in drxk data struct */
- ext_attr->aud_data.deviation = *dev;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get Prescaler settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_cfg_aud_prescale * \return int.
-*
-*/
-static int
-aud_ctrl_get_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 r_max_fm_deviation = 0;
- u16 r_nicam_prescaler = 0;
-
- if (presc == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* read register data */
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, &r_nicam_prescaler, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_FM_PRESC__A, &r_max_fm_deviation, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* calculate max FM deviation */
- r_max_fm_deviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
- if (r_max_fm_deviation > 0) {
- presc->fm_deviation = 3600UL + (r_max_fm_deviation >> 1);
- presc->fm_deviation /= r_max_fm_deviation;
- } else {
- presc->fm_deviation = 380; /* kHz */
- }
-
- /* calculate NICAM gain from pre-scaler */
- /*
- nicam_gain = 20 * ( log10( preScaler / 16) )
- = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
-
- because log1_times100() cannot return negative numbers
- = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
-
- for 0.1dB resolution:
-
- nicam_gain = 200 * ( log10( preScaler / 16) )
- = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
- = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
-
- */
- r_nicam_prescaler >>= 8;
- if (r_nicam_prescaler <= 1)
- presc->nicam_gain = -241;
- else
- presc->nicam_gain = (s16)(((s32)(log1_times100(10 * r_nicam_prescaler * r_nicam_prescaler)) - (s32)(log1_times100(10 * 16 * 16))));
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set Prescaler settings
-* \param demod instance of demodulator
-* \param pointer to struct drx_cfg_aud_prescale * \return int.
-*
-*/
-static int
-aud_ctrl_set_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 w_max_fm_deviation = 0;
- u16 nicam_prescaler;
-
- if (presc == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* setting of max FM deviation */
- w_max_fm_deviation = (u16) (frac(3600UL, presc->fm_deviation, 0));
- w_max_fm_deviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
- if (w_max_fm_deviation >= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION)
- w_max_fm_deviation = AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
-
- /* NICAM Prescaler */
- if ((presc->nicam_gain >= -241) && (presc->nicam_gain <= 180)) {
- /* calculation
-
- prescaler = 16 * 10^( gd_b / 20 )
-
- minval of gd_b = -20*log( 16 ) = -24.1dB
-
- negative numbers not allowed for d_b2lin_times100, so
-
- prescaler = 16 * 10^( gd_b / 20 )
- = 10^( (gd_b / 20) + log10(16) )
- = 10^( (gd_b + 20log10(16)) / 20 )
-
- in 0.1dB
-
- = 10^( G0.1dB + 200log10(16)) / 200 )
-
- */
- nicam_prescaler = (u16)
- ((d_b2lin_times100(presc->nicam_gain + 241UL) + 50UL) / 100UL);
-
- /* clip result */
- if (nicam_prescaler > 127)
- nicam_prescaler = 127;
-
- /* shift before writing to register */
- nicam_prescaler <<= 8;
- } else {
- return -EINVAL;
- }
- /* end of setting NICAM Prescaler */
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, nicam_prescaler, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_FM_PRESC__A, w_max_fm_deviation, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- ext_attr->aud_data.prescale = *presc;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Beep
-* \param demod instance of demodulator
-* \param pointer to struct drx_aud_beep * \return int.
-*
-*/
-static int aud_ctrl_beep(struct drx_demod_instance *demod, struct drx_aud_beep *beep)
-{
- struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
- struct drxj_data *ext_attr = (struct drxj_data *) NULL;
- int rc;
- u16 the_beep = 0;
- u16 volume = 0;
- u32 frequency = 0;
-
- if (beep == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- if ((beep->volume > 0) || (beep->volume < -127))
- return -EINVAL;
-
- if (beep->frequency > 3000)
- return -EINVAL;
-
- volume = (u16) beep->volume + 127;
- the_beep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
-
- frequency = ((u32) beep->frequency) * 23 / 500;
- if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M)
- frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
- the_beep |= (u16) frequency;
-
- if (beep->mute == true)
- the_beep = 0;
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_BEEPER__A, the_beep, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Set an audio standard
-* \param demod instance of demodulator
-* \param pointer to enum drx_aud_standard * \return int.
-*
-*/
-static int
-aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- enum drx_standard current_standard = DRX_STANDARD_UNKNOWN;
- int rc;
- u16 w_standard = 0;
- u16 w_modus = 0;
- u16 r_modus = 0;
-
- bool mute_buffer = false;
- s16 volume_buffer = 0;
- u16 w_volume = 0;
-
- if (standard == NULL)
- return -EINVAL;
-
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, false);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- /* reset RDS data availability flag */
- ext_attr->aud_data.rds_data_present = false;
-
- /* we need to mute from here to avoid noise during standard switching */
- mute_buffer = ext_attr->aud_data.volume.mute;
- volume_buffer = ext_attr->aud_data.volume.volume;
-
- ext_attr->aud_data.volume.mute = true;
- /* restore data structure from DRX ExtAttr, call volume first to mute */
- rc = aud_ctrl_set_cfg_volume(demod, &ext_attr->aud_data.volume);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = aud_ctrl_set_cfg_carrier(demod, &ext_attr->aud_data.carriers);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = aud_ctrl_set_cfg_ass_thres(demod, &ext_attr->aud_data.ass_thresholds);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = aud_ctr_setl_cfg_auto_sound(demod, &ext_attr->aud_data.auto_sound);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = aud_ctrl_set_cfg_mixer(demod, &ext_attr->aud_data.mixer);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = aud_ctrl_set_cfg_av_sync(demod, &ext_attr->aud_data.av_sync);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = aud_ctrl_set_cfg_output_i2s(demod, &ext_attr->aud_data.i2sdata);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* get prescaler from presets */
- rc = aud_ctrl_set_cfg_prescale(demod, &ext_attr->aud_data.prescale);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- rc = aud_get_modus(demod, &r_modus);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- w_modus = r_modus;
-
- switch (*standard) {
- case DRX_AUD_STANDARD_AUTO:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
- break;
- case DRX_AUD_STANDARD_BTSC:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
- if (ext_attr->aud_data.btsc_detect == DRX_BTSC_MONO_AND_SAP)
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
- break;
- case DRX_AUD_STANDARD_A2:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
- break;
- case DRX_AUD_STANDARD_EIAJ:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
- break;
- case DRX_AUD_STANDARD_FM_STEREO:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
- break;
- case DRX_AUD_STANDARD_BG_FM:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
- break;
- case DRX_AUD_STANDARD_D_K1:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
- break;
- case DRX_AUD_STANDARD_D_K2:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
- break;
- case DRX_AUD_STANDARD_D_K3:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
- break;
- case DRX_AUD_STANDARD_BG_NICAM_FM:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
- break;
- case DRX_AUD_STANDARD_L_NICAM_AM:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
- break;
- case DRX_AUD_STANDARD_I_NICAM_FM:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
- break;
- case DRX_AUD_STANDARD_D_K_NICAM_FM:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
- break;
- case DRX_AUD_STANDARD_UNKNOWN:
- w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
- break;
- default:
- return -EIO;
- }
-
- if (*standard == DRX_AUD_STANDARD_AUTO) {
- /* we need the current standard here */
- current_standard = ext_attr->standard;
-
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
-
- if ((current_standard == DRX_STANDARD_PAL_SECAM_L) || (current_standard == DRX_STANDARD_PAL_SECAM_LP))
- w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
- else
- w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
-
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
- if (current_standard == DRX_STANDARD_NTSC)
- w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
- else
- w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
-
- }
-
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
-
- /* just get hardcoded deemphasis and activate here */
- if (ext_attr->aud_data.deemph == DRX_AUD_FM_DEEMPH_50US)
- w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
- else
- w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
-
- w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_BTSC__M;
- if (ext_attr->aud_data.btsc_detect == DRX_BTSC_STEREO)
- w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
- else
- w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
-
- if (w_modus != r_modus) {
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-
- rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_STANDARD_SEL__A, w_standard, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /**************************************************************************/
- /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard */
- /* detection, need to keep things very minimal here, but keep audio */
- /* buffers intact */
- /**************************************************************************/
- ext_attr->aud_data.volume.mute = mute_buffer;
- if (ext_attr->aud_data.volume.mute == false) {
- w_volume |= (u16) ((volume_buffer + AUD_VOLUME_ZERO_DB) <<
- AUD_DSP_WR_VOLUME_VOL_MAIN__B);
- rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-
- /* write standard selected */
- ext_attr->aud_data.audio_standard = *standard;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief Get the current audio standard
-* \param demod instance of demodulator
-* \param pointer to enum drx_aud_standard * \return int.
-*
-*/
-static int
-aud_ctrl_get_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
- u16 r_data = 0;
-
- if (standard == NULL)
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
-
- /* power up */
- if (ext_attr->aud_data.audio_is_active == false) {
- rc = power_up_aud(demod, true);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->aud_data.audio_is_active = true;
- }
-
- *standard = DRX_AUD_STANDARD_UNKNOWN;
-
- rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RD_STANDARD_RES__A, &r_data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* return OK if the detection is not ready yet */
- if (r_data >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
- *standard = DRX_AUD_STANDARD_NOT_READY;
- return 0;
- }
-
- /* detection done, return correct standard */
- switch (r_data) {
- /* no standard detected */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
- *standard = DRX_AUD_STANDARD_UNKNOWN;
- break;
- /* standard is KOREA(A2) */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
- *standard = DRX_AUD_STANDARD_A2;
- break;
- /* standard is EIA-J (Japan) */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
- *standard = DRX_AUD_STANDARD_EIAJ;
- break;
- /* standard is BTSC-stereo */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
- *standard = DRX_AUD_STANDARD_BTSC;
- break;
- /* standard is BTSC-mono (SAP) */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
- *standard = DRX_AUD_STANDARD_BTSC;
- break;
- /* standard is FM radio */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
- *standard = DRX_AUD_STANDARD_FM_STEREO;
- break;
- /* standard is BG FM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
- *standard = DRX_AUD_STANDARD_BG_FM;
- break;
- /* standard is DK-1 FM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
- *standard = DRX_AUD_STANDARD_D_K1;
- break;
- /* standard is DK-2 FM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
- *standard = DRX_AUD_STANDARD_D_K2;
- break;
- /* standard is DK-3 FM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
- *standard = DRX_AUD_STANDARD_D_K3;
- break;
- /* standard is BG-NICAM FM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
- *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
- break;
- /* standard is L-NICAM AM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
- *standard = DRX_AUD_STANDARD_L_NICAM_AM;
- break;
- /* standard is I-NICAM FM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
- *standard = DRX_AUD_STANDARD_I_NICAM_FM;
- break;
- /* standard is DK-NICAM FM */
- case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
- *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
- break;
- default:
- *standard = DRX_AUD_STANDARD_UNKNOWN;
- }
-
- return 0;
-rw_error:
- return -EIO;
-
-}
-
-/*============================================================================*/
-/**
-* \brief Retreive lock status in case of FM standard
-* \param demod instance of demodulator
-* \param pointer to lock status
-* \return int.
-*
-*/
-static int
-fm_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
-{
- struct drx_aud_status status;
- int rc;
-
- /* Check detection of audio carriers */
- rc = aud_ctrl_get_carrier_detect_status(demod, &status);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* locked if either primary or secondary carrier is detected */
- if ((status.carrier_a == true) || (status.carrier_b == true))
- *lock_stat = DRX_LOCKED;
- else
- *lock_stat = DRX_NOT_LOCKED;
-
- return 0;
-
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-/**
-* \brief retreive signal quality in case of FM standard
-* \param demod instance of demodulator
-* \param pointer to signal quality
-* \return int.
-*
-* Only the quality indicator field is will be supplied.
-* This will either be 0% or 100%, nothing in between.
-*
-*/
-static int
-fm_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
-{
- enum drx_lock_status lock_status = DRX_NOT_LOCKED;
- int rc;
-
- rc = fm_lock_status(demod, &lock_status);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- if (lock_status == DRX_LOCKED)
- sig_quality->indicator = 100;
- else
- sig_quality->indicator = 0;
-
- return 0;
-
-rw_error:
- return -EIO;
-}
-
-/*===========================================================================*/
-/*== END AUDIO DATAPATH FUNCTIONS ==*/
-/*===========================================================================*/
-
-/*============================================================================*/
-/*============================================================================*/
-/*== OOB DATAPATH FUNCTIONS ==*/
-/*============================================================================*/
-/*============================================================================*/
-/**
-* \fn int get_oob_lock_status ()
-* \brief Get OOB lock status.
-* \param dev_addr I2C address
- \ oob_lock OOB lock status.
-* \return int.
-*
-* Gets OOB lock status
-*
-*/
-static int
-get_oob_lock_status(struct drx_demod_instance *demod,
- struct i2c_device_addr *dev_addr, enum drx_lock_status *oob_lock)
-{
- struct drxjscu_cmd scu_cmd;
- int rc;
- u16 cmd_result[2];
- u16 oob_lock_state;
-
- *oob_lock = DRX_NOT_LOCKED;
-
- scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
- SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
- scu_cmd.result_len = 2;
- scu_cmd.result = cmd_result;
- scu_cmd.parameter_len = 0;
-
- rc = scu_command(dev_addr, &scu_cmd);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if (scu_cmd.result[1] < 0x4000) {
- /* 0x00 NOT LOCKED */
- *oob_lock = DRX_NOT_LOCKED;
- } else if (scu_cmd.result[1] < 0x8000) {
- /* 0x40 DEMOD LOCKED */
- *oob_lock = DRXJ_OOB_SYNC_LOCK;
- } else if (scu_cmd.result[1] < 0xC000) {
- /* 0x80 DEMOD + OOB LOCKED (system lock) */
- oob_lock_state = scu_cmd.result[1] & 0x00FF;
-
- if (oob_lock_state & 0x0008)
- *oob_lock = DRXJ_OOB_SYNC_LOCK;
- else if ((oob_lock_state & 0x0002) && (oob_lock_state & 0x0001))
- *oob_lock = DRXJ_OOB_AGC_LOCK;
- } else {
- /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
- *oob_lock = DRX_NEVER_LOCK;
- }
-
- /* *oob_lock = scu_cmd.result[1]; */
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int get_oob_symbol_rate_offset ()
-* \brief Get OOB Symbol rate offset. Unit is [ppm]
-* \param dev_addr I2C address
-* \ Symbol Rate Offset OOB parameter.
-* \return int.
-*
-* Gets OOB frequency offset
-*
-*/
-static int
-get_oob_symbol_rate_offset(struct i2c_device_addr *dev_addr, s32 *symbol_rate_offset)
-{
-/* offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm] */
-/* offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm] */
-/* after reconfiguration: */
-/* offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm] */
-/* shift symbol rate left by 5 without lossing information */
-/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
-/* shift 10^6 left by 6 without loosing information */
-/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
-/* trim 12656250/15625 = 810 */
-/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm] */
-/* offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm] */
- int rc;
- s32 timing_offset = 0;
- u32 unsigned_timing_offset = 0;
- s32 division_factor = 810;
- u16 data = 0;
- u32 symbol_rate = 0;
- bool negative = false;
-
- *symbol_rate_offset = 0;
- /* read data rate */
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
- symbol_rate = 1024000; /* bps */
- break;
- case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
- symbol_rate = 772000; /* bps */
- break;
- case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
- symbol_rate = 1544000; /* bps */
- break;
- default:
- return -EIO;
- }
-
- rc = drxj_dap_read_reg16(dev_addr, ORX_CON_CTI_DTI_R__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- /* convert data to positive and keep information about sign */
- if ((data & 0x8000) == 0x8000) {
- if (data == 0x8000)
- unsigned_timing_offset = 32768;
- else
- unsigned_timing_offset = 0x00007FFF & (u32) (-data);
- negative = true;
- } else
- unsigned_timing_offset = (u32) data;
-
- symbol_rate = symbol_rate >> 5;
- unsigned_timing_offset = (unsigned_timing_offset * symbol_rate);
- unsigned_timing_offset = frac(unsigned_timing_offset, 256, FRAC_ROUND);
- unsigned_timing_offset = frac(unsigned_timing_offset,
- division_factor, FRAC_ROUND);
- if (negative)
- timing_offset = (s32) unsigned_timing_offset;
- else
- timing_offset = -(s32) unsigned_timing_offset;
-
- *symbol_rate_offset = timing_offset;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int get_oob_freq_offset ()
-* \brief Get OOB lock status.
-* \param dev_addr I2C address
-* \ freq_offset OOB frequency offset.
-* \return int.
-*
-* Gets OOB frequency offset
-*
-*/
-static int
-get_oob_freq_offset(struct drx_demod_instance *demod, s32 *freq_offset)
-{
- struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
- struct i2c_device_addr *dev_addr = NULL;
- int rc;
- u16 data = 0;
- u16 rot = 0;
- u16 symbol_rate_reg = 0;
- u32 symbol_rate = 0;
- s32 coarse_freq_offset = 0;
- s32 fine_freq_offset = 0;
- s32 fine_sign = 1;
- s32 coarse_sign = 1;
- u32 data64hi = 0;
- u32 data64lo = 0;
- u32 temp_freq_offset = 0;
-
- /* check arguments */
- if ((demod == NULL) || (freq_offset == NULL))
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- common_attr = (struct drx_common_attr *) demod->my_common_attr;
-
- *freq_offset = 0;
-
- /* read sign (spectrum inversion) */
- rc = drxj_dap_read_reg16(dev_addr, ORX_FWP_IQM_FRQ_W__A, &rot, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* read frequency offset */
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_FRQ_OFFSET__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- /* find COARSE frequency offset */
- /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
- if (data & 0x8000) {
- data = (0xffff - data + 1);
- coarse_sign = -1;
- }
- mult32(data, (common_attr->sys_clock_freq * 1000) / 6, &data64hi,
- &data64lo);
- temp_freq_offset = (((data64lo >> 21) & 0x7ff) | (data64hi << 11));
-
- /* get value in KHz */
- coarse_freq_offset = coarse_sign * frac(temp_freq_offset, 1000, FRAC_ROUND); /* KHz */
- /* read data rate */
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbol_rate_reg, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- switch (symbol_rate_reg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
- symbol_rate = 1024000;
- break;
- case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
- symbol_rate = 772000;
- break;
- case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
- case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
- symbol_rate = 1544000;
- break;
- default:
- return -EIO;
- }
-
- /* find FINE frequency offset */
- /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
- rc = drxj_dap_read_reg16(dev_addr, ORX_CON_CPH_FRQ_R__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
- fine_freq_offset = (symbol_rate >> 5);
- if (data & 0x8000) {
- fine_freq_offset *= 0xffff - data + 1; /* Hz */
- fine_sign = -1;
- } else {
- fine_freq_offset *= data; /* Hz */
- }
- /* Left to divide with 8192 (2^13) */
- fine_freq_offset = frac(fine_freq_offset, 8192, FRAC_ROUND);
- /* and to divide with 1000 to get KHz */
- fine_freq_offset = fine_sign * frac(fine_freq_offset, 1000, FRAC_ROUND); /* KHz */
-
- if ((rot & 0x8000) == 0x8000)
- *freq_offset = -(coarse_freq_offset + fine_freq_offset);
- else
- *freq_offset = (coarse_freq_offset + fine_freq_offset);
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int get_oob_frequency ()
-* \brief Get OOB frequency (Unit:KHz).
-* \param dev_addr I2C address
-* \ frequency OOB frequency parameters.
-* \return int.
-*
-* Gets OOB frequency
-*
-*/
-static int
-get_oob_frequency(struct drx_demod_instance *demod, s32 *frequency)
-{
- struct i2c_device_addr *dev_addr = NULL;
- int rc;
- u16 data = 0;
- s32 freq_offset = 0;
- s32 freq = 0;
-
- dev_addr = demod->my_i2c_dev_addr;
-
- *frequency = 0; /* KHz */
-
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- freq = (s32) ((s32) data * 50 + 50000L);
-
- rc = get_oob_freq_offset(demod, &freq_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- *frequency = freq + freq_offset;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int get_oobmer ()
-* \brief Get OOB MER.
-* \param dev_addr I2C address
- \ MER OOB parameter in dB.
-* \return int.
-*
-* Gets OOB MER. Table for MER is in Programming guide.
-*
-*/
-static int get_oobmer(struct i2c_device_addr *dev_addr, u32 *mer)
-{
- int rc;
- u16 data = 0;
-
- *mer = 0;
- /* READ MER */
- rc = drxj_dap_read_reg16(dev_addr, ORX_EQU_MER_MER_R__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- switch (data) {
- case 0: /* fall through */
- case 1:
- *mer = 39;
- break;
- case 2:
- *mer = 33;
- break;
- case 3:
- *mer = 29;
- break;
- case 4:
- *mer = 27;
- break;
- case 5:
- *mer = 25;
- break;
- case 6:
- *mer = 23;
- break;
- case 7:
- *mer = 22;
- break;
- case 8:
- *mer = 21;
- break;
- case 9:
- *mer = 20;
- break;
- case 10:
- *mer = 19;
- break;
- case 11:
- *mer = 18;
- break;
- case 12:
- *mer = 17;
- break;
- case 13: /* fall through */
- case 14:
- *mer = 16;
- break;
- case 15: /* fall through */
- case 16:
- *mer = 15;
- break;
- case 17: /* fall through */
- case 18:
- *mer = 14;
- break;
- case 19: /* fall through */
- case 20:
- *mer = 13;
- break;
- case 21: /* fall through */
- case 22:
- *mer = 12;
- break;
- case 23: /* fall through */
- case 24: /* fall through */
- case 25:
- *mer = 11;
- break;
- case 26: /* fall through */
- case 27: /* fall through */
- case 28:
- *mer = 10;
- break;
- case 29: /* fall through */
- case 30: /* fall through */
- case 31: /* fall through */
- case 32:
- *mer = 9;
- break;
- case 33: /* fall through */
- case 34: /* fall through */
- case 35: /* fall through */
- case 36:
- *mer = 8;
- break;
- case 37: /* fall through */
- case 38: /* fall through */
- case 39: /* fall through */
- case 40:
- *mer = 7;
- break;
- case 41: /* fall through */
- case 42: /* fall through */
- case 43: /* fall through */
- case 44: /* fall through */
- case 45:
- *mer = 6;
- break;
- case 46: /* fall through */
- case 47: /* fall through */
- case 48: /* fall through */
- case 49: /* fall through */
- case 50: /* fall through */
- *mer = 5;
- break;
- case 51: /* fall through */
- case 52: /* fall through */
- case 53: /* fall through */
- case 54: /* fall through */
- case 55: /* fall through */
- case 56: /* fall through */
- case 57:
- *mer = 4;
- break;
- case 58: /* fall through */
- case 59: /* fall through */
- case 60: /* fall through */
- case 61: /* fall through */
- case 62: /* fall through */
- case 63:
- *mer = 0;
- break;
- default:
- *mer = 0;
- break;
- }
- return 0;
-rw_error:
- return -EIO;
-}
-#endif
-
-/**
-* \fn int set_orx_nsu_aox()
-* \brief Configure OrxNsuAox for OOB
-* \param demod instance of demodulator.
-* \param active
-* \return int.
-*/
-static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
-{
- struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
- int rc;
- u16 data = 0;
-
- /* Configure NSU_AOX */
- rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- if (!active)
- data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
- else
- data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
- rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int ctrl_set_oob()
-* \brief Set OOB channel to be used.
-* \param demod instance of demodulator
-* \param oob_param OOB parameters for channel setting.
-* \frequency should be in KHz
-* \return int.
-*
-* Accepts only. Returns error otherwise.
-* Demapper value is written after scu_command START
-* because START command causes COMM_EXEC transition
-* from 0 to 1 which causes all registers to be
-* overwritten with initial value
-*
-*/
-
-/* Nyquist filter impulse response */
-#define IMPULSE_COSINE_ALPHA_0_3 {-3, -4, -1, 6, 10, 7, -5, -20, -25, -10, 29, 79, 123, 140} /*sqrt raised-cosine filter with alpha=0.3 */
-#define IMPULSE_COSINE_ALPHA_0_5 { 2, 0, -2, -2, 2, 5, 2, -10, -20, -14, 20, 74, 125, 145} /*sqrt raised-cosine filter with alpha=0.5 */
-#define IMPULSE_COSINE_ALPHA_RO_0_5 { 0, 0, 1, 2, 3, 0, -7, -15, -16, 0, 34, 77, 114, 128} /*full raised-cosine filter with alpha=0.5 (receiver only) */
-
-/* Coefficients for the nyquist fitler (total: 27 taps) */
-#define NYQFILTERLEN 27
-
-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 -EIO;
-}
-
-#if 0
-
-/**
-* \fn int ctrl_get_oob()
-* \brief Set modulation standard to be used.
-* \param demod instance of demodulator
-* \param oob_status OOB status parameters.
-* \return int.
-*/
-static int
-ctrl_get_oob(struct drx_demod_instance *demod, struct drxoob_status *oob_status)
-{
- int rc;
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- u16 data = 0;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* check arguments */
- if (oob_status == NULL)
- return -EINVAL;
-
- if (!ext_attr->oob_power_on)
- return -EIO;
-
- rc = drxj_dap_read_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_DGN_KI__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = drxj_dap_read_reg16(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- rc = get_oob_lock_status(demod, dev_addr, &oob_status->lock);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = get_oob_frequency(demod, &oob_status->frequency);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = get_oobmer(dev_addr, &oob_status->mer);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = get_oob_symbol_rate_offset(dev_addr, &oob_status->symbol_rate_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int ctrl_set_cfg_oob_pre_saw()
-* \brief Configure PreSAW treshold value
-* \param cfg_data Pointer to configuration parameter
-* \return Error code
-*/
-static int
-ctrl_set_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- if (cfg_data == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, *cfg_data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->oob_pre_saw = *cfg_data;
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int ctrl_get_cfg_oob_pre_saw()
-* \brief Configure PreSAW treshold value
-* \param cfg_data Pointer to configuration parameter
-* \return Error code
-*/
-static int
-ctrl_get_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
-{
- struct drxj_data *ext_attr = NULL;
-
- if (cfg_data == NULL)
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- *cfg_data = ext_attr->oob_pre_saw;
-
- return 0;
-}
-
-/**
-* \fn int ctrl_set_cfg_oob_lo_power()
-* \brief Configure LO Power value
-* \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
-*/
-static int
-ctrl_set_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
-
- if (cfg_data == NULL)
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, *cfg_data, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- ext_attr->oob_lo_pow = *cfg_data;
- return 0;
-rw_error:
- return -EIO;
-}
-
-/**
-* \fn int ctrl_get_cfg_oob_lo_power()
-* \brief Configure LO Power value
-* \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
-*/
-static int
-ctrl_get_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
-{
- struct drxj_data *ext_attr = NULL;
-
- if (cfg_data == NULL)
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- *cfg_data = ext_attr->oob_lo_pow;
-
- return 0;
-}
-#endif
-/*============================================================================*/
-/*== END OOB DATAPATH FUNCTIONS ==*/
-/*============================================================================*/
-
-/*=============================================================================
- ===== MC command related functions ==========================================
- ===========================================================================*/
-
-/*=============================================================================
- ===== ctrl_set_channel() ==========================================================
- ===========================================================================*/
-/**
-* \fn int ctrl_set_channel()
-* \brief Select a new transmission channel.
-* \param demod instance of demod.
-* \param channel Pointer to channel data.
-* \return int.
-*
-* In case the tuner module is not used and in case of NTSC/FM the pogrammer
-* must tune the tuner to the centre frequency of the NTSC/FM channel.
-*
-*/
-static int
-ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
-{
- int rc;
- s32 tuner_freq_offset = 0;
- s32 intermediate_freq = 0;
- struct drxj_data *ext_attr = NULL;
- struct i2c_device_addr *dev_addr = NULL;
- enum drx_standard standard = DRX_STANDARD_UNKNOWN;
- struct drx_common_attr *common_attr = NULL;
-#ifndef DRXJ_VSB_ONLY
- u32 min_symbol_rate = 0;
- u32 max_symbol_rate = 0;
- int bandwidth_temp = 0;
- int bandwidth = 0;
-#endif
- /*== check arguments ======================================================*/
- if ((demod == NULL) || (channel == NULL))
- return -EINVAL;
-
- common_attr = (struct drx_common_attr *) demod->my_common_attr;
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- standard = ext_attr->standard;
-
- /* check valid standards */
- switch (standard) {
- case DRX_STANDARD_8VSB:
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A:
- case DRX_STANDARD_ITU_B:
- case DRX_STANDARD_ITU_C:
-#endif /* DRXJ_VSB_ONLY */
-#if 0
- case DRX_STANDARD_NTSC:
- case DRX_STANDARD_FM:
- case DRX_STANDARD_PAL_SECAM_BG:
- case DRX_STANDARD_PAL_SECAM_DK:
- case DRX_STANDARD_PAL_SECAM_I:
- case DRX_STANDARD_PAL_SECAM_L:
- case DRX_STANDARD_PAL_SECAM_LP:
-#endif
- break;
- case DRX_STANDARD_UNKNOWN:
- default:
- return -EINVAL;
- }
-
- /* check bandwidth QAM annex B, NTSC and 8VSB */
- if ((standard == DRX_STANDARD_ITU_B) ||
- (standard == DRX_STANDARD_8VSB) ||
- (standard == DRX_STANDARD_NTSC)) {
- switch (channel->bandwidth) {
- case DRX_BANDWIDTH_6MHZ:
- case DRX_BANDWIDTH_UNKNOWN: /* fall through */
- channel->bandwidth = DRX_BANDWIDTH_6MHZ;
- break;
- case DRX_BANDWIDTH_8MHZ: /* fall through */
- case DRX_BANDWIDTH_7MHZ: /* fall through */
- default:
- return -EINVAL;
- }
- }
-#if 0
- if (standard == DRX_STANDARD_PAL_SECAM_BG) {
- switch (channel->bandwidth) {
- case DRX_BANDWIDTH_7MHZ: /* fall through */
- case DRX_BANDWIDTH_8MHZ:
- /* ok */
- break;
- case DRX_BANDWIDTH_6MHZ: /* fall through */
- case DRX_BANDWIDTH_UNKNOWN: /* fall through */
- default:
- return -EINVAL;
- }
- }
- /* check bandwidth PAL/SECAM */
- if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
- (standard == DRX_STANDARD_PAL_SECAM_DK) ||
- (standard == DRX_STANDARD_PAL_SECAM_I) ||
- (standard == DRX_STANDARD_PAL_SECAM_L) ||
- (standard == DRX_STANDARD_PAL_SECAM_LP)) {
- switch (channel->bandwidth) {
- case DRX_BANDWIDTH_8MHZ:
- case DRX_BANDWIDTH_UNKNOWN: /* fall through */
- channel->bandwidth = DRX_BANDWIDTH_8MHZ;
- break;
- case DRX_BANDWIDTH_6MHZ: /* fall through */
- case DRX_BANDWIDTH_7MHZ: /* fall through */
- default:
- return -EINVAL;
- }
- }
-#endif
-
- /* For QAM annex A and annex C:
- -check symbolrate and constellation
- -derive bandwidth from symbolrate (input bandwidth is ignored)
- */
-#ifndef DRXJ_VSB_ONLY
- if ((standard == DRX_STANDARD_ITU_A) ||
- (standard == DRX_STANDARD_ITU_C)) {
- struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
- int bw_rolloff_factor = 0;
-
- bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
- min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
- max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
- /* config SMA_TX pin to SAW switch mode */
- rc = ctrl_set_uio_cfg(demod, &uio_cfg);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- if (channel->symbolrate < min_symbol_rate ||
- channel->symbolrate > max_symbol_rate) {
- return -EINVAL;
- }
-
- switch (channel->constellation) {
- case DRX_CONSTELLATION_QAM16: /* fall through */
- case DRX_CONSTELLATION_QAM32: /* fall through */
- case DRX_CONSTELLATION_QAM64: /* fall through */
- case DRX_CONSTELLATION_QAM128: /* fall through */
- case DRX_CONSTELLATION_QAM256:
- bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
- bandwidth = bandwidth_temp / 100;
-
- if ((bandwidth_temp % 100) >= 50)
- bandwidth++;
-
- if (bandwidth <= 6100000) {
- channel->bandwidth = DRX_BANDWIDTH_6MHZ;
- } else if ((bandwidth > 6100000)
- && (bandwidth <= 7100000)) {
- channel->bandwidth = DRX_BANDWIDTH_7MHZ;
- } else if (bandwidth > 7100000) {
- channel->bandwidth = DRX_BANDWIDTH_8MHZ;
- }
- break;
- default:
- return -EINVAL;
- }
- }
-
- /* For QAM annex B:
- -check constellation
- */
- if (standard == DRX_STANDARD_ITU_B) {
- switch (channel->constellation) {
- case DRX_CONSTELLATION_AUTO:
- case DRX_CONSTELLATION_QAM256:
- case DRX_CONSTELLATION_QAM64:
- break;
- default:
- return -EINVAL;
- }
-
- switch (channel->interleavemode) {
- case DRX_INTERLEAVEMODE_I128_J1:
- case DRX_INTERLEAVEMODE_I128_J1_V2:
- case DRX_INTERLEAVEMODE_I128_J2:
- case DRX_INTERLEAVEMODE_I64_J2:
- case DRX_INTERLEAVEMODE_I128_J3:
- case DRX_INTERLEAVEMODE_I32_J4:
- case DRX_INTERLEAVEMODE_I128_J4:
- case DRX_INTERLEAVEMODE_I16_J8:
- case DRX_INTERLEAVEMODE_I128_J5:
- case DRX_INTERLEAVEMODE_I8_J16:
- case DRX_INTERLEAVEMODE_I128_J6:
- case DRX_INTERLEAVEMODE_I128_J7:
- case DRX_INTERLEAVEMODE_I128_J8:
- case DRX_INTERLEAVEMODE_I12_J17:
- case DRX_INTERLEAVEMODE_I5_J4:
- case DRX_INTERLEAVEMODE_B52_M240:
- case DRX_INTERLEAVEMODE_B52_M720:
- case DRX_INTERLEAVEMODE_UNKNOWN:
- case DRX_INTERLEAVEMODE_AUTO:
- break;
- default:
- return -EINVAL;
- }
- }
-
- if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
- /* SAW SW, user UIO is used for switchable SAW */
- struct drxuio_data uio1 = { DRX_UIO1, false };
-
- switch (channel->bandwidth) {
- case DRX_BANDWIDTH_8MHZ:
- uio1.value = true;
- break;
- case DRX_BANDWIDTH_7MHZ:
- uio1.value = false;
- break;
- case DRX_BANDWIDTH_6MHZ:
- uio1.value = false;
- break;
- case DRX_BANDWIDTH_UNKNOWN:
- default:
- return -EINVAL;
- }
-
- rc = ctrl_uio_write(demod, &uio1);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
-#endif /* DRXJ_VSB_ONLY */
- rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- tuner_freq_offset = 0;
- intermediate_freq = demod->my_common_attr->intermediate_freq;
-
- /*== Setup demod for specific standard ====================================*/
- switch (standard) {
- case DRX_STANDARD_8VSB:
- if (channel->mirror == DRX_MIRROR_AUTO)
- ext_attr->mirror = DRX_MIRROR_NO;
- else
- ext_attr->mirror = channel->mirror;
- rc = set_vsb(demod);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = set_frequency(demod, channel, tuner_freq_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#if 0
- case DRX_STANDARD_NTSC: /* fallthrough */
- case DRX_STANDARD_FM: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_LP:
- if (channel->mirror == DRX_MIRROR_AUTO)
- ext_attr->mirror = DRX_MIRROR_NO;
- else
- ext_attr->mirror = channel->mirror;
- rc = set_atv_channel(demod, tuner_freq_offset, channel, standard);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#endif
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A: /* fallthrough */
- case DRX_STANDARD_ITU_B: /* fallthrough */
- case DRX_STANDARD_ITU_C:
- rc = set_qam_channel(demod, channel, tuner_freq_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#endif
- case DRX_STANDARD_UNKNOWN:
- default:
- return -EIO;
- }
-
- /* flag the packet error counter reset */
- ext_attr->reset_pkt_err_acc = true;
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-#if 0
-/*=============================================================================
- ===== ctrl_get_channel() ==========================================================
- ===========================================================================*/
-/**
-* \fn int ctrl_get_channel()
-* \brief Retreive parameters of current transmission channel.
-* \param demod Pointer to demod instance.
-* \param channel Pointer to channel data.
-* \return int.
-*/
-static int
-ctrl_get_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
- enum drx_lock_status lock_status = DRX_NOT_LOCKED;
- enum drx_standard standard = DRX_STANDARD_UNKNOWN;
- struct drx_common_attr *common_attr = NULL;
- s32 intermediate_freq = 0;
- s32 ctl_freq_offset = 0;
- u32 iqm_rc_rate_lo = 0;
- u32 adc_frequency = 0;
-#ifndef DRXJ_VSB_ONLY
- int bandwidth_temp = 0;
- int bandwidth = 0;
-#endif
-
- /* check arguments */
- if ((demod == NULL) || (channel == NULL))
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- standard = ext_attr->standard;
- common_attr = (struct drx_common_attr *) demod->my_common_attr;
-
- /* initialize channel fields */
- channel->mirror = DRX_MIRROR_UNKNOWN;
- channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
- channel->priority = DRX_PRIORITY_UNKNOWN;
- channel->coderate = DRX_CODERATE_UNKNOWN;
- channel->guard = DRX_GUARD_UNKNOWN;
- channel->fftmode = DRX_FFTMODE_UNKNOWN;
- channel->classification = DRX_CLASSIFICATION_UNKNOWN;
- channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
- channel->constellation = DRX_CONSTELLATION_UNKNOWN;
- channel->symbolrate = 0;
- channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
- channel->carrier = DRX_CARRIER_UNKNOWN;
- channel->framemode = DRX_FRAMEMODE_UNKNOWN;
-/* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
- channel->ldpc = DRX_LDPC_UNKNOWN;
-
- intermediate_freq = common_attr->intermediate_freq;
-
- /* check lock status */
- rc = ctrl_lock_status(demod, &lock_status);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- if ((lock_status == DRX_LOCKED) || (lock_status == DRXJ_DEMOD_LOCK)) {
- rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &iqm_rc_rate_lo, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
-
- channel->symbolrate =
- frac28(adc_frequency, (iqm_rc_rate_lo + (1 << 23))) >> 7;
-
- switch (standard) {
- case DRX_STANDARD_8VSB:
- channel->bandwidth = DRX_BANDWIDTH_6MHZ;
- /* get the channel frequency */
- rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- channel->frequency -= ctl_freq_offset;
- /* get the channel constellation */
- channel->constellation = DRX_CONSTELLATION_AUTO;
- break;
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A:
- case DRX_STANDARD_ITU_B:
- case DRX_STANDARD_ITU_C:
- {
- /* get the channel frequency */
- rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- channel->frequency -= ctl_freq_offset;
-
- if (standard == DRX_STANDARD_ITU_B) {
- channel->bandwidth = DRX_BANDWIDTH_6MHZ;
- } else {
- /* annex A & C */
-
- u32 roll_off = 113; /* default annex C */
-
- if (standard == DRX_STANDARD_ITU_A)
- roll_off = 115;
-
- bandwidth_temp =
- channel->symbolrate * roll_off;
- bandwidth = bandwidth_temp / 100;
-
- if ((bandwidth_temp % 100) >= 50)
- bandwidth++;
-
- if (bandwidth <= 6000000) {
- channel->bandwidth =
- DRX_BANDWIDTH_6MHZ;
- } else if ((bandwidth > 6000000)
- && (bandwidth <= 7000000)) {
- channel->bandwidth =
- DRX_BANDWIDTH_7MHZ;
- } else if (bandwidth > 7000000) {
- channel->bandwidth =
- DRX_BANDWIDTH_8MHZ;
- }
- } /* if (standard == DRX_STANDARD_ITU_B) */
-
- {
- struct drxjscu_cmd cmd_scu = { 0, 0, 0, NULL, NULL };
- u16 cmd_result[3] = { 0, 0, 0 };
-
- cmd_scu.command =
- SCU_RAM_COMMAND_STANDARD_QAM |
- SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
- cmd_scu.parameter_len = 0;
- cmd_scu.result_len = 3;
- cmd_scu.parameter = NULL;
- cmd_scu.result = cmd_result;
- rc = scu_command(dev_addr, &cmd_scu);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- channel->interleavemode =
- (enum drx_interleave_mode) (cmd_scu.
- result[2]);
- }
-
- switch (ext_attr->constellation) {
- case DRX_CONSTELLATION_QAM256:
- channel->constellation =
- DRX_CONSTELLATION_QAM256;
- break;
- case DRX_CONSTELLATION_QAM128:
- channel->constellation =
- DRX_CONSTELLATION_QAM128;
- break;
- case DRX_CONSTELLATION_QAM64:
- channel->constellation =
- DRX_CONSTELLATION_QAM64;
- break;
- case DRX_CONSTELLATION_QAM32:
- channel->constellation =
- DRX_CONSTELLATION_QAM32;
- break;
- case DRX_CONSTELLATION_QAM16:
- channel->constellation =
- DRX_CONSTELLATION_QAM16;
- break;
- default:
- channel->constellation =
- DRX_CONSTELLATION_UNKNOWN;
- return -EIO;
- }
- }
- break;
-#endif
- case DRX_STANDARD_NTSC: /* fall trough */
- case DRX_STANDARD_PAL_SECAM_BG:
- case DRX_STANDARD_PAL_SECAM_DK:
- case DRX_STANDARD_PAL_SECAM_I:
- case DRX_STANDARD_PAL_SECAM_L:
- case DRX_STANDARD_PAL_SECAM_LP:
- case DRX_STANDARD_FM:
- rc = get_atv_channel(demod, channel, standard);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
- case DRX_STANDARD_UNKNOWN: /* fall trough */
- default:
- return -EIO;
- } /* switch ( standard ) */
-
- if (lock_status == DRX_LOCKED)
- channel->mirror = ext_attr->mirror;
- }
- /* if ( lock_status == DRX_LOCKED ) */
- return 0;
-rw_error:
- return -EIO;
-}
-#endif
-
-/*=============================================================================
- ===== SigQuality() ==========================================================
- ===========================================================================*/
-
-static u16
-mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
-{
- u16 indicator = 0;
-
- if (mer < min_mer) {
- indicator = 0;
- } else if (mer < threshold_mer) {
- if ((threshold_mer - min_mer) != 0)
- indicator = 25 * (mer - min_mer) / (threshold_mer - min_mer);
- } else if (mer < max_mer) {
- if ((max_mer - threshold_mer) != 0)
- indicator = 25 + 75 * (mer - threshold_mer) / (max_mer - threshold_mer);
- else
- indicator = 25;
- } else {
- indicator = 100;
- }
-
- return indicator;
-}
-
-/**
-* \fn int ctrl_sig_quality()
-* \brief Retreive signal quality form device.
-* \param devmod Pointer to demodulator instance.
-* \param sig_quality Pointer to signal quality data.
-* \return int.
-* \retval 0 sig_quality contains valid data.
-* \retval -EINVAL sig_quality is NULL.
-* \retval -EIO Erroneous data, sig_quality contains invalid data.
-
-*/
-static int
-ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
-{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
- enum drx_standard standard = DRX_STANDARD_UNKNOWN;
- enum drx_lock_status lock_status = DRX_NOT_LOCKED;
- u16 min_mer = 0;
- u16 max_mer = 0;
- u16 threshold_mer = 0;
-
- /* Check arguments */
- if ((sig_quality == NULL) || (demod == NULL))
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- standard = ext_attr->standard;
-
- /* get basic information */
- dev_addr = demod->my_i2c_dev_addr;
- rc = ctrl_lock_status(demod, &lock_status);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- switch (standard) {
- case DRX_STANDARD_8VSB:
-#ifdef DRXJ_SIGNAL_ACCUM_ERR
- rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-#else
- rc = get_vsb_post_rs_pck_err(dev_addr, &sig_quality->packet_error);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-#endif
- if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
- sig_quality->post_viterbi_ber = 500000;
- sig_quality->MER = 20;
- sig_quality->pre_viterbi_ber = 0;
- } else {
- /* PostViterbi is compute in steps of 10^(-6) */
- rc = get_vs_bpre_viterbi_ber(dev_addr, &sig_quality->pre_viterbi_ber);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = get_vs_bpost_viterbi_ber(dev_addr, &sig_quality->post_viterbi_ber);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = get_vsbmer(dev_addr, &sig_quality->MER);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- }
- min_mer = 20;
- max_mer = 360;
- threshold_mer = 145;
- sig_quality->post_reed_solomon_ber = 0;
- sig_quality->scale_factor_ber = 1000000;
- sig_quality->indicator =
- mer2indicator(sig_quality->MER, min_mer, threshold_mer,
- max_mer);
- break;
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A:
- case DRX_STANDARD_ITU_B:
- case DRX_STANDARD_ITU_C:
- rc = ctrl_get_qam_sig_quality(demod, sig_quality);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
- switch (ext_attr->constellation) {
- case DRX_CONSTELLATION_QAM256:
- sig_quality->MER = 210;
- break;
- case DRX_CONSTELLATION_QAM128:
- sig_quality->MER = 180;
- break;
- case DRX_CONSTELLATION_QAM64:
- sig_quality->MER = 150;
- break;
- case DRX_CONSTELLATION_QAM32:
- sig_quality->MER = 120;
- break;
- case DRX_CONSTELLATION_QAM16:
- sig_quality->MER = 90;
- break;
- default:
- sig_quality->MER = 0;
- return -EIO;
- }
- }
-
- switch (ext_attr->constellation) {
- case DRX_CONSTELLATION_QAM256:
- min_mer = 210;
- threshold_mer = 270;
- max_mer = 380;
- break;
- case DRX_CONSTELLATION_QAM64:
- min_mer = 150;
- threshold_mer = 210;
- max_mer = 380;
- break;
- case DRX_CONSTELLATION_QAM128:
- case DRX_CONSTELLATION_QAM32:
- case DRX_CONSTELLATION_QAM16:
- break;
- default:
- return -EIO;
- }
- sig_quality->indicator =
- mer2indicator(sig_quality->MER, min_mer, threshold_mer,
- max_mer);
- break;
-#endif
-#if 0
- case DRX_STANDARD_PAL_SECAM_BG:
- case DRX_STANDARD_PAL_SECAM_DK:
- case DRX_STANDARD_PAL_SECAM_I:
- case DRX_STANDARD_PAL_SECAM_L:
- case DRX_STANDARD_PAL_SECAM_LP:
- case DRX_STANDARD_NTSC:
- rc = atv_sig_quality(demod, sig_quality);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
- case DRX_STANDARD_FM:
- rc = fm_sig_quality(demod, sig_quality);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#endif
- default:
- return -EIO;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-
-/**
-* \fn int ctrl_lock_status()
-* \brief Retreive lock status .
-* \param dev_addr Pointer to demodulator device address.
-* \param lock_stat Pointer to lock status structure.
-* \return int.
-*
-*/
-static int
-ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
-{
- enum drx_standard standard = DRX_STANDARD_UNKNOWN;
- struct drxj_data *ext_attr = NULL;
- struct i2c_device_addr *dev_addr = NULL;
- struct drxjscu_cmd cmd_scu = { /* command */ 0,
- /* parameter_len */ 0,
- /* result_len */ 0,
- /* *parameter */ NULL,
- /* *result */ NULL
- };
- int rc;
- u16 cmd_result[2] = { 0, 0 };
- u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
-
- /* check arguments */
- if ((demod == NULL) || (lock_stat == NULL))
- return -EINVAL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- standard = ext_attr->standard;
-
- *lock_stat = DRX_NOT_LOCKED;
-
- /* define the SCU command code */
- switch (standard) {
- case DRX_STANDARD_8VSB:
- cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
- SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
- demod_lock |= 0x6;
- break;
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A:
- case DRX_STANDARD_ITU_B:
- case DRX_STANDARD_ITU_C:
- cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
- SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
- break;
-#endif
-#if 0
- case DRX_STANDARD_NTSC:
- case DRX_STANDARD_PAL_SECAM_BG:
- case DRX_STANDARD_PAL_SECAM_DK:
- case DRX_STANDARD_PAL_SECAM_I:
- case DRX_STANDARD_PAL_SECAM_L:
- case DRX_STANDARD_PAL_SECAM_LP:
- cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
- SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
- break;
- case DRX_STANDARD_FM:
- return fm_lock_status(demod, lock_stat);
-#endif
- case DRX_STANDARD_UNKNOWN: /* fallthrough */
- default:
- return -EIO;
- }
-
- /* define the SCU command paramters and execute the command */
- cmd_scu.parameter_len = 0;
- cmd_scu.result_len = 2;
- cmd_scu.parameter = NULL;
- cmd_scu.result = cmd_result;
- rc = scu_command(dev_addr, &cmd_scu);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-
- /* set the lock status */
- if (cmd_scu.result[1] < demod_lock) {
- /* 0x0000 NOT LOCKED */
- *lock_stat = DRX_NOT_LOCKED;
- } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
- *lock_stat = DRXJ_DEMOD_LOCK;
- } else if (cmd_scu.result[1] <
- SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
- /* 0x8000 DEMOD + FEC LOCKED (system lock) */
- *lock_stat = DRX_LOCKED;
- } else {
- /* 0xC000 NEVER LOCKED */
- /* (system will never be able to lock to the signal) */
- *lock_stat = DRX_NEVER_LOCK;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-
-#if 0
-/**
-* \fn int ctrl_constel()
-* \brief Retreive a constellation point via I2C.
-* \param demod Pointer to demodulator instance.
-* \param complex_nr Pointer to the structure in which to store the
- constellation point.
-* \return int.
-*/
-static int
-ctrl_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
-{
- int rc;
- enum drx_standard standard = DRX_STANDARD_UNKNOWN;
- /**< active standard */
-
- /* check arguments */
- if ((demod == NULL) || (complex_nr == NULL))
- return -EINVAL;
-
- /* read device info */
- standard = ((struct drxj_data *) demod->my_ext_attr)->standard;
-
- /* Read constellation point */
- switch (standard) {
- case DRX_STANDARD_8VSB:
- rc = ctrl_get_vsb_constel(demod, complex_nr);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A: /* fallthrough */
- case DRX_STANDARD_ITU_B: /* fallthrough */
- case DRX_STANDARD_ITU_C:
- rc = ctrl_get_qam_constel(demod, complex_nr);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#endif
- case DRX_STANDARD_UNKNOWN:
- default:
- return -EIO;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-#endif
-
-/*============================================================================*/
-
-/**
-* \fn int ctrl_set_standard()
-* \brief Set modulation standard to be used.
-* \param standard Modulation standard.
-* \return int.
-*
-* Setup stuff for the desired demodulation standard.
-* Disable and power down the previous selected demodulation standard
-*
-*/
-static int
-ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
-{
- struct drxj_data *ext_attr = NULL;
- int rc;
- enum drx_standard prev_standard;
-
- /* check arguments */
- if ((standard == NULL) || (demod == NULL))
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- prev_standard = ext_attr->standard;
-
- /*
- Stop and power down previous standard
- */
- switch (prev_standard) {
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A: /* fallthrough */
- case DRX_STANDARD_ITU_B: /* fallthrough */
- case DRX_STANDARD_ITU_C:
- rc = power_down_qam(demod, false);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#endif
- case DRX_STANDARD_8VSB:
- rc = power_down_vsb(demod, false);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#if 0
- case DRX_STANDARD_NTSC: /* fallthrough */
- case DRX_STANDARD_FM: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_LP:
- rc = power_down_atv(demod, prev_standard, false);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#endif
- case DRX_STANDARD_UNKNOWN:
- /* Do nothing */
- break;
- case DRX_STANDARD_AUTO: /* fallthrough */
- default:
- return -EINVAL;
- }
-
- /*
- Initialize channel independent registers
- Power up new standard
- */
- ext_attr->standard = *standard;
-
- switch (*standard) {
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A: /* fallthrough */
- case DRX_STANDARD_ITU_B: /* fallthrough */
- case DRX_STANDARD_ITU_C:
- do {
- u16 dummy;
- rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- } while (0);
- break;
-#endif
- case DRX_STANDARD_8VSB:
- rc = set_vsb_leak_n_gain(demod);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#if 0
- case DRX_STANDARD_NTSC: /* fallthrough */
- case DRX_STANDARD_FM: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
- case DRX_STANDARD_PAL_SECAM_LP:
- rc = set_atv_standard(demod, standard);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- rc = power_up_atv(demod, *standard);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
-#endif
- default:
- ext_attr->standard = DRX_STANDARD_UNKNOWN;
- return -EINVAL;
- break;
- }
-
- return 0;
-rw_error:
- /* Don't know what the standard is now ... try again */
- ext_attr->standard = DRX_STANDARD_UNKNOWN;
- return -EIO;
-}
-
-#if 0
-/*============================================================================*/
-
-/**
-* \fn int ctrl_get_standard()
-* \brief Get modulation standard currently used to demodulate.
-* \param standard Modulation standard.
-* \return int.
-*
-* Returns 8VSB, NTSC, QAM only.
-*
-*/
-static int
-ctrl_get_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
-{
- struct drxj_data *ext_attr = NULL;
- int rc;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
-
- /* check arguments */
- if (standard == NULL)
- return -EINVAL;
-
- *standard = ext_attr->standard;
- do {
- u16 dummy;
- rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- } while (0);
-
- return 0;
-rw_error:
- return -EIO;
-}
-
-/*============================================================================*/
-
-/**
-* \fn int ctrl_get_cfg_symbol_clock_offset()
-* \brief Get frequency offsets of STR.
-* \param pointer to s32.
-* \return int.
-*
-*/
-static int
-ctrl_get_cfg_symbol_clock_offset(struct drx_demod_instance *demod, s32 *rate_offset)
-{
- enum drx_standard standard = DRX_STANDARD_UNKNOWN;
- int rc;
- struct drxj_data *ext_attr = NULL;
-
- /* check arguments */
- if (rate_offset == NULL)
- return -EINVAL;
-
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- standard = ext_attr->standard;
-
- switch (standard) {
- case DRX_STANDARD_8VSB: /* fallthrough */
-#ifndef DRXJ_VSB_ONLY
- case DRX_STANDARD_ITU_A: /* fallthrough */
- case DRX_STANDARD_ITU_B: /* fallthrough */
- case DRX_STANDARD_ITU_C:
-#endif
- rc = get_str_freq_offset(demod, rate_offset);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
- break;
- case DRX_STANDARD_NTSC:
- case DRX_STANDARD_UNKNOWN:
- default:
- return -EINVAL;
- }
-
- return 0;
-rw_error:
- return -EIO;
-}
-#endif
-
-/*============================================================================*/
-
-static void drxj_reset_mode(struct drxj_data *ext_attr)
-{
- /* Initialize default AFE configuartion for QAM */
- if (ext_attr->has_lna) {
- /* IF AGC off, PGA active */
-#ifndef DRXJ_VSB_ONLY
- ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
- ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
- ext_attr->qam_pga_cfg = 140 + (11 * 13);
-#endif
- ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
- ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
- ext_attr->vsb_pga_cfg = 140 + (11 * 13);
- } else {
- /* IF AGC on, PGA not active */
-#ifndef DRXJ_VSB_ONLY
- ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
- ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
- ext_attr->qam_if_agc_cfg.min_output_level = 0;
- ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
- ext_attr->qam_if_agc_cfg.speed = 3;
- ext_attr->qam_if_agc_cfg.top = 1297;
- ext_attr->qam_pga_cfg = 140;
-#endif
- ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
- ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
- ext_attr->vsb_if_agc_cfg.min_output_level = 0;
- ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
- ext_attr->vsb_if_agc_cfg.speed = 3;
- ext_attr->vsb_if_agc_cfg.top = 1024;
- ext_attr->vsb_pga_cfg = 140;
- }
- /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
- /* mc has not used them */
-#ifndef DRXJ_VSB_ONLY
- ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
- ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
- ext_attr->qam_rf_agc_cfg.min_output_level = 0;
- ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
- ext_attr->qam_rf_agc_cfg.speed = 3;
- ext_attr->qam_rf_agc_cfg.top = 9500;
- ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
- ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
- ext_attr->qam_pre_saw_cfg.reference = 0x07;
- ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
-#endif
- /* Initialize default AFE configuartion for VSB */
- ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
- ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
- ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
- ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
- ext_attr->vsb_rf_agc_cfg.speed = 3;
- ext_attr->vsb_rf_agc_cfg.top = 9500;
- ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
- ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
- ext_attr->vsb_pre_saw_cfg.reference = 0x07;
- ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;