From b6c4065eef7ce18d29870cbcf979e7d8c803c551 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 9 Mar 2014 07:34:51 -0300 Subject: [PATCH] [media] drx-j: get rid of dead code There are large chunks of code at drx-j that aren't used. Most of them are due to analog TV support. Well, just enabling them won't make analog support work, as devices with DRX and analog support requires an extra chip (avf4910). We don't have drivers for it, nor the current device that uses this frontend has support for analog TV. So, let's just get rid of this code. If latter needed, this patch can easily be reverted from git history. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drx39xyj/drxj.c | 10769 ++---------------- 1 file changed, 1128 insertions(+), 9641 deletions(-) diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index a8fd53b612ae..e8c890800904 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -1028,13 +1028,6 @@ ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode); static int power_down_aud(struct drx_demod_instance *demod); -#if 0 -static int power_up_aud(struct drx_demod_instance *demod, bool set_standard); - -static int -aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard); -#endif - static int ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw); @@ -1047,97 +1040,6 @@ ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain /*============================================================================*/ /*============================================================================*/ -#if 0 -/** -* \fn void mult32(u32 a, u32 b, u32 *h, u32 *l) -* \brief 32bitsx32bits signed multiplication -* \param a 32 bits multiplicant, typecast from signed to unisgned -* \param b 32 bits multiplier, typecast from signed to unisgned -* \param h pointer to high part 64 bits result, typecast from signed to unisgned -* \param l pointer to low part 64 bits result -* -* For the 2n+n addition a + b: -* if a >= 0, then h += 0 (sign extension = 0) -* but if a < 0, then h += 2^n-1 ==> h -= 1. -* -* Also, if a + b < 2^n, then a + b >= a && a + b >= b -* but if a + b >= 2^n, then R = a + b - 2^n, -* and because a < 2^n && b < 2*n ==> R < a && R < b. -* Therefore, to detect overflow, simply compare the addition result with -* one of the operands; if the result is smaller, overflow has occurred and -* h must be incremented. -* -* Booth multiplication uses additions and subtractions to reduce the number -* of iterations. This is done by taking three subsequent bits abc and calculating -* the following multiplication factor: -2a + b + c. This factor is multiplied -* by the second operand and added to the result. Next, the first operand is -* shifted two bits (hence one of the three bits is reused) and the process -* repeated. The last iteration has only two bits left, but we simply add -* a zero to the end. -* -* Hence: (n=4) -* 1 * a = 0 * 4a + 1 * a -* 2 * a = 1 * 4a - 2 * a -* 3 * a = 1 * 4a - 1 * a -* -1 * a = 0 * 4a - 1 * a -* -5 * a = -1 * 4a - 1 * a -* -* etc. -* -* Note that the function is type size independent. Any unsigned integer type -* can be substituted for booth_t. -* -*/ - -#define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0) - -static void mult32(u32 a, u32 b, u32 *h, u32 *l) -{ - unsigned int i; - *h = *l = 0; - - /* n/2 iterations; shift operand a left two bits after each iteration. */ - /* This automatically appends a zero to the operand for the last iteration. */ - for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) { - /* Shift result left two bits */ - *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2)); - *l = (*l << 2); - - /* Take the first three bits of operand a for the Booth conversion: */ - /* 0, 7: do nothing */ - /* 1, 2: add b */ - /* 3 : add 2b */ - /* 4 : subtract 2b */ - /* 5, 6: subtract b */ - switch (a >> (sizeof(a) * 8 - 3)) { - case 3: - *l += b; - *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b); - case 1: - case 2: - *l += b; - *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b); - break; - case 4: - *l -= b; - *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l < - ((u32) - (- - ((s32) - b)))); - case 5: - case 6: - *l -= b; - *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l < - ((u32) - (- - ((s32) - b)))); - break; - } - } -} -#endif /*============================================================================*/ @@ -1331,108 +1233,6 @@ static u32 frac_times1e6(u32 N, u32 D) /*============================================================================*/ -#if 0 -/** -* \brief Compute: 100 * 10^( gd_b / 200 ). -* \param u32 gd_b Gain in 0.1dB -* \return u32 Gainfactor in 0.01 resolution -* -*/ -static u32 d_b2lin_times100(u32 gd_b) -{ - u32 result = 0; - u32 nr6d_b_steps = 0; - u32 remainder = 0; - u32 remainder_fac = 0; - - /* start with factors 2 (6.02dB) */ - nr6d_b_steps = gd_b * 1000UL / 60206UL; - if (nr6d_b_steps > 17) { - /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */ - return MAX_U32; - } - result = (1 << nr6d_b_steps); - - /* calculate remaining factor, - poly approximation of 10^(gd_b/200): - - y = 1E-04x2 + 0.0106x + 1.0026 - - max deviation < 0.005 for range x = [0 ... 60] - */ - remainder = ((gd_b * 1000UL) % 60206UL) / 1000UL; - /* using 1e-4 for poly calculation */ - remainder_fac = 1 * remainder * remainder; - remainder_fac += 106 * remainder; - remainder_fac += 10026; - - /* multiply by remaining factor */ - result *= remainder_fac; - - /* conversion from 1e-4 to 1e-2 */ - return (result + 50) / 100; -} - -#define FRAC_FLOOR 0 -#define FRAC_CEIL 1 -#define FRAC_ROUND 2 -/** -* \fn u32 frac( u32 N, u32 D, u16 RC ) -* \brief Compute: N/D. -* \param N nominator 32-bits. -* \param D denominator 32-bits. -* \param RC-result correction: 0-floor; 1-ceil; 2-round -* \return u32 -* \retval N/D, 32 bits -* -* If D=0 returns 0 -*/ -static u32 frac(u32 N, u32 D, u16 RC) -{ - u32 remainder = 0; - u32 frac = 0; - u16 bit_cnt = 32; - - if (D == 0) { - frac = 0; - remainder = 0; - - return frac; - } - - if (D > N) { - frac = 0; - remainder = N; - } else { - remainder = 0; - frac = N; - while (bit_cnt-- > 0) { - remainder <<= 1; - remainder |= ((frac & 0x80000000) >> 31); - frac <<= 1; - if (remainder < D) { - frac &= 0xFFFFFFFE; - } else { - remainder -= D; - frac |= 0x1; - } - } - - /* result correction if needed */ - if ((RC == FRAC_CEIL) && (remainder != 0)) { - /* ceil the result */ - /*(remainder is not zero -> value behind decimal point exists) */ - frac++; - } - if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) { - /* remainder is bigger from D/2 -> round the result */ - frac++; - } - } - - return frac; -} -#endif /** * \brief Values for NICAM prescaler gain. Computed from dB to integer @@ -3542,67 +3342,6 @@ rw_error: /*----------------------------------------------------------------------------*/ -#if 0 -/** -* \fn int ctrl_get_cfg_mpeg_output() -* \brief Get MPEG output configuration of the device. -* \param devmod Pointer to demodulator instance. -* \param cfg_data Pointer to MPEG output configuaration struct. -* \return int. -* -* Retrieve MPEG output configuartion. -* -*/ -static int -ctrl_get_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data) -{ - struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL); - struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL); - enum drx_lock_status lock_status = DRX_NOT_LOCKED; - int rc; - u32 rate_reg = 0; - u32 data64hi = 0; - u32 data64lo = 0; - - if (cfg_data == NULL) - return -EINVAL; - - dev_addr = demod->my_i2c_dev_addr; - common_attr = demod->my_common_attr; - - cfg_data->enable_mpeg_output = common_attr->mpeg_cfg.enable_mpeg_output; - cfg_data->insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte; - cfg_data->enable_parallel = common_attr->mpeg_cfg.enable_parallel; - cfg_data->invert_data = common_attr->mpeg_cfg.invert_data; - cfg_data->invert_err = common_attr->mpeg_cfg.invert_err; - cfg_data->invert_str = common_attr->mpeg_cfg.invert_str; - cfg_data->invert_val = common_attr->mpeg_cfg.invert_val; - cfg_data->invert_clk = common_attr->mpeg_cfg.invert_clk; - cfg_data->static_clk = common_attr->mpeg_cfg.static_clk; - cfg_data->bitrate = 0; - - rc = ctrl_lock_status(demod, &lock_status); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - if ((lock_status == DRX_LOCKED)) { - rc = drxdap_fasi_read_reg32(dev_addr, FEC_OC_RCN_DYN_RATE_LO__A, &rate_reg, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */ - mult32(rate_reg, common_attr->sys_clock_freq * 1000, &data64hi, - &data64lo); - cfg_data->bitrate = (data64hi << 7) | (data64lo >> 25); - } - - return 0; -rw_error: - return -EIO; -} -#endif /*----------------------------------------------------------------------------*/ /* MPEG Output Configuration Functions - end */ @@ -3727,40 +3466,6 @@ rw_error: return -EIO; } -/*----------------------------------------------------------------------------*/ -/** -* \fn int set_mpeg_output_clock_rate() -* \brief Set MPEG output clock rate. -* \param devmod Pointer to demodulator instance. -* \return int. -* -* This routine should be called during a set channel of QAM/VSB -* -*/ -#if 0 -static int set_mpeg_output_clock_rate(struct drx_demod_instance *demod) -{ - struct drxj_data *ext_attr = (struct drxj_data *) (NULL); - struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL); - int rc; - - dev_addr = demod->my_i2c_dev_addr; - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) { - rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, ext_attr->mpeg_output_clock_rate - 1, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - } - - return 0; -rw_error: - return -EIO; -} -#endif - /*----------------------------------------------------------------------------*/ /** * \fn int set_mpeg_start_width() @@ -3805,165 +3510,6 @@ rw_error: return -EIO; } -#if 0 -/*----------------------------------------------------------------------------*/ -/** -* \fn int ctrl_set_cfg_mpeg_output_misc() -* \brief Set miscellaneous configuartions -* \param devmod Pointer to demodulator instance. -* \param cfg_data pDRXJCfgMisc_t -* \return int. -* -* This routine can be used to set configuartion options that are DRXJ -* specific and/or added to the requirements at a late stage. -* -*/ -static int -ctrl_set_cfg_mpeg_output_misc(struct drx_demod_instance *demod, - struct drxj_cfg_mpeg_output_misc *cfg_data) -{ - struct drxj_data *ext_attr = NULL; - int rc; - - if (cfg_data == NULL) - return -EINVAL; - - ext_attr = demod->my_ext_attr; - - /* - Set disable TEI bit handling flag. - TEI must be left untouched by device in case of BER measurements using - external equipment that is unable to ignore the TEI bit in the TS. - Default will false (enable TEI bit handling). - Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)). - Set clock rate. Default is auto that is derived from symbol rate. - The flags and values will also be used to set registers during a set channel. - */ - ext_attr->disable_te_ihandling = cfg_data->disable_tei_handling; - ext_attr->bit_reverse_mpeg_outout = cfg_data->bit_reverse_mpeg_outout; - ext_attr->mpeg_output_clock_rate = cfg_data->mpeg_output_clock_rate; - ext_attr->mpeg_start_width = cfg_data->mpeg_start_width; - /* Don't care what the active standard is, activate setting immediatly */ - rc = set_mpegtei_handling(demod); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = bit_reverse_mpeg_output(demod); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = set_mpeg_output_clock_rate(demod); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = set_mpeg_start_width(demod); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} - -/*----------------------------------------------------------------------------*/ - -/** -* \fn int ctrl_get_cfg_mpeg_output_misc() -* \brief Get miscellaneous configuartions. -* \param devmod Pointer to demodulator instance. -* \param cfg_data Pointer to DRXJCfgMisc_t. -* \return int. -* -* This routine can be used to retreive the current setting of the configuartion -* options that are DRXJ specific and/or added to the requirements at a -* late stage. -* -*/ -static int -ctrl_get_cfg_mpeg_output_misc(struct drx_demod_instance *demod, - struct drxj_cfg_mpeg_output_misc *cfg_data) -{ - struct drxj_data *ext_attr = NULL; - int rc; - u16 data = 0; - - if (cfg_data == NULL) - return -EINVAL; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; - cfg_data->disable_tei_handling = ext_attr->disable_te_ihandling; - cfg_data->bit_reverse_mpeg_outout = ext_attr->bit_reverse_mpeg_outout; - cfg_data->mpeg_start_width = ext_attr->mpeg_start_width; - if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) { - cfg_data->mpeg_output_clock_rate = ext_attr->mpeg_output_clock_rate; - } else { - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, FEC_OC_DTO_PERIOD__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - cfg_data->mpeg_output_clock_rate = - (enum drxj_mpeg_output_clock_rate) (data + 1); - } - - return 0; -rw_error: - return -EIO; -} - -/*----------------------------------------------------------------------------*/ - -/** -* \fn int ctrl_get_cfg_hw_cfg() -* \brief Get HW configuartions. -* \param devmod Pointer to demodulator instance. -* \param cfg_data Pointer to Bool. -* \return int. -* -* This routine can be used to retreive the current setting of the configuartion -* options that are DRXJ specific and/or added to the requirements at a -* late stage. -* -*/ -static int -ctrl_get_cfg_hw_cfg(struct drx_demod_instance *demod, struct drxj_cfg_hw_cfg *cfg_data) -{ - int rc; - u16 data = 0; - - if (cfg_data == NULL) - return -EINVAL; - - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_OHW_CFG__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - cfg_data->i2c_speed = (enum drxji2c_speed) ((data >> 6) & 0x1); - cfg_data->xtal_freq = (enum drxj_xtal_freq) (data & 0x3); - - return 0; -rw_error: - return -EIO; -} -#endif - /*----------------------------------------------------------------------------*/ /* miscellaneous configuartions - end */ /*----------------------------------------------------------------------------*/ @@ -4108,68 +3654,25 @@ rw_error: return -EIO; } -#if 0 -/*============================================================================*/ /** -* \fn int ctrl_getuio_cfg() -* \brief Get modus oprandi UIO. +* \fn int ctrl_uio_write() +* \brief Write to a UIO. * \param demod Pointer to demodulator instance. -* \param uio_cfg Pointer to a configuration setting for a certain UIO. +* \param uio_data Pointer to data container for a certain UIO. * \return int. */ -static int ctrl_getuio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg) +static int +ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data) { + struct drxj_data *ext_attr = (struct drxj_data *) (NULL); + int rc; + u16 pin_cfg_value = 0; + u16 value = 0; - struct drxj_data *ext_attr = (struct drxj_data *) NULL; - enum drxuio_mode *uio_mode[4] = { NULL }; - bool *uio_available[4] = { NULL }; - - ext_attr = demod->my_ext_attr; - - uio_mode[DRX_UIO1] = &ext_attr->uio_sma_tx_mode; - uio_mode[DRX_UIO2] = &ext_attr->uio_sma_rx_mode; - uio_mode[DRX_UIO3] = &ext_attr->uio_gpio_mode; - uio_mode[DRX_UIO4] = &ext_attr->uio_irqn_mode; - - uio_available[DRX_UIO1] = &ext_attr->has_smatx; - uio_available[DRX_UIO2] = &ext_attr->has_smarx; - uio_available[DRX_UIO3] = &ext_attr->has_gpio; - uio_available[DRX_UIO4] = &ext_attr->has_irqn; - - if (uio_cfg == NULL) - return -EINVAL; - - if ((uio_cfg->uio > DRX_UIO4) || (uio_cfg->uio < DRX_UIO1)) + if ((uio_data == NULL) || (demod == NULL)) return -EINVAL; - if (!*uio_available[uio_cfg->uio]) - return -EIO; - - uio_cfg->mode = *uio_mode[uio_cfg->uio]; - - return 0; -} -#endif - -/** -* \fn int ctrl_uio_write() -* \brief Write to a UIO. -* \param demod Pointer to demodulator instance. -* \param uio_data Pointer to data container for a certain UIO. -* \return int. -*/ -static int -ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data) -{ - struct drxj_data *ext_attr = (struct drxj_data *) (NULL); - int rc; - u16 pin_cfg_value = 0; - u16 value = 0; - - if ((uio_data == NULL) || (demod == NULL)) - return -EINVAL; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; + ext_attr = (struct drxj_data *) demod->my_ext_attr; /* Write magic word to enable pdr reg write */ rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0); @@ -4353,186 +3856,6 @@ rw_error: return -EIO; } -#if 0 -/** -*\fn int ctrl_uio_read -*\brief Read from a UIO. -* \param demod Pointer to demodulator instance. -* \param uio_data Pointer to data container for a certain UIO. -* \return int. -*/ -static int ctrl_uio_read(struct drx_demod_instance *demod, struct drxuio_data *uio_data) -{ - struct drxj_data *ext_attr = (struct drxj_data *) (NULL); - int rc; - u16 pin_cfg_value = 0; - u16 value = 0; - - if ((uio_data == NULL) || (demod == NULL)) - return -EINVAL; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* Write magic word to enable pdr reg write */ - rc = drxj_dap_write_reg16(demod->my_i2c_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; - } - switch (uio_data->uio) { - /*====================================================================*/ - case DRX_UIO1: - /* DRX_UIO1: SMA_TX UIO-1 */ - if (!ext_attr->has_smatx) - return -EIO; - - if (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE) - return -EIO; - - pin_cfg_value = 0; - /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ - pin_cfg_value |= 0x0110; - /* io_pad_cfg_mode output mode is drive always */ - /* io_pad_cfg_drive is set to power 2 (23 mA) */ - - /* write to io pad configuration register - input mode */ - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - if ((value & 0x8000) != 0) { /* check 15th bit - 1st UIO */ - uio_data->value = true; - } else { - uio_data->value = false; - } - break; - /*======================================================================*/ - case DRX_UIO2: - /* DRX_UIO2: SMA_RX UIO-2 */ - if (!ext_attr->has_smarx) - return -EIO; - - if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE) - return -EIO; - - pin_cfg_value = 0; - /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ - pin_cfg_value |= 0x0110; - /* io_pad_cfg_mode output mode is drive always */ - /* io_pad_cfg_drive is set to power 2 (23 mA) */ - - /* write to io pad configuration register - input mode */ - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - if ((value & 0x4000) != 0) /* check 14th bit - 2nd UIO */ - uio_data->value = true; - else - uio_data->value = false; - - break; - /*=====================================================================*/ - case DRX_UIO3: - /* DRX_UIO3: GPIO UIO-3 */ - if (!ext_attr->has_gpio) - return -EIO; - - if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE) - return -EIO; - - pin_cfg_value = 0; - /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ - pin_cfg_value |= 0x0110; - /* io_pad_cfg_mode output mode is drive always */ - /* io_pad_cfg_drive is set to power 2 (23 mA) */ - - /* write to io pad configuration register - input mode */ - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* read io input data registar */ - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_HI__A, &value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - if ((value & 0x0004) != 0) { /* check 2nd bit - 3rd UIO */ - uio_data->value = true; - } else { - uio_data->value = false; - } - break; - /*=====================================================================*/ - case DRX_UIO4: - /* DRX_UIO4: IRQN UIO-4 */ - if (!ext_attr->has_irqn) - return -EIO; - - if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE) - return -EIO; - - pin_cfg_value = 0; - /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ - pin_cfg_value |= 0x0110; - /* io_pad_cfg_mode output mode is drive always */ - /* io_pad_cfg_drive is set to power 2 (23 mA) */ - - /* write to io pad configuration register - input mode */ - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* read io input data registar */ - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - if ((value & 0x1000) != 0) /* check 12th bit - 4th UIO */ - uio_data->value = true; - else - uio_data->value = false; - - break; - /*====================================================================*/ - default: - return -EINVAL; - } /* switch ( uio_data->uio ) */ - - /* Write magic word to disable pdr reg write */ - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} -#endif - /*---------------------------------------------------------------------------*/ /* UIO Configuration Functions - end */ /*---------------------------------------------------------------------------*/ @@ -4648,119 +3971,6 @@ rw_error: return -EIO; } -#if 0 -/** -* \fn int ctrl_set_cfg_smart_ant() -* \brief Set Smart Antenna. -* \param pointer to struct drxj_cfg_smart_ant. -* \return int. -* -*/ -static int -ctrl_set_cfg_smart_ant(struct drx_demod_instance *demod, struct drxj_cfg_smart_ant *smart_ant) -{ - struct drxj_data *ext_attr = NULL; - struct i2c_device_addr *dev_addr = NULL; - int rc; - u32 start_time = 0; - u16 data = 0; - static bool bit_inverted; - - dev_addr = demod->my_i2c_dev_addr; - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* check arguments */ - if (smart_ant == NULL) - return -EINVAL; - - if (bit_inverted != ext_attr->smart_ant_inverted - || ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SMA) { - rc = smart_ant_init(demod); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - bit_inverted = ext_attr->smart_ant_inverted; - } - - /* Write magic word to enable pdr reg write */ - rc = drxj_dap_write_reg16(demod->my_i2c_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; - } - - switch (smart_ant->io) { - case DRXJ_SMT_ANT_OUTPUT: - /* enable Tx if Mode B (input) is supported */ - /* - RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data ); - WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M ); - */ - start_time = jiffies_to_msecs(jiffies); - do { - rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_STATUS__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - } while ((data & SIO_SA_TX_STATUS_BUSY__M) && ((jiffies_to_msecs(jiffies) - start_time) < DRXJ_MAX_WAITTIME)); - - if (data & SIO_SA_TX_STATUS_BUSY__M) - return -EIO; - - /* write to smart antenna configuration register */ - rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_DATA0__A, 0x9200 | ((smart_ant->ctrl_data & 0x0001) << 8) | ((smart_ant->ctrl_data & 0x0002) << 10) | ((smart_ant->ctrl_data & 0x0004) << 12), 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_DATA1__A, 0x4924 | ((smart_ant->ctrl_data & 0x0008) >> 2) | ((smart_ant->ctrl_data & 0x0010)) | ((smart_ant->ctrl_data & 0x0020) << 2) | ((smart_ant->ctrl_data & 0x0040) << 4) | ((smart_ant->ctrl_data & 0x0080) << 6), 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_DATA2__A, 0x2492 | ((smart_ant->ctrl_data & 0x0100) >> 8) | ((smart_ant->ctrl_data & 0x0200) >> 6) | ((smart_ant->ctrl_data & 0x0400) >> 4) | ((smart_ant->ctrl_data & 0x0800) >> 2) | ((smart_ant->ctrl_data & 0x1000)) | ((smart_ant->ctrl_data & 0x2000) << 2), 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_DATA3__A, 0xff8d, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* trigger the sending */ - rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_LENGTH__A, 56, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - break; - case DRXJ_SMT_ANT_INPUT: - /* disable Tx if Mode B (input) is supported */ - /* - RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data ); - WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) ); - */ - default: - return -EINVAL; - } - /* Write magic word to enable pdr reg write */ - rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} -#endif - static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd) { int rc; @@ -5141,321 +4351,6 @@ rw_error: return -EIO; } -#if 0 -/** -* \brief Configure IQM AF registers -* \param demod instance of demodulator. -* \param active -* \return int. -*/ -static int iqm_set_af(struct drx_demod_instance *demod, bool active) -{ - struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; - int rc; - u16 data = 0; - - /* Configure IQM */ - rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - if (!active) - data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE)); - else - data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE); - rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} - -/* -------------------------------------------------------------------------- */ -static int -ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg); - -/** -* \brief set configuration of pin-safe mode -* \param demod instance of demodulator. -* \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m. -* \return int. -*/ -static int -ctrl_set_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enable) -{ - struct drxj_data *ext_attr = NULL; - struct i2c_device_addr *dev_addr = NULL; - int rc; - - if (enable == NULL) - return -EINVAL; - - dev_addr = demod->my_i2c_dev_addr; - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* Write magic word to enable pdr reg write */ - 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 (*enable) { - bool bridge_enabled = false; - - /* MPEG pins to input */ - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* PD_I2C_SDA2 Bridge off, Port2 Inactive - PD_I2C_SCL2 Bridge off, Port2 Inactive */ - rc = ctrl_i2c_bridge(demod, &bridge_enabled); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* PD_GPIO Store and set to input - PD_VSYNC Store and set to input - PD_SMA_RX Store and set to input - PD_SMA_TX Store and set to input */ - rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_GPIO_CFG__A, &ext_attr->pdr_safe_restore_val_gpio, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_VSYNC_CFG__A, &ext_attr->pdr_safe_restore_val_v_sync, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_SMA_RX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_rx, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_SMA_TX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_tx, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate! - PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */ - rc = iqm_set_af(demod, false); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* PD_CVBS Analog DAC output, standby mode - PD_SIF Analog DAC output, standby mode */ - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* PD_I2S_CL Input - PD_I2S_DA Input - PD_I2S_WS Input */ - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE, 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, DRXJ_PIN_SAFE_MODE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - } else { - /* No need to restore MPEG pins; - is done in SetStandard/SetChannel */ - - /* PD_I2C_SDA2 Port2 active - PD_I2C_SCL2 Port2 active */ - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, SIO_PDR_I2C_SDA2_CFG__PRE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, SIO_PDR_I2C_SCL2_CFG__PRE, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* PD_GPIO Restore - PD_VSYNC Restore - PD_SMA_RX Restore - PD_SMA_TX Restore */ - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_GPIO_CFG__A, ext_attr->pdr_safe_restore_val_gpio, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_VSYNC_CFG__A, ext_attr->pdr_safe_restore_val_v_sync, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_RX_CFG__A, ext_attr->pdr_safe_restore_val_sma_rx, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_TX_CFG__A, ext_attr->pdr_safe_restore_val_sma_tx, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* PD_RF_AGC, PD_IF_AGC - No need to restore; will be restored in SetStandard/SetChannel */ - - /* PD_CVBS, PD_SIF - No need to restore; will be restored in SetStandard/SetChannel */ - - /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS - Should be restored via DRX_CTRL_SET_AUD */ - } - - /* Write magic word to disable pdr reg write */ - 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; - } - ext_attr->pdr_safe_mode = *enable; - - return 0; - -rw_error: - return -EIO; -} - -/* -------------------------------------------------------------------------- */ - -/** -* \brief get configuration of pin-safe mode -* \param demod instance of demodulator. -* \param enable boolean indicating whether pin-safe mode is active -* \return int. -*/ -static int -ctrl_get_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enabled) -{ - struct drxj_data *ext_attr = (struct drxj_data *) NULL; - - if (enabled == NULL) - return -EINVAL; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; - *enabled = ext_attr->pdr_safe_mode; - - return 0; -} -#endif - /*============================================================================*/ /*== END AUXILIARY FUNCTIONS ==*/ /*============================================================================*/ @@ -5666,72 +4561,6 @@ static int init_agc(struct drx_demod_instance *demod) goto rw_error; } break; -#endif -#if 0 - case DRX_STANDARD_FM: - clp_sum_max = 1023; - sns_sum_max = 1023; - ki_innergain_min = (u16) (-32768); - if_iaccu_hi_tgt_min = 2047; - agc_ki_dgain = 0x7; - ki_min = 0x0225; - ki_max = 0x0547; - clp_dir_to = (u16) (-9); - sns_dir_to = (u16) (-9); - ingain_tgt_max = 9000; - clp_ctrl_mode = 1; - p_agc_if_settings = &(ext_attr->atv_if_agc_cfg); - p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg); - rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - break; - case DRX_STANDARD_NTSC: - case DRX_STANDARD_PAL_SECAM_BG: - case DRX_STANDARD_PAL_SECAM_DK: - case DRX_STANDARD_PAL_SECAM_I: - clp_sum_max = 1023; - sns_sum_max = 1023; - ki_innergain_min = (u16) (-32768); - if_iaccu_hi_tgt_min = 2047; - agc_ki_dgain = 0x7; - ki_min = 0x0225; - ki_max = 0x0547; - clp_dir_to = (u16) (-9); - ingain_tgt_max = 9000; - p_agc_if_settings = &(ext_attr->atv_if_agc_cfg); - p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg); - sns_dir_to = (u16) (-9); - clp_ctrl_mode = 1; - rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - break; - case DRX_STANDARD_PAL_SECAM_L: - case DRX_STANDARD_PAL_SECAM_LP: - clp_sum_max = 1023; - sns_sum_max = 1023; - ki_innergain_min = (u16) (-32768); - if_iaccu_hi_tgt_min = 2047; - agc_ki_dgain = 0x7; - ki_min = 0x0225; - ki_max = 0x0547; - clp_dir_to = (u16) (-9); - sns_dir_to = (u16) (-9); - ingain_tgt_max = 9000; - clp_ctrl_mode = 1; - p_agc_if_settings = &(ext_attr->atv_if_agc_cfg); - p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg); - rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - break; #endif default: return -EINVAL; @@ -6004,85 +4833,6 @@ rw_error: return -EIO; } -#if 0 -/** -* \fn int get_sig_strength() -* \brief Retrieve signal strength for VSB and QAM. -* \param demod Pointer to demod instance -* \param u16-t Pointer to signal strength data; range 0, .. , 100. -* \return int. -* \retval 0 sig_strength contains valid data. -* \retval -EINVAL sig_strength is NULL. -* \retval -EIO Erroneous data, sig_strength contains invalid data. -*/ -#define DRXJ_AGC_TOP 0x2800 -#define DRXJ_AGC_SNS 0x1600 -#define DRXJ_RFAGC_MAX 0x3fff -#define DRXJ_RFAGC_MIN 0x800 - -static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength) -{ - struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; - int rc; - u16 rf_gain = 0; - u16 if_gain = 0; - u16 if_agc_sns = 0; - u16 if_agc_top = 0; - u16 rf_agc_max = 0; - u16 rf_agc_min = 0; - - rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - if_gain &= IQM_AF_AGC_IF__M; - rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rf_gain &= IQM_AF_AGC_RF__M; - - if_agc_sns = DRXJ_AGC_SNS; - if_agc_top = DRXJ_AGC_TOP; - rf_agc_max = DRXJ_RFAGC_MAX; - rf_agc_min = DRXJ_RFAGC_MIN; - - if (if_gain > if_agc_top) { - if (rf_gain > rf_agc_max) - *sig_strength = 100; - else if (rf_gain > rf_agc_min) { - if (rf_agc_max == rf_agc_min) { - pr_err("error: rf_agc_max == rf_agc_min\n"); - return -EIO; - } - *sig_strength = - 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max - - rf_agc_min); - } else - *sig_strength = 75; - } else if (if_gain > if_agc_sns) { - if (if_agc_top == if_agc_sns) { - pr_err("error: if_agc_top == if_agc_sns\n"); - return -EIO; - } - *sig_strength = - 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns); - } else { - if (!if_agc_sns) { - pr_err("error: if_agc_sns is zero!\n"); - return -EIO; - } - *sig_strength = (20 * if_gain / if_agc_sns); - } - - return 0; -rw_error: - return -EIO; -} -#endif - /** * \fn int get_acc_pkt_err() * \brief Retrieve signal strength for VSB and QAM. @@ -6132,130 +4882,6 @@ rw_error: } #endif -#if 0 -/** -* \fn int ResetAccPktErr() -* \brief Reset Accumulating packet error count. -* \param demod Pointer to demod instance -* \return int. -* \retval 0. -* \retval -EIO Erroneous data. -*/ -static int ctrl_set_cfg_reset_pkt_err(struct drx_demod_instance *demod) -{ - struct drxj_data *ext_attr = NULL; - int rc; - u16 packet_error = 0; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; - ext_attr->reset_pkt_err_acc = true; - /* call to reset counter */ - rc = get_acc_pkt_err(demod, &packet_error); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} - -/** -* \fn static short get_str_freq_offset() -* \brief Get symbol rate offset in QAM & 8VSB mode -* \return Error code -*/ -static int get_str_freq_offset(struct drx_demod_instance *demod, s32 *str_freq) -{ - int rc; - u32 symbol_frequency_ratio = 0; - u32 symbol_nom_frequency_ratio = 0; - - struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; - struct drxj_data *ext_attr = demod->my_ext_attr; - - rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &symbol_frequency_ratio, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - symbol_nom_frequency_ratio = ext_attr->iqm_rc_rate_ofs; - - if (symbol_frequency_ratio > symbol_nom_frequency_ratio) - *str_freq = - -1 * - frac_times1e6((symbol_frequency_ratio - - symbol_nom_frequency_ratio), - (symbol_frequency_ratio + (1 << 23))); - else - *str_freq = - frac_times1e6((symbol_nom_frequency_ratio - - symbol_frequency_ratio), - (symbol_frequency_ratio + (1 << 23))); - - return 0; -rw_error: - return -EIO; -} - -/** -* \fn static short get_ctl_freq_offset -* \brief Get the value of ctl_freq in QAM & ATSC mode -* \return Error code -*/ -static int get_ctl_freq_offset(struct drx_demod_instance *demod, s32 *ctl_freq) -{ - s32 sampling_frequency = 0; - s32 current_frequency = 0; - s32 nominal_frequency = 0; - s32 carrier_frequency_shift = 0; - s32 sign = 1; - u32 data64hi = 0; - u32 data64lo = 0; - struct drxj_data *ext_attr = NULL; - struct drx_common_attr *common_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; - common_attr = (struct drx_common_attr *) demod->my_common_attr; - - sampling_frequency = common_attr->sys_clock_freq / 3; - - /* both registers are sign extended */ - nominal_frequency = ext_attr->iqm_fs_rate_ofs; - rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, (u32 *)¤t_frequency, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - if (ext_attr->pos_image) { - /* negative image */ - carrier_frequency_shift = nominal_frequency - current_frequency; - } else { - /* positive image */ - carrier_frequency_shift = current_frequency - nominal_frequency; - } - - /* carrier Frequency Shift In Hz */ - if (carrier_frequency_shift < 0) { - sign = -1; - carrier_frequency_shift *= sign; - } - - /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */ - mult32(carrier_frequency_shift, sampling_frequency, &data64hi, &data64lo); - *ctl_freq = - (s32) ((((data64lo >> 28) & 0xf) | (data64hi << 4)) * sign); - - return 0; -rw_error: - return -EIO; -} -#endif /*============================================================================*/ @@ -6463,93 +5089,15 @@ set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, case DRX_STANDARD_ITU_C: ext_attr->qam_rf_agc_cfg = *agc_settings; 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: - case DRX_STANDARD_FM: - ext_attr->atv_rf_agc_cfg = *agc_settings; - break; -#endif - default: - return -EIO; - } - - return 0; -rw_error: - return -EIO; -} - -#if 0 -/** -* \fn int get_agc_rf () -* \brief get configuration of RF AGC -* \param demod instance of demodulator. -* \param agc_settings AGC configuration structure -* \return int. -*/ -static int -get_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings) -{ - struct i2c_device_addr *dev_addr = NULL; - struct drxj_data *ext_attr = NULL; - enum drx_standard standard = DRX_STANDARD_UNKNOWN; - int rc; - - dev_addr = demod->my_i2c_dev_addr; - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* Return stored AGC settings */ - standard = agc_settings->standard; - switch (agc_settings->standard) { - case DRX_STANDARD_8VSB: - *agc_settings = ext_attr->vsb_rf_agc_cfg; - break; -#ifndef DRXJ_VSB_ONLY - case DRX_STANDARD_ITU_A: - case DRX_STANDARD_ITU_B: - case DRX_STANDARD_ITU_C: - *agc_settings = ext_attr->qam_rf_agc_cfg; - 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: - case DRX_STANDARD_FM: - *agc_settings = ext_attr->atv_rf_agc_cfg; - break; #endif default: return -EIO; } - agc_settings->standard = standard; - - /* Get AGC output only if standard is currently active. */ - if ((ext_attr->standard == agc_settings->standard) || - (DRXJ_ISQAMSTD(ext_attr->standard) && - DRXJ_ISQAMSTD(agc_settings->standard)) || - (DRXJ_ISATVSTD(ext_attr->standard) && - DRXJ_ISATVSTD(agc_settings->standard))) { - rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, &(agc_settings->output_level), 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - } return 0; rw_error: return -EIO; } -#endif /** * \fn int set_agc_if () @@ -6771,91 +5319,14 @@ set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, ext_attr->qam_if_agc_cfg = *agc_settings; 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: - case DRX_STANDARD_FM: - ext_attr->atv_if_agc_cfg = *agc_settings; - break; -#endif - default: - return -EIO; - } - - return 0; -rw_error: - return -EIO; -} - -#if 0 -/** -* \fn int get_agc_if () -* \brief get configuration of If AGC -* \param demod instance of demodulator. -* \param agc_settings AGC configuration structure -* \return int. -*/ -static int -get_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings) -{ - struct i2c_device_addr *dev_addr = NULL; - struct drxj_data *ext_attr = NULL; - enum drx_standard standard = DRX_STANDARD_UNKNOWN; - int rc; - - dev_addr = demod->my_i2c_dev_addr; - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* Return stored ATV AGC settings */ - standard = agc_settings->standard; - switch (agc_settings->standard) { - case DRX_STANDARD_8VSB: - *agc_settings = ext_attr->vsb_if_agc_cfg; - break; -#ifndef DRXJ_VSB_ONLY - case DRX_STANDARD_ITU_A: - case DRX_STANDARD_ITU_B: - case DRX_STANDARD_ITU_C: - *agc_settings = ext_attr->qam_if_agc_cfg; - break; -#endif - 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: - case DRX_STANDARD_FM: - *agc_settings = ext_attr->atv_if_agc_cfg; - break; default: return -EIO; } - agc_settings->standard = standard; - - /* Get AGC output only if standard is currently active */ - if ((ext_attr->standard == agc_settings->standard) || - (DRXJ_ISQAMSTD(ext_attr->standard) && - DRXJ_ISQAMSTD(agc_settings->standard)) || - (DRXJ_ISATVSTD(ext_attr->standard) && - DRXJ_ISATVSTD(agc_settings->standard))) { - /* read output level */ - rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, &(agc_settings->output_level), 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - } return 0; rw_error: return -EIO; } -#endif /** * \fn int set_iqm_af () @@ -7832,151 +6303,29 @@ rw_error: return -EIO; } -#if 0 /** -* \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber) -* \brief Get the values of ber in VSB mode +* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer) +* \brief Get the values of MER * \return Error code */ -static int get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ser) +static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer) { int rc; - u16 data = 0; - u16 period = 0; - u16 prescale = 0; - u16 symb_errors_mant = 0; - u16 symb_errors_exp = 0; + u16 data_hi = 0; - rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &data, 0); + rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - period = FEC_RS_MEASUREMENT_PERIOD; - prescale = FEC_RS_MEASUREMENT_PRESCALE; - - symb_errors_mant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M; - symb_errors_exp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M) - >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B; - - if (period * prescale == 0) { - pr_err("error: period and/or prescale is zero!\n"); - return -EIO; - } - *ser = (u32) frac_times1e6((symb_errors_mant << symb_errors_exp) * 1000, - (period * prescale * 77318)); + *mer = + (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52)); return 0; rw_error: return -EIO; } -#endif - -/** -* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer) -* \brief Get the values of MER -* \return Error code -*/ -static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer) -{ - int rc; - u16 data_hi = 0; - - rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - *mer = - (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52)); - - return 0; -rw_error: - return -EIO; -} - -#if 0 -/*============================================================================*/ -/** -* \fn int ctrl_get_vsb_constel() -* \brief Retreive a VSB 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_get_vsb_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr) -{ - struct i2c_device_addr *dev_addr = NULL; - int rc; - /**< device address */ - u16 vsb_top_comm_mb = 0; /**< VSB SL MB configuration */ - u16 vsb_top_comm_mb_init = 0; /**< VSB SL MB intial configuration */ - u16 re = 0; /**< constellation Re part */ - u32 data = 0; - - /* read device info */ - dev_addr = demod->my_i2c_dev_addr; - - /* TODO: */ - /* Monitor bus grabbing is an open external interface issue */ - /* Needs to be checked when external interface PG is updated */ - - /* Configure MB (Monitor bus) */ - rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_COMM_MB__A, &vsb_top_comm_mb_init, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - /* set observe flag & MB mux */ - vsb_top_comm_mb = (vsb_top_comm_mb_init | - VSB_TOP_COMM_MB_OBS_OBS_ON | - VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2); - rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* Enable MB grabber in the FEC OC */ - rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* Disable MB grabber in the FEC OC */ - rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, 0x0, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* read data */ - rc = drxdap_fasi_read_reg32(dev_addr, FEC_OC_OCR_GRAB_RD1__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - re = (u16) (((data >> 10) & 0x300) | ((data >> 2) & 0xff)); - if (re & 0x0200) - re |= 0xfc00; - complex_nr->re = re; - complex_nr->im = 0; - - /* Restore MB (Monitor bus) */ - rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb_init, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - return 0; -rw_error: - return -EIO; -} -#endif /*============================================================================*/ /*== END 8VSB DATAPATH FUNCTIONS ==*/ @@ -11202,112 +9551,6 @@ rw_error: return -EIO; } -#if 0 -/** -* \fn int ctrl_get_qam_constel() -* \brief Retreive a QAM 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_get_qam_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr) -{ - struct i2c_device_addr *dev_addr = NULL; - int rc; - u32 data = 0; - u16 fec_oc_ocr_mode = 0; - /**< FEC OCR grabber configuration */ - u16 qam_sl_comm_mb = 0;/**< QAM SL MB configuration */ - u16 qam_sl_comm_mb_init = 0; - /**< QAM SL MB intial configuration */ - u16 im = 0; /**< constellation Im part */ - u16 re = 0; /**< constellation Re part */ - /**< device address */ - - /* read device info */ - dev_addr = demod->my_i2c_dev_addr; - - /* TODO: */ - /* Monitor bus grabbing is an open external interface issue */ - /* Needs to be checked when external interface PG is updated */ - - /* Configure MB (Monitor bus) */ - rc = drxj_dap_read_reg16(dev_addr, QAM_SL_COMM_MB__A, &qam_sl_comm_mb_init, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - /* set observe flag & MB mux */ - qam_sl_comm_mb = qam_sl_comm_mb_init & (~(QAM_SL_COMM_MB_OBS__M + - QAM_SL_COMM_MB_MUX_OBS__M)); - qam_sl_comm_mb |= (QAM_SL_COMM_MB_OBS_ON + - QAM_SL_COMM_MB_MUX_OBS_CONST_CORR); - rc = drxj_dap_write_reg16(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* Enable MB grabber in the FEC OC */ - fec_oc_ocr_mode = (/* output select: observe bus */ - (FEC_OC_OCR_MODE_MB_SELECT__M & - (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) | - /* grabber enable: on */ - (FEC_OC_OCR_MODE_GRAB_ENABLE__M & - (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) | - /* grabber select: observe bus */ - (FEC_OC_OCR_MODE_GRAB_SELECT__M & - (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) | - /* grabber mode: continuous */ - (FEC_OC_OCR_MODE_GRAB_COUNTED__M & - (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B))); - rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, fec_oc_ocr_mode, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* Disable MB grabber in the FEC OC */ - rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, 0x00, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - /* read data */ - rc = drxdap_fasi_read_reg32(dev_addr, FEC_OC_OCR_GRAB_RD0__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - re = (u16) (data & FEC_OC_OCR_GRAB_RD0__M); - im = (u16) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M); - - /* TODO: */ - /* interpret data (re & im) according to the Monitor bus mapping ?? */ - - /* sign extension, 10th bit is sign bit */ - if ((re & 0x0200) == 0x0200) - re |= 0xFC00; - if ((im & 0x0200) == 0x0200) - im |= 0xFC00; - complex_nr->re = ((s16) re); - complex_nr->im = ((s16) im); - - /* Restore MB (Monitor bus) */ - rc = drxj_dap_write_reg16(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb_init, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} -#endif /* #if 0 */ #endif /* #ifndef DRXJ_VSB_ONLY */ /*============================================================================*/ @@ -11376,308 +9619,159 @@ rw_error: */ /* -------------------------------------------------------------------------- */ -#if 0 -/** -* \brief Get array index for atv coef (ext_attr->atvTopCoefX[index]) -* \param standard -* \param pointer to index -* \return int. -* -*/ -static int atv_equ_coef_index(enum drx_standard standard, int *index) -{ - switch (standard) { - case DRX_STANDARD_PAL_SECAM_BG: - *index = (int)DRXJ_COEF_IDX_BG; - break; - case DRX_STANDARD_PAL_SECAM_DK: - *index = (int)DRXJ_COEF_IDX_DK; - break; - case DRX_STANDARD_PAL_SECAM_I: - *index = (int)DRXJ_COEF_IDX_I; - break; - case DRX_STANDARD_PAL_SECAM_L: - *index = (int)DRXJ_COEF_IDX_L; - break; - case DRX_STANDARD_PAL_SECAM_LP: - *index = (int)DRXJ_COEF_IDX_LP; - break; - case DRX_STANDARD_NTSC: - *index = (int)DRXJ_COEF_IDX_MN; - break; - case DRX_STANDARD_FM: - *index = (int)DRXJ_COEF_IDX_FM; - break; - default: - *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */ - return -EIO; - break; - } - - return 0; -} - -/* -------------------------------------------------------------------------- */ /** -* \fn int atv_update_config () -* \brief Flush changes in ATV shadow registers to physical registers. +* \fn int power_down_atv () +* \brief Power down ATV. * \param demod instance of demodulator -* \param force_update don't look at standard or change flags, flush all. +* \param standard either NTSC or FM (sub strandard for ATV ) * \return int. * +* Stops and thus resets ATV and IQM block +* SIF and CVBS ADC are powered down +* Calls audio power down */ static int -atv_update_config(struct drx_demod_instance *demod, bool force_update) +power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary) { - struct i2c_device_addr *dev_addr = NULL; - struct drxj_data *ext_attr = NULL; + struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; + struct drxjscu_cmd cmd_scu = { /* command */ 0, + /* parameter_len */ 0, + /* result_len */ 0, + /* *parameter */ NULL, + /* *result */ NULL + }; int rc; + u16 cmd_result = 0; - dev_addr = demod->my_i2c_dev_addr; - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* equalizer coefficients */ - if (force_update || - ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_COEF) != 0)) { - int index = 0; + /* ATV NTSC */ - rc = atv_equ_coef_index(ext_attr->standard, &index); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU0__A, ext_attr->atv_top_equ0[index], 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU1__A, ext_attr->atv_top_equ1[index], 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU2__A, ext_attr->atv_top_equ2[index], 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU3__A, ext_attr->atv_top_equ3[index], 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } + /* Stop ATV SCU (will reset ATV and IQM hardware */ + cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV | + SCU_RAM_COMMAND_CMD_DEMOD_STOP; + 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; + } + /* Disable ATV outputs (ATV reset enables CVBS, undo this) */ + rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; } - /* bypass fast carrier recovery */ - if (force_update) { - u16 data = 0; - - rc = drxj_dap_read_reg16(dev_addr, IQM_RT_ROT_BP__A, &data, 0); + rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + if (primary) { + rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - data &= (~((u16) IQM_RT_ROT_BP_ROT_OFF__M)); - if (ext_attr->phase_correction_bypass) - data |= IQM_RT_ROT_BP_ROT_OFF_OFF; - else - data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE; - rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ROT_BP__A, data, 0); + rc = set_iqm_af(demod, false); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - } - - /* peak filter setting */ - if (force_update || - ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) { - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_PEAK__A, ext_attr->atv_top_vid_peak, 0); + } else { + rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - } - - /* noise filter setting */ - if (force_update || - ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) { - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_NOISE_TH__A, ext_attr->atv_top_noise_th, 0); + rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - } - - /* SIF attenuation */ - if (force_update || - ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) { - u16 attenuation = 0; - - switch (ext_attr->sif_attenuation) { - case DRXJ_SIF_ATTENUATION_0DB: - attenuation = ATV_TOP_AF_SIF_ATT_0DB; - break; - case DRXJ_SIF_ATTENUATION_3DB: - attenuation = ATV_TOP_AF_SIF_ATT_M3DB; - break; - case DRXJ_SIF_ATTENUATION_6DB: - attenuation = ATV_TOP_AF_SIF_ATT_M6DB; - break; - case DRXJ_SIF_ATTENUATION_9DB: - attenuation = ATV_TOP_AF_SIF_ATT_M9DB; - break; - default: - return -EIO; - break; - } - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_AF_SIF_ATT__A, attenuation, 0); + rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - } - - /* SIF & CVBS enable */ - if (force_update || - ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) { - u16 data = 0; - - rc = drxj_dap_read_reg16(dev_addr, ATV_TOP_STDBY__A, &data, 0); + rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - if (ext_attr->enable_cvbs_output) - data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE; - else - data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE); - - if (ext_attr->enable_sif_output) - data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY); - else - data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY; - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, data, 0); + rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } } - - ext_attr->atv_cfg_changed_flags = 0; + rc = power_down_aud(demod); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } return 0; rw_error: return -EIO; } -/* -------------------------------------------------------------------------- */ +/*============================================================================*/ + /** -* \fn int ctrl_set_cfg_atv_output() -* \brief Configure ATV ouputs +* \brief Power up AUD. * \param demod instance of demodulator -* \param output_cfg output configuaration * \return int. * */ -static int -ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg) +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; - /* Check arguments */ - if (output_cfg == NULL) - return -EINVAL; - + dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr; ext_attr = (struct drxj_data *) demod->my_ext_attr; - if (output_cfg->enable_sif_output) { - switch (output_cfg->sif_attenuation) { - case DRXJ_SIF_ATTENUATION_0DB: /* fallthrough */ - case DRXJ_SIF_ATTENUATION_3DB: /* fallthrough */ - case DRXJ_SIF_ATTENUATION_6DB: /* fallthrough */ - case DRXJ_SIF_ATTENUATION_9DB: - /* Do nothing */ - break; - default: - return -EINVAL; - break; - } - - if (ext_attr->sif_attenuation != output_cfg->sif_attenuation) { - ext_attr->sif_attenuation = output_cfg->sif_attenuation; - ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_SIF_ATT; - } - } - if (ext_attr->enable_cvbs_output != output_cfg->enable_cvbs_output) { - ext_attr->enable_cvbs_output = output_cfg->enable_cvbs_output; - ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT; - } - - if (ext_attr->enable_sif_output != output_cfg->enable_sif_output) { - ext_attr->enable_sif_output = output_cfg->enable_sif_output; - ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT; - } - - rc = atv_update_config(demod, false); + 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; } -/* -------------------------------------------------------------------------- */ /** -* \fn int ctrl_set_cfg_atv_equ_coef() -* \brief Set ATV equalizer coefficients -* \param demod instance of demodulator -* \param coef the equalizer coefficients +* \fn int set_orx_nsu_aox() +* \brief Configure OrxNsuAox for OOB +* \param demod instance of demodulator. +* \param active * \return int. -* */ -static int -ctrl_set_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef) +static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active) { - struct drxj_data *ext_attr = NULL; + struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; int rc; - int index; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* current standard needs to be an ATV standard */ - if (!DRXJ_ISATVSTD(ext_attr->standard)) - return -EIO; - - /* Check arguments */ - if ((coef == NULL) || - (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) || - (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) || - (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) || - (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) || - (coef->coef0 < ((s16) ~(ATV_TOP_EQU0_EQU_C0__M >> 1))) || - (coef->coef1 < ((s16) ~(ATV_TOP_EQU1_EQU_C1__M >> 1))) || - (coef->coef2 < ((s16) ~(ATV_TOP_EQU2_EQU_C2__M >> 1))) || - (coef->coef3 < ((s16) ~(ATV_TOP_EQU3_EQU_C3__M >> 1)))) { - return -EINVAL; - } + u16 data = 0; - rc = atv_equ_coef_index(ext_attr->standard, &index); + /* 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; } - ext_attr->atv_top_equ0[index] = coef->coef0; - ext_attr->atv_top_equ1[index] = coef->coef1; - ext_attr->atv_top_equ2[index] = coef->coef2; - ext_attr->atv_top_equ3[index] = coef->coef3; - ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_COEF; - - rc = atv_update_config(demod, false); + 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; @@ -11688,7534 +9782,1351 @@ rw_error: return -EIO; } -/* -------------------------------------------------------------------------- */ /** -* \fn int ctrl_get_cfg_atv_equ_coef() -* \brief Get ATV equ coef settings +* \fn int ctrl_set_oob() +* \brief Set OOB channel to be used. * \param demod instance of demodulator -* \param coef The ATV equ coefficients +* \param oob_param OOB parameters for channel setting. +* \frequency should be in KHz * \return int. * -* The values are read from the shadow registers maintained by the drxdriver -* If registers are manipulated outside of the drxdriver scope the reported -* settings will not reflect these changes because of the use of shadow -* regitsers. +* 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 * */ -static int -ctrl_get_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef) -{ - struct drxj_data *ext_attr = NULL; - int rc; - int index = 0; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - /* current standard needs to be an ATV standard */ - if (!DRXJ_ISATVSTD(ext_attr->standard)) - return -EIO; - - /* Check arguments */ - if (coef == NULL) - return -EINVAL; - rc = atv_equ_coef_index(ext_attr->standard, &index); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - coef->coef0 = ext_attr->atv_top_equ0[index]; - coef->coef1 = ext_attr->atv_top_equ1[index]; - coef->coef2 = ext_attr->atv_top_equ2[index]; - coef->coef3 = ext_attr->atv_top_equ3[index]; +/* 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) */ - return 0; -rw_error: - return -EIO; -} +/* Coefficients for the nyquist fitler (total: 27 taps) */ +#define NYQFILTERLEN 27 -/* -------------------------------------------------------------------------- */ -/** -* \fn int ctrl_set_cfg_atv_misc() -* \brief Set misc. settings for ATV. -* \param demod instance of demodulator -* \param -* \return int. -* -*/ -static int -ctrl_set_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings) +static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param) { - struct drxj_data *ext_attr = NULL; int rc; - - /* Check arguments */ - if ((settings == NULL) || - ((settings->peak_filter) < (s16) (-8)) || - ((settings->peak_filter) > (s16) (15)) || - ((settings->noise_filter) > 15)) { - return -EINVAL; - } - /* if */ - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - if (settings->peak_filter != ext_attr->atv_top_vid_peak) { - ext_attr->atv_top_vid_peak = settings->peak_filter; - ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_PEAK_FLT; - } - - if (settings->noise_filter != ext_attr->atv_top_noise_th) { - ext_attr->atv_top_noise_th = settings->noise_filter; - ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_NOISE_FLT; - } - - rc = atv_update_config(demod, false); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} - -/* -------------------------------------------------------------------------- */ -/** -* \fn int ctrl_get_cfg_atv_misc() -* \brief Get misc settings of ATV. -* \param demod instance of demodulator -* \param settings misc. ATV settings -* \return int. -* -* The values are read from the shadow registers maintained by the drxdriver -* If registers are manipulated outside of the drxdriver scope the reported -* settings will not reflect these changes because of the use of shadow -* regitsers. -*/ -static int -ctrl_get_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings) -{ + 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; - /* Check arguments */ - if (settings == NULL) - return -EINVAL; - + 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; - settings->peak_filter = ext_attr->atv_top_vid_peak; - settings->noise_filter = ext_attr->atv_top_noise_th; - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -/** -* \fn int ctrl_get_cfg_atv_output() -* \brief -* \param demod instance of demodulator -* \param output_cfg output configuaration -* \return int. -* -*/ -static int -ctrl_get_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg) -{ - int rc; - u16 data = 0; - - /* Check arguments */ - if (output_cfg == NULL) - return -EINVAL; - - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, ATV_TOP_STDBY__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) - output_cfg->enable_cvbs_output = true; - else - output_cfg->enable_cvbs_output = false; - - if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) { - output_cfg->enable_sif_output = false; - } else { - output_cfg->enable_sif_output = true; - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, ATV_TOP_AF_SIF_ATT__A, &data, 0); + /* 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; } - output_cfg->sif_attenuation = (enum drxjsif_attenuation) data; - } - - return 0; -rw_error: - return -EIO; -} - -/* -------------------------------------------------------------------------- */ -/** -* \fn int ctrl_get_cfg_atv_agc_status() -* \brief -* \param demod instance of demodulator -* \param agc_status agc status -* \return int. -* -*/ -static int -ctrl_get_cfg_atv_agc_status(struct drx_demod_instance *demod, - struct drxj_cfg_atv_agc_status *agc_status) -{ - struct i2c_device_addr *dev_addr = NULL; - int rc; - u16 data = 0; - u32 tmp = 0; - /* Check arguments */ - if (agc_status == NULL) - return -EINVAL; + ext_attr->oob_power_on = false; + return 0; + } - dev_addr = demod->my_i2c_dev_addr; + freq = oob_param->frequency; + if ((freq < 70000) || (freq > 130000)) + return -EIO; + freq = (freq - 50000) / 50; - /* - RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA) - = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000 + { + u16 index = 0; + u16 remainder = 0; + u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg; - IQM_AF_AGC_RF__A * 27 is 20 bits worst case. - */ - rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &data, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; + 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; } - tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */ - agc_status->rf_agc_gain = (u16) (tmp / 1000); /* uA */ - /* rounding */ - if (tmp % 1000 >= 500) - (agc_status->rf_agc_gain)++; - - /* - IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA) - = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000 - IQM_AF_AGC_IF__A * 27 is 20 bits worst case. - */ - rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &data, 0); + /*********/ + /* 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; } - tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */ - agc_status->if_agc_gain = (u16) (tmp / 1000); /* uA */ - /* rounding */ - if (tmp % 1000 >= 500) - (agc_status->if_agc_gain)++; - - /* - videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB) - = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB) - = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB) - = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB) - = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB) - */ - - rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &data, 0); + 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; } - /* dividing by 32 inclusive rounding */ - data >>= 4; - if ((data & 1) != 0) - data++; - data >>= 1; - agc_status->video_agc_gain = ((s16) data) - 75; /* 0.1 dB */ - - /* - audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB) - = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB) - = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB) - = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB) - = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB) - */ - - rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &data, 0); - if (rc != 0) { + /*********/ + /* 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; } - data &= SCU_RAM_ATV_SIF_GAIN__M; - /* dividing by 2 inclusive rounding */ - if ((data & 1) != 0) - data++; - data >>= 1; - agc_status->audio_agc_gain = ((s16) data) - 4; /* 0.1 dB */ - - /* Loop gain's */ - rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0); + /***********/ + /* 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; } - agc_status->video_agc_loop_gain = - ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B); - agc_status->rf_agc_loop_gain = - ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B); - agc_status->if_agc_loop_gain = - ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B); - - return 0; -rw_error: - return -EIO; -} -/* -------------------------------------------------------------------------- */ - -/** -* \fn int power_up_atv () -* \brief Power up ATV. -* \param demod instance of demodulator -* \param standard either NTSC or FM (sub strandard for ATV ) -* \return int. -* -* * Starts ATV and IQM -* * AUdio already started during standard init for ATV. -*/ -static int power_up_atv(struct drx_demod_instance *demod, enum drx_standard standard) -{ - struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; - int rc; + 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 */ - /* ATV NTSC */ - rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE, 0); + 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; } - /* turn on IQM_AF */ - rc = set_iqm_af(demod, true); + 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 = adc_synchronization(demod); + 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; } - rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0); + /* 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; } - /* Audio, already done during set standard */ - - return 0; -rw_error: - return -EIO; -} -#endif - -/* -------------------------------------------------------------------------- */ - -/** -* \fn int power_down_atv () -* \brief Power down ATV. -* \param demod instance of demodulator -* \param standard either NTSC or FM (sub strandard for ATV ) -* \return int. -* -* Stops and thus resets ATV and IQM block -* SIF and CVBS ADC are powered down -* Calls audio power down -*/ -static int -power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary) -{ - struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; - struct drxjscu_cmd cmd_scu = { /* command */ 0, - /* parameter_len */ 0, - /* result_len */ 0, - /* *parameter */ NULL, - /* *result */ NULL - }; - int rc; - u16 cmd_result = 0; - - /* ATV NTSC */ + /* 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; + } - /* Stop ATV SCU (will reset ATV and IQM hardware */ - cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV | - SCU_RAM_COMMAND_CMD_DEMOD_STOP; - 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); + /* 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; } - /* Disable ATV outputs (ATV reset enables CVBS, undo this) */ - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0); + 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; } - rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0); + /* 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; } - if (primary) { - rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = set_iqm_af(demod, false); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - } else { - rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 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 = power_down_aud(demod); + 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; } - return 0; -rw_error: - return -EIO; -} - -/* -------------------------------------------------------------------------- */ -/** -* \fn int set_atv_standard () -* \brief Set up ATV demodulator. -* \param demod instance of demodulator -* \param standard either NTSC or FM (sub strandard for ATV ) -* \return int. -* -* Init all channel independent registers. -* Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode -* -*/ -#if 0 -#define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */ -static int -set_atv_standard(struct drx_demod_instance *demod, enum drx_standard *standard) -{ -/* TODO: enable alternative for tap settings via external file - -something like: -#ifdef DRXJ_ATV_COEF_FILE -#include DRXJ_ATV_COEF_FILE -#else -... code defining fixed coef's ... -#endif - -Cutsomer must create file "customer_coefs.c.inc" containing -modified copy off the constants below, and define the compiler -switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc". - -Still to check if this will work; DRXJ_16TO8 macro may cause -trouble ? -*/ - const u8 ntsc_taps_re[] = { - DRXJ_16TO8(-12), /* re0 */ - DRXJ_16TO8(-9), /* re1 */ - DRXJ_16TO8(9), /* re2 */ - DRXJ_16TO8(19), /* re3 */ - DRXJ_16TO8(-4), /* re4 */ - DRXJ_16TO8(-24), /* re5 */ - DRXJ_16TO8(-6), /* re6 */ - DRXJ_16TO8(16), /* re7 */ - DRXJ_16TO8(6), /* re8 */ - DRXJ_16TO8(-16), /* re9 */ - DRXJ_16TO8(-5), /* re10 */ - DRXJ_16TO8(13), /* re11 */ - DRXJ_16TO8(-2), /* re12 */ - DRXJ_16TO8(-20), /* re13 */ - DRXJ_16TO8(4), /* re14 */ - DRXJ_16TO8(25), /* re15 */ - DRXJ_16TO8(-6), /* re16 */ - DRXJ_16TO8(-36), /* re17 */ - DRXJ_16TO8(2), /* re18 */ - DRXJ_16TO8(38), /* re19 */ - DRXJ_16TO8(-10), /* re20 */ - DRXJ_16TO8(-48), /* re21 */ - DRXJ_16TO8(35), /* re22 */ - DRXJ_16TO8(94), /* re23 */ - DRXJ_16TO8(-59), /* re24 */ - DRXJ_16TO8(-217), /* re25 */ - DRXJ_16TO8(50), /* re26 */ - DRXJ_16TO8(679) /* re27 */ - }; - const u8 ntsc_taps_im[] = { - DRXJ_16TO8(11), /* im0 */ - DRXJ_16TO8(1), /* im1 */ - DRXJ_16TO8(-10), /* im2 */ - DRXJ_16TO8(2), /* im3 */ - DRXJ_16TO8(24), /* im4 */ - DRXJ_16TO8(21), /* im5 */ - DRXJ_16TO8(1), /* im6 */ - DRXJ_16TO8(-4), /* im7 */ - DRXJ_16TO8(7), /* im8 */ - DRXJ_16TO8(14), /* im9 */ - DRXJ_16TO8(27), /* im10 */ - DRXJ_16TO8(42), /* im11 */ - DRXJ_16TO8(22), /* im12 */ - DRXJ_16TO8(-20), /* im13 */ - DRXJ_16TO8(2), /* im14 */ - DRXJ_16TO8(98), /* im15 */ - DRXJ_16TO8(122), /* im16 */ - DRXJ_16TO8(0), /* im17 */ - DRXJ_16TO8(-85), /* im18 */ - DRXJ_16TO8(51), /* im19 */ - DRXJ_16TO8(247), /* im20 */ - DRXJ_16TO8(192), /* im21 */ - DRXJ_16TO8(-55), /* im22 */ - DRXJ_16TO8(-95), /* im23 */ - DRXJ_16TO8(217), /* im24 */ - DRXJ_16TO8(544), /* im25 */ - DRXJ_16TO8(553), /* im26 */ - DRXJ_16TO8(302) /* im27 */ - }; - const u8 bg_taps_re[] = { - DRXJ_16TO8(-18), /* re0 */ - DRXJ_16TO8(18), /* re1 */ - DRXJ_16TO8(19), /* re2 */ - DRXJ_16TO8(-26), /* re3 */ - DRXJ_16TO8(-20), /* re4 */ - DRXJ_16TO8(36), /* re5 */ - DRXJ_16TO8(5), /* re6 */ - DRXJ_16TO8(-51), /* re7 */ - DRXJ_16TO8(15), /* re8 */ - DRXJ_16TO8(45), /* re9 */ - DRXJ_16TO8(-46), /* re10 */ - DRXJ_16TO8(-24), /* re11 */ - DRXJ_16TO8(71), /* re12 */ - DRXJ_16TO8(-17), /* re13 */ - DRXJ_16TO8(-83), /* re14 */ - DRXJ_16TO8(74), /* re15 */ - DRXJ_16TO8(75), /* re16 */ - DRXJ_16TO8(-134), /* re17 */ - DRXJ_16TO8(-40), /* re18 */ - DRXJ_16TO8(191), /* re19 */ - DRXJ_16TO8(-11), /* re20 */ - DRXJ_16TO8(-233), /* re21 */ - DRXJ_16TO8(74), /* re22 */ - DRXJ_16TO8(271), /* re23 */ - DRXJ_16TO8(-132), /* re24 */ - DRXJ_16TO8(-341), /* re25 */ - DRXJ_16TO8(172), /* re26 */ - DRXJ_16TO8(801) /* re27 */ - }; - const u8 bg_taps_im[] = { - DRXJ_16TO8(-24), /* im0 */ - DRXJ_16TO8(-10), /* im1 */ - DRXJ_16TO8(9), /* im2 */ - DRXJ_16TO8(-5), /* im3 */ - DRXJ_16TO8(-51), /* im4 */ - DRXJ_16TO8(-17), /* im5 */ - DRXJ_16TO8(31), /* im6 */ - DRXJ_16TO8(-48), /* im7 */ - DRXJ_16TO8(-95), /* im8 */ - DRXJ_16TO8(25), /* im9 */ - DRXJ_16TO8(37), /* im10 */ - DRXJ_16TO8(-123), /* im11 */ - DRXJ_16TO8(-77), /* im12 */ - DRXJ_16TO8(94), /* im13 */ - DRXJ_16TO8(-10), /* im14 */ - DRXJ_16TO8(-149), /* im15 */ - DRXJ_16TO8(10), /* im16 */ - DRXJ_16TO8(108), /* im17 */ - DRXJ_16TO8(-49), /* im18 */ - DRXJ_16TO8(-59), /* im19 */ - DRXJ_16TO8(90), /* im20 */ - DRXJ_16TO8(73), /* im21 */ - DRXJ_16TO8(55), /* im22 */ - DRXJ_16TO8(148), /* im23 */ - DRXJ_16TO8(86), /* im24 */ - DRXJ_16TO8(146), /* im25 */ - DRXJ_16TO8(687), /* im26 */ - DRXJ_16TO8(877) /* im27 */ - }; - const u8 dk_i_l_lp_taps_re[] = { - DRXJ_16TO8(-23), /* re0 */ - DRXJ_16TO8(9), /* re1 */ - DRXJ_16TO8(16), /* re2 */ - DRXJ_16TO8(-26), /* re3 */ - DRXJ_16TO8(-3), /* re4 */ - DRXJ_16TO8(13), /* re5 */ - DRXJ_16TO8(-19), /* re6 */ - DRXJ_16TO8(-3), /* re7 */ - DRXJ_16TO8(13), /* re8 */ - DRXJ_16TO8(-26), /* re9 */ - DRXJ_16TO8(-4), /* re10 */ - DRXJ_16TO8(28), /* re11 */ - DRXJ_16TO8(-15), /* re12 */ - DRXJ_16TO8(-14), /* re13 */ - DRXJ_16TO8(10), /* re14 */ - DRXJ_16TO8(1), /* re15 */ - DRXJ_16TO8(39), /* re16 */ - DRXJ_16TO8(-18), /* re17 */ - DRXJ_16TO8(-90), /* re18 */ - DRXJ_16TO8(109), /* re19 */ - DRXJ_16TO8(113), /* re20 */ - DRXJ_16TO8(-235), /* re21 */ - DRXJ_16TO8(-49), /* re22 */ - DRXJ_16TO8(359), /* re23 */ - DRXJ_16TO8(-79), /* re24 */ - DRXJ_16TO8(-459), /* re25 */ - DRXJ_16TO8(206), /* re26 */ - DRXJ_16TO8(894) /* re27 */ - }; - const u8 dk_i_l_lp_taps_im[] = { - DRXJ_16TO8(-8), /* im0 */ - DRXJ_16TO8(-20), /* im1 */ - DRXJ_16TO8(17), /* im2 */ - DRXJ_16TO8(-14), /* im3 */ - DRXJ_16TO8(-52), /* im4 */ - DRXJ_16TO8(4), /* im5 */ - DRXJ_16TO8(9), /* im6 */ - DRXJ_16TO8(-62), /* im7 */ - DRXJ_16TO8(-47), /* im8 */ - DRXJ_16TO8(0), /* im9 */ - DRXJ_16TO8(-20), /* im10 */ - DRXJ_16TO8(-48), /* im11 */ - DRXJ_16TO8(-65), /* im12 */ - DRXJ_16TO8(-23), /* im13 */ - DRXJ_16TO8(44), /* im14 */ - DRXJ_16TO8(-60), /* im15 */ - DRXJ_16TO8(-113), /* im16 */ - DRXJ_16TO8(92), /* im17 */ - DRXJ_16TO8(81), /* im18 */ - DRXJ_16TO8(-125), /* im19 */ - DRXJ_16TO8(28), /* im20 */ - DRXJ_16TO8(182), /* im21 */ - DRXJ_16TO8(35), /* im22 */ - DRXJ_16TO8(94), /* im23 */ - DRXJ_16TO8(180), /* im24 */ - DRXJ_16TO8(134), /* im25 */ - DRXJ_16TO8(657), /* im26 */ - DRXJ_16TO8(1023) /* im27 */ - }; - const u8 fm_taps_re[] = { - DRXJ_16TO8(0), /* re0 */ - DRXJ_16TO8(0), /* re1 */ - DRXJ_16TO8(0), /* re2 */ - DRXJ_16TO8(0), /* re3 */ - DRXJ_16TO8(0), /* re4 */ - DRXJ_16TO8(0), /* re5 */ - DRXJ_16TO8(0), /* re6 */ - DRXJ_16TO8(0), /* re7 */ - DRXJ_16TO8(0), /* re8 */ - DRXJ_16TO8(0), /* re9 */ - DRXJ_16TO8(0), /* re10 */ - DRXJ_16TO8(0), /* re11 */ - DRXJ_16TO8(0), /* re12 */ - DRXJ_16TO8(0), /* re13 */ - DRXJ_16TO8(0), /* re14 */ - DRXJ_16TO8(0), /* re15 */ - DRXJ_16TO8(0), /* re16 */ - DRXJ_16TO8(0), /* re17 */ - DRXJ_16TO8(0), /* re18 */ - DRXJ_16TO8(0), /* re19 */ - DRXJ_16TO8(0), /* re20 */ - DRXJ_16TO8(0), /* re21 */ - DRXJ_16TO8(0), /* re22 */ - DRXJ_16TO8(0), /* re23 */ - DRXJ_16TO8(0), /* re24 */ - DRXJ_16TO8(0), /* re25 */ - DRXJ_16TO8(0), /* re26 */ - DRXJ_16TO8(0) /* re27 */ - }; - const u8 fm_taps_im[] = { - DRXJ_16TO8(-6), /* im0 */ - DRXJ_16TO8(2), /* im1 */ - DRXJ_16TO8(14), /* im2 */ - DRXJ_16TO8(-38), /* im3 */ - DRXJ_16TO8(58), /* im4 */ - DRXJ_16TO8(-62), /* im5 */ - DRXJ_16TO8(42), /* im6 */ - DRXJ_16TO8(0), /* im7 */ - DRXJ_16TO8(-45), /* im8 */ - DRXJ_16TO8(73), /* im9 */ - DRXJ_16TO8(-65), /* im10 */ - DRXJ_16TO8(23), /* im11 */ - DRXJ_16TO8(34), /* im12 */ - DRXJ_16TO8(-77), /* im13 */ - DRXJ_16TO8(80), /* im14 */ - DRXJ_16TO8(-39), /* im15 */ - DRXJ_16TO8(-25), /* im16 */ - DRXJ_16TO8(78), /* im17 */ - DRXJ_16TO8(-90), /* im18 */ - DRXJ_16TO8(52), /* im19 */ - DRXJ_16TO8(16), /* im20 */ - DRXJ_16TO8(-77), /* im21 */ - DRXJ_16TO8(97), /* im22 */ - DRXJ_16TO8(-62), /* im23 */ - DRXJ_16TO8(-8), /* im24 */ - DRXJ_16TO8(75), /* im25 */ - DRXJ_16TO8(-100), /* im26 */ - DRXJ_16TO8(70) /* im27 */ - }; + /* 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; + } - struct i2c_device_addr *dev_addr = NULL; - struct drxjscu_cmd cmd_scu = { /* command */ 0, - /* parameter_len */ 0, - /* result_len */ 0, - /* *parameter */ NULL, - /* *result */ NULL - }; - u16 cmd_result = 0; - u16 cmd_param = 0; - struct drxj_data *ext_attr = NULL; - int rc; + /* 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; + } - ext_attr = (struct drxj_data *) demod->my_ext_attr; - dev_addr = demod->my_i2c_dev_addr; + /* 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; + } - rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0); + /* 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, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0); + 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, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0); + 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, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0); + 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, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0); + 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; } - rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0); + + /* 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; } - /* Reset ATV SCU */ - cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV | - SCU_RAM_COMMAND_CMD_DEMOD_RESET; - 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); + 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; } - rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE, 0); + /* 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; } - /* TODO remove AUTO/OFF patches after ucode fix. */ - switch (*standard) { - case DRX_STANDARD_NTSC: - /* NTSC */ - cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_MN; + /* 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; + } - rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN, 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(ntsc_taps_re), ((u8 *)ntsc_taps_re), 0); + /* 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 = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im), ((u8 *)ntsc_taps_im), 0); + 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 = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN, 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_MN | ATV_TOP_CR_CONT_CR_D_MN | ATV_TOP_CR_CONT_CR_I_MN), 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_MN, 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_MN | ATV_TOP_STD_VID_POL_MN), 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_MN, 0); - 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; + } - 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; + ext_attr->oob_power_on = true; -#if 0 - /* Initialize default AFE configuartion for ATV */ - ext_attr->atv_rf_agc_cfg.standard = DRX_STANDARD_NTSC; - ext_attr->atv_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO; - ext_attr->atv_rf_agc_cfg.top = 9500; - ext_attr->atv_rf_agc_cfg.cut_off_current = 4000; - ext_attr->atv_rf_agc_cfg.speed = 3; - ext_attr->atv_if_agc_cfg.standard = DRX_STANDARD_NTSC; - ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO; - ext_attr->atv_if_agc_cfg.speed = 3; - ext_attr->atv_if_agc_cfg.top = 2400; - ext_attr->atv_pre_saw_cfg.reference = 0x0007; - ext_attr->atv_pre_saw_cfg.use_pre_saw = true; - ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC; -#endif + return 0; +rw_error: + return -EIO; } +/*============================================================================*/ +/*== END OOB DATAPATH FUNCTIONS ==*/ +/*============================================================================*/ + +/*============================================================================= + ===== MC command related functions ========================================== + ===========================================================================*/ + +/*============================================================================= + ===== ctrl_set_channel() ========================================================== + ===========================================================================*/ /** -* \fn int ctrl_power_mode() -* \brief Set the power mode of the device to the specified power mode -* \param demod Pointer to demodulator instance. -* \param mode Pointer to new power mode. +* \fn int ctrl_set_channel() +* \brief Select a new transmission channel. +* \param demod instance of demod. +* \param channel Pointer to channel data. * \return int. -* \retval 0 Success -* \retval -EIO I2C error or other failure -* \retval -EINVAL Invalid mode argument. * +* 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_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode) +ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel) { - struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL; - struct drxj_data *ext_attr = (struct drxj_data *) NULL; - struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL; int rc; - u16 sio_cc_pwd_mode = 0; + 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; - ext_attr = (struct drxj_data *) demod->my_ext_attr; dev_addr = demod->my_i2c_dev_addr; + ext_attr = (struct drxj_data *) demod->my_ext_attr; + standard = ext_attr->standard; - /* Check arguments */ - if (mode == NULL) - return -EINVAL; - - /* If already in requested power mode, do nothing */ - if (common_attr->current_power_mode == *mode) - return 0; - - switch (*mode) { - case DRX_POWER_UP: - case DRXJ_POWER_DOWN_MAIN_PATH: - sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE; - break; - case DRXJ_POWER_DOWN_CORE: - sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK; - break; - case DRXJ_POWER_DOWN_PLL: - sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL; - break; - case DRX_POWER_DOWN: - sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC; + /* 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 */ break; + case DRX_STANDARD_UNKNOWN: default: - /* Unknow sleep mode */ return -EINVAL; - break; } - /* Check if device needs to be powered up */ - if ((common_attr->current_power_mode != DRX_POWER_UP)) { - rc = power_up_device(demod); + /* 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; + } + } + + /* 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 ((*mode == DRX_POWER_UP)) { - /* Restore analog & pin configuartion */ + if (channel->symbolrate < min_symbol_rate || + channel->symbolrate > max_symbol_rate) { + return -EINVAL; + } - /* Initialize default AFE configuartion for VSB */ - drxj_reset_mode(ext_attr); - } else { - /* Power down to requested mode */ - /* Backup some register settings */ - /* Set pins with possible pull-ups connected to them in input mode */ - /* Analog power down */ - /* ADC power down */ - /* Power down device */ - /* stop all comm_exec */ - /* - Stop and power down previous standard - */ + 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; - switch (ext_attr->standard) { - case DRX_STANDARD_ITU_A: - case DRX_STANDARD_ITU_B: - case DRX_STANDARD_ITU_C: - rc = power_down_qam(demod, true); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - break; - case DRX_STANDARD_8VSB: - rc = power_down_vsb(demod, true); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; + 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; - 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: /* fallthrough */ - case DRX_STANDARD_FM: - rc = power_down_atv(demod, ext_attr->standard, true); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } + 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; - case DRX_STANDARD_UNKNOWN: - /* Do nothing */ + 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; - case DRX_STANDARD_AUTO: /* fallthrough */ default: - return -EIO; + return -EINVAL; } - ext_attr->standard = DRX_STANDARD_UNKNOWN; } - if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) { - rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; + 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 = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0); + + rc = ctrl_uio_write(demod, &uio1); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - - if ((*mode != DRX_POWER_UP)) { - /* Initialize HI, wakeup key especially before put IC to sleep */ - rc = init_hi(demod); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; - rc = hi_cfg_command(demod); - 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; } - common_attr->current_power_mode = *mode; - - return 0; -rw_error: - return rc; -} - -#if 0 -/*============================================================================*/ - -/** -* \fn int ctrl_probe_device() -* \brief Probe device, check if it is present -* \param demod Pointer to demodulator instance. -* \return int. -* \retval 0 a drx39xxj device has been detected. -* \retval -EIO no drx39xxj device detected. -* -* This funtion can be caled before open() and after close(). -* -*/ - -static int ctrl_probe_device(struct drx_demod_instance *demod) -{ - enum drx_power_mode org_power_mode = DRX_POWER_UP; - int ret_status = 0; - struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL); - int rc; - - common_attr = (struct drx_common_attr *) demod->my_common_attr; - - if (common_attr->is_opened == false - || common_attr->current_power_mode != DRX_POWER_UP) { - struct i2c_device_addr *dev_addr = NULL; - enum drx_power_mode power_mode = DRX_POWER_UP; - u32 jtag = 0; - - dev_addr = demod->my_i2c_dev_addr; - - /* Remeber original power mode */ - org_power_mode = common_attr->current_power_mode; + tuner_freq_offset = 0; + intermediate_freq = demod->my_common_attr->intermediate_freq; - if (demod->my_common_attr->is_opened == false) { - rc = power_up_device(demod); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - common_attr->current_power_mode = DRX_POWER_UP; - } else { - /* Wake-up device, feedback from device */ - rc = ctrl_power_mode(demod, &power_mode); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - } - /* Initialize HI, wakeup key especially */ - rc = init_hi(demod); + /*== 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; } - - /* Check device id */ - rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0); + rc = set_frequency(demod, channel, tuner_freq_offset); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - jtag = (jtag >> 12) & 0xFFFF; - switch (jtag) { - case 0x3931: /* fallthrough */ - case 0x3932: /* fallthrough */ - case 0x3933: /* fallthrough */ - case 0x3934: /* fallthrough */ - case 0x3941: /* fallthrough */ - case 0x3942: /* fallthrough */ - case 0x3943: /* fallthrough */ - case 0x3944: /* fallthrough */ - case 0x3945: /* fallthrough */ - case 0x3946: - /* ok , do nothing */ - break; - default: - ret_status = -EIO; - break; - } - - /* Device was not opened, return to orginal powermode, - feedback from device */ - rc = ctrl_power_mode(demod, &org_power_mode); + break; +#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; } - } else { - /* dummy read to make this function fail in case device - suddenly disappears after a succesful drx_open */ - 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_UNKNOWN: + default: + return -EIO; } - return ret_status; + /* flag the packet error counter reset */ + ext_attr->reset_pkt_err_acc = true; + return 0; rw_error: - common_attr->current_power_mode = org_power_mode; return -EIO; } -#endif -/*============================================================================*/ -/*== CTRL Set/Get Config related functions ===================================*/ -/*============================================================================*/ +/*============================================================================= + ===== 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; +} -#if 0 -/*===== SigStrength() =========================================================*/ /** -* \fn int ctrl_sig_strength() -* \brief Retrieve signal strength. +* \fn int ctrl_sig_quality() +* \brief Retreive signal quality form device. * \param devmod Pointer to demodulator instance. -* \param sig_quality Pointer to signal strength data; range 0, .. , 100. +* \param sig_quality Pointer to signal quality data. * \return int. -* \retval 0 sig_strength contains valid data. -* \retval -EINVAL sig_strength is NULL. -* \retval -EIO Erroneous data, sig_strength contains invalid data. +* \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_strength(struct drx_demod_instance *demod, u16 *sig_strength) +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; - enum drx_standard standard = DRX_STANDARD_UNKNOWN; 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_strength == NULL) || (demod == NULL)) + if ((sig_quality == NULL) || (demod == NULL)) return -EINVAL; ext_attr = (struct drxj_data *) demod->my_ext_attr; standard = ext_attr->standard; - *sig_strength = 0; - /* Signal strength indication for each 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: /* fallthrough */ + 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: /* fallthrough */ - case DRX_STANDARD_ITU_B: /* fallthrough */ + case DRX_STANDARD_ITU_A: + case DRX_STANDARD_ITU_B: case DRX_STANDARD_ITU_C: -#endif - rc = get_sig_strength(demod, sig_strength); + rc = ctrl_get_qam_sig_quality(demod, sig_quality); if (rc != 0) { pr_err("error %d\n", rc); goto rw_error; } - break; - 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: /* fallthrough */ - case DRX_STANDARD_FM: - rc = get_atv_sig_strength(demod, sig_strength); - 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; - case DRX_STANDARD_UNKNOWN: /* fallthrough */ +#endif default: - return -EINVAL; + return -EIO; } - /* TODO */ - /* find out if signal strength is calculated in the same way for all standards */ return 0; rw_error: return -EIO; } /*============================================================================*/ -/** -* \fn int ctrl_get_cfg_oob_misc() -* \brief Get current state information of OOB. -* \param pointer to struct drxj_cfg_oob_misc. -* \return int. -* -*/ -static int -ctrl_get_cfg_oob_misc(struct drx_demod_instance *demod, struct drxj_cfg_oob_misc *misc) -{ - struct i2c_device_addr *dev_addr = NULL; - int rc; - u16 lock = 0U; - u16 state = 0U; - u16 data = 0U; - u16 digital_agc_mant = 0U; - u16 digital_agc_exp = 0U; - - /* check arguments */ - if (misc == NULL) - return -EINVAL; - - dev_addr = demod->my_i2c_dev_addr; - - /* TODO */ - /* check if the same registers are used for all standards (QAM/VSB/ATV) */ - rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC, 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, &misc->agc.RFAGC, 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; - } - - digital_agc_mant = data & ORX_FWP_SRC_DGN_W_MANT__M; - digital_agc_exp = (data & ORX_FWP_SRC_DGN_W_EXP__M) - >> ORX_FWP_SRC_DGN_W_EXP__B; - misc->agc.digital_agc = digital_agc_mant << digital_agc_exp; - - rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_LOCK__A, &lock, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - misc->ana_gain_lock = ((lock & 0x0001) ? true : false); - misc->dig_gain_lock = ((lock & 0x0002) ? true : false); - misc->freq_lock = ((lock & 0x0004) ? true : false); - misc->phase_lock = ((lock & 0x0008) ? true : false); - misc->sym_timing_lock = ((lock & 0x0010) ? true : false); - misc->eq_lock = ((lock & 0x0020) ? true : false); - - rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_STATE__A, &state, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - misc->state = (state >> 8) & 0xff; - - return 0; -rw_error: - return -EIO; -} /** -* \fn int ctrl_get_cfg_vsb_misc() -* \brief Get current state information of OOB. -* \param pointer to struct drxj_cfg_oob_misc. +* \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_get_cfg_vsb_misc(struct drx_demod_instance *demod, struct drxj_cfg_vsb_misc *misc) +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 (misc == NULL) + 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; - rc = get_vsb_symb_err(dev_addr, &misc->symb_error); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} - -/*============================================================================*/ - -/** -* \fn int ctrl_set_cfg_agc_if() -* \brief Set IF AGC. -* \param demod demod instance -* \param agc_settings If agc configuration -* \return int. -* -* Check arguments -* Dispatch handling to standard specific function. -* -*/ -static int -ctrl_set_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings) -{ - /* check arguments */ - if (agc_settings == NULL) - return -EINVAL; + *lock_stat = DRX_NOT_LOCKED; - switch (agc_settings->ctrl_mode) { - case DRX_AGC_CTRL_AUTO: /* fallthrough */ - case DRX_AGC_CTRL_USER: /* fallthrough */ - case DRX_AGC_CTRL_OFF: /* fallthrough */ + /* 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; - default: - return -EINVAL; - } - - /* Distpatch */ - switch (agc_settings->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 -#if 0 - 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: /* fallthrough */ - case DRX_STANDARD_FM: -#endif - return set_agc_if(demod, agc_settings, true); - case DRX_STANDARD_UNKNOWN: - default: - return -EINVAL; - } - - return 0; -} - -/*============================================================================*/ - -/** -* \fn int ctrl_get_cfg_agc_if() -* \brief Retrieve IF AGC settings. -* \param demod demod instance -* \param agc_settings If agc configuration -* \return int. -* -* Check arguments -* Dispatch handling to standard specific function. -* -*/ -static int -ctrl_get_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings) -{ - /* check arguments */ - if (agc_settings == NULL) - return -EINVAL; - - /* Distpatch */ - switch (agc_settings->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_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_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: /* fallthrough */ - case DRX_STANDARD_FM: -#endif - return get_agc_if(demod, agc_settings); - case DRX_STANDARD_UNKNOWN: + case DRX_STANDARD_UNKNOWN: /* fallthrough */ default: - return -EINVAL; + return -EIO; } - return 0; -} - -/*============================================================================*/ - -/** -* \fn int ctrl_set_cfg_agc_rf() -* \brief Set RF AGC. -* \param demod demod instance -* \param agc_settings rf agc configuration -* \return int. -* -* Check arguments -* Dispatch handling to standard specific function. -* -*/ -static int -ctrl_set_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings) -{ - /* check arguments */ - if (agc_settings == NULL) - return -EINVAL; - - switch (agc_settings->ctrl_mode) { - case DRX_AGC_CTRL_AUTO: /* fallthrough */ - case DRX_AGC_CTRL_USER: /* fallthrough */ - case DRX_AGC_CTRL_OFF: - break; - default: - return -EINVAL; + /* 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; } - /* Distpatch */ - switch (agc_settings->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 - 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: /* fallthrough */ - case DRX_STANDARD_FM: - return set_agc_rf(demod, agc_settings, true); - case DRX_STANDARD_UNKNOWN: - default: - return -EINVAL; + /* 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; } /*============================================================================*/ /** -* \fn int ctrl_get_cfg_agc_rf() -* \brief Retrieve RF AGC settings. -* \param demod demod instance -* \param agc_settings Rf agc configuration +* \fn int ctrl_set_standard() +* \brief Set modulation standard to be used. +* \param standard Modulation standard. * \return int. * -* Check arguments -* Dispatch handling to standard specific function. +* Setup stuff for the desired demodulation standard. +* Disable and power down the previous selected demodulation standard * */ static int -ctrl_get_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings) +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 (agc_settings == NULL) + if ((standard == NULL) || (demod == NULL)) return -EINVAL; - /* Distpatch */ - switch (agc_settings->standard) { - case DRX_STANDARD_8VSB: /* fallthrough */ + 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_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: /* fallthrough */ - case DRX_STANDARD_FM: - return get_agc_rf(demod, agc_settings); + case DRX_STANDARD_8VSB: + rc = power_down_vsb(demod, false); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + break; 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; 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; } /*============================================================================*/ +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; +} + /** -* \fn int ctrl_get_cfg_agc_internal() -* \brief Retrieve internal AGC value. -* \param demod demod instance -* \param u16 +* \fn int ctrl_power_mode() +* \brief Set the power mode of the device to the specified power mode +* \param demod Pointer to demodulator instance. +* \param mode Pointer to new power mode. * \return int. +* \retval 0 Success +* \retval -EIO I2C error or other failure +* \retval -EINVAL Invalid mode argument. * -* Check arguments -* Dispatch handling to standard specific function. * */ static int -ctrl_get_cfg_agc_internal(struct drx_demod_instance *demod, u16 *agc_internal) +ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode) { - struct i2c_device_addr *dev_addr = NULL; + struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL; + struct drxj_data *ext_attr = (struct drxj_data *) NULL; + struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL; int rc; - enum drx_lock_status lock_status = DRX_NOT_LOCKED; - struct drxj_data *ext_attr = NULL; - u16 iqm_cf_scale_sh = 0; - u16 iqm_cf_power = 0; - u16 iqm_cf_amp = 0; - u16 iqm_cf_gain = 0; + u16 sio_cc_pwd_mode = 0; - /* check arguments */ - if (agc_internal == NULL) - return -EINVAL; - dev_addr = demod->my_i2c_dev_addr; + common_attr = (struct drx_common_attr *) demod->my_common_attr; ext_attr = (struct drxj_data *) demod->my_ext_attr; + 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; - } - if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) { - *agc_internal = 0; + /* Check arguments */ + if (mode == NULL) + return -EINVAL; + + /* If already in requested power mode, do nothing */ + if (common_attr->current_power_mode == *mode) return 0; - } - /* Distpatch */ - switch (ext_attr->standard) { - case DRX_STANDARD_8VSB: - iqm_cf_gain = 57; + switch (*mode) { + case DRX_POWER_UP: + case DRXJ_POWER_DOWN_MAIN_PATH: + sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE; break; -#ifndef DRXJ_VSB_ONLY - case DRX_STANDARD_ITU_A: - case DRX_STANDARD_ITU_B: - case DRX_STANDARD_ITU_C: - switch (ext_attr->constellation) { - case DRX_CONSTELLATION_QAM256: - case DRX_CONSTELLATION_QAM128: - case DRX_CONSTELLATION_QAM32: - case DRX_CONSTELLATION_QAM16: - iqm_cf_gain = 57; + case DRXJ_POWER_DOWN_CORE: + sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK; + break; + case DRXJ_POWER_DOWN_PLL: + sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL; + break; + case DRX_POWER_DOWN: + sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC; + break; + default: + /* Unknow sleep mode */ + return -EINVAL; + break; + } + + /* Check if device needs to be powered up */ + if ((common_attr->current_power_mode != DRX_POWER_UP)) { + rc = power_up_device(demod); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + } + + if ((*mode == DRX_POWER_UP)) { + /* Restore analog & pin configuartion */ + + /* Initialize default AFE configuartion for VSB */ + drxj_reset_mode(ext_attr); + } else { + /* Power down to requested mode */ + /* Backup some register settings */ + /* Set pins with possible pull-ups connected to them in input mode */ + /* Analog power down */ + /* ADC power down */ + /* Power down device */ + /* stop all comm_exec */ + /* + Stop and power down previous standard + */ + + switch (ext_attr->standard) { + case DRX_STANDARD_ITU_A: + case DRX_STANDARD_ITU_B: + case DRX_STANDARD_ITU_C: + rc = power_down_qam(demod, true); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + break; + case DRX_STANDARD_8VSB: + rc = power_down_vsb(demod, true); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + break; + 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: /* fallthrough */ + case DRX_STANDARD_FM: + rc = power_down_atv(demod, ext_attr->standard, true); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } break; - case DRX_CONSTELLATION_QAM64: - iqm_cf_gain = 56; + case DRX_STANDARD_UNKNOWN: + /* Do nothing */ break; + case DRX_STANDARD_AUTO: /* fallthrough */ default: return -EIO; } - break; -#endif - default: - return -EINVAL; + ext_attr->standard = DRX_STANDARD_UNKNOWN; } - rc = drxj_dap_read_reg16(dev_addr, IQM_CF_POW__A, &iqm_cf_power, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_read_reg16(dev_addr, IQM_CF_SCALE_SH__A, &iqm_cf_scale_sh, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - rc = drxj_dap_read_reg16(dev_addr, IQM_CF_AMP__A, &iqm_cf_amp, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; + if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) { + rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + + if ((*mode != DRX_POWER_UP)) { + /* Initialize HI, wakeup key especially before put IC to sleep */ + rc = init_hi(demod); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + + ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; + rc = hi_cfg_command(demod); + if (rc != 0) { + pr_err("error %d\n", rc); + goto rw_error; + } + } } - /* IQM_CF_PWR_CORRECTION_dB = 3; - P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */ - /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10 - -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10) - +6*7+10*log10(1+0.115/4); */ - /* PadcdB = P4dB +3 -6 +60; dBmV */ - *agc_internal = (u16) (log1_times100(iqm_cf_power) - - 2 * log1_times100(iqm_cf_amp) - - iqm_cf_gain - 120 * iqm_cf_scale_sh + 781); + + common_attr->current_power_mode = *mode; return 0; rw_error: - return -EIO; + return rc; } /*============================================================================*/ -#endif +/*== CTRL Set/Get Config related functions ===================================*/ +/*============================================================================*/ /** * \fn int ctrl_set_cfg_pre_saw() @@ -19268,17 +11179,6 @@ ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw * case DRX_STANDARD_ITU_C: ext_attr->qam_pre_saw_cfg = *pre_saw; break; -#endif -#if 0 - 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: /* fallthrough */ - case DRX_STANDARD_FM: - ext_attr->atv_pre_saw_cfg = *pre_saw; - break; #endif default: return -EINVAL; @@ -19372,419 +11272,6 @@ rw_error: /*============================================================================*/ -#if 0 -/** -* \fn int ctrl_get_cfg_pre_saw() -* \brief Get Pre-saw reference setting. -* \param demod demod instance -* \param u16 * -* \return int. -* -* Check arguments -* Dispatch handling to standard specific function. -* -*/ -static int -ctrl_get_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw) -{ - struct drxj_data *ext_attr = NULL; - - /* check arguments */ - if (pre_saw == NULL) - return -EINVAL; - - ext_attr = (struct drxj_data *) demod->my_ext_attr; - - switch (pre_saw->standard) { - case DRX_STANDARD_8VSB: - *pre_saw = ext_attr->vsb_pre_saw_cfg; - break; -#ifndef DRXJ_VSB_ONLY - case DRX_STANDARD_ITU_A: /* fallthrough */ - case DRX_STANDARD_ITU_B: /* fallthrough */ - case DRX_STANDARD_ITU_C: - *pre_saw = ext_attr->qam_pre_saw_cfg; - break; -#endif - 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: - ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC; - *pre_saw = ext_attr->atv_pre_saw_cfg; - break; - case DRX_STANDARD_FM: - ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_FM; - *pre_saw = ext_attr->atv_pre_saw_cfg; - break; - - default: - return -EINVAL; - } - - return 0; -} - -/*============================================================================*/ - -/** -* \fn int ctrl_get_cfg_afe_gain() -* \brief Get AFE Gain. -* \param demod demod instance -* \param u16 * -* \return int. -* -* Check arguments -* Dispatch handling to standard specific function. -* -*/ -static int -ctrl_get_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain) -{ - struct drxj_data *ext_attr = NULL; - - /* check arguments */ - if (afe_gain == NULL) - return -EINVAL; - - ext_attr = demod->my_ext_attr; - - switch (afe_gain->standard) { - case DRX_STANDARD_8VSB: - afe_gain->gain = ext_attr->vsb_pga_cfg; - break; -#ifndef DRXJ_VSB_ONLY - case DRX_STANDARD_ITU_A: /* fallthrough */ - case DRX_STANDARD_ITU_B: /* fallthrough */ - case DRX_STANDARD_ITU_C: - afe_gain->gain = ext_attr->qam_pga_cfg; - break; -#endif - default: - return -EINVAL; - } - - return 0; -} - -/*============================================================================*/ - -/** -* \fn int ctrl_get_fec_meas_seq_count() -* \brief Get FEC measurement sequnce number. -* \param demod demod instance -* \param u16 * -* \return int. -* -* Check arguments -* Dispatch handling to standard specific function. -* -*/ -static int -ctrl_get_fec_meas_seq_count(struct drx_demod_instance *demod, u16 *fec_meas_seq_count) -{ - int rc; - /* check arguments */ - if (fec_meas_seq_count == NULL) - return -EINVAL; - - rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, fec_meas_seq_count, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} - -/*============================================================================*/ - -/** -* \fn int ctrl_get_accum_cr_rs_cw_err() -* \brief Get accumulative corrected RS codeword number. -* \param demod demod instance -* \param u32 * -* \return int. -* -* Check arguments -* Dispatch handling to standard specific function. -* -*/ -static int -ctrl_get_accum_cr_rs_cw_err(struct drx_demod_instance *demod, u32 *accum_cr_rs_cw_err) -{ - int rc; - if (accum_cr_rs_cw_err == NULL) - return -EINVAL; - - rc = drxdap_fasi_read_reg32(demod->my_i2c_dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, accum_cr_rs_cw_err, 0); - if (rc != 0) { - pr_err("error %d\n", rc); - goto rw_error; - } - - return 0; -rw_error: - return -EIO; -} - -/** -* \fn int ctrl_set_cfg() -* \brief Set 'some' configuration of the device. -* \param devmod Pointer to demodulator instance. -* \param config Pointer to configuration parameters (type and data). -* \return int. - -*/ -static int ctrl_set_cfg(struct drx_demod_instance *demod, struct drx_cfg *config) -{ - int rc; - - if (config == NULL) - return -EINVAL; - - 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); - switch (config->cfg_type) { - case DRX_CFG_MPEG_OUTPUT: - return ctrl_set_cfg_mpeg_output(demod, - (struct drx_cfg_mpeg_output *) config-> - cfg_data); - case DRX_CFG_PINS_SAFE_MODE: - return ctrl_set_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data); - case DRXJ_CFG_AGC_RF: - return ctrl_set_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data); - case DRXJ_CFG_AGC_IF: - return ctrl_set_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data); - case DRXJ_CFG_PRE_SAW: - return ctrl_set_cfg_pre_saw(demod, - (struct drxj_cfg_pre_saw *) config->cfg_data); - case DRXJ_CFG_AFE_GAIN: - return ctrl_set_cfg_afe_gain(demod, - (struct drxj_cfg_afe_gain *) config->cfg_data); - case DRXJ_CFG_SMART_ANT: - return ctrl_set_cfg_smart_ant(demod, - (struct drxj_cfg_smart_ant *) (config-> - cfg_data)); - case DRXJ_CFG_RESET_PACKET_ERR: - return ctrl_set_cfg_reset_pkt_err(demod); -#if 0 - case DRXJ_CFG_OOB_PRE_SAW: - return ctrl_set_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data)); - case DRXJ_CFG_OOB_LO_POW: - return ctrl_set_cfg_oob_lo_power(demod, - (enum drxj_cfg_oob_lo_power *) (config-> - cfg_data)); - case DRXJ_CFG_ATV_MISC: - return ctrl_set_cfg_atv_misc(demod, - (struct drxj_cfg_atv_misc *) config->cfg_data); - case DRXJ_CFG_ATV_EQU_COEF: - return ctrl_set_cfg_atv_equ_coef(demod, - (struct drxj_cfg_atv_equ_coef *) config-> - cfg_data); - case DRXJ_CFG_ATV_OUTPUT: - return ctrl_set_cfg_atv_output(demod, - (struct drxj_cfg_atv_output *) config-> - cfg_data); -#endif - case DRXJ_CFG_MPEG_OUTPUT_MISC: - return ctrl_set_cfg_mpeg_output_misc(demod, - (struct drxj_cfg_mpeg_output_misc *) - config->cfg_data); -#ifndef DRXJ_EXCLUDE_AUDIO - case DRX_CFG_AUD_VOLUME: - return aud_ctrl_set_cfg_volume(demod, - (struct drx_cfg_aud_volume *) config-> - cfg_data); - case DRX_CFG_I2S_OUTPUT: - return aud_ctrl_set_cfg_output_i2s(demod, - (struct drx_cfg_i2s_output *) config-> - cfg_data); - case DRX_CFG_AUD_AUTOSOUND: - return aud_ctr_setl_cfg_auto_sound(demod, (enum drx_cfg_aud_auto_sound *) - config->cfg_data); - case DRX_CFG_AUD_ASS_THRES: - return aud_ctrl_set_cfg_ass_thres(demod, (struct drx_cfg_aud_ass_thres *) - config->cfg_data); - case DRX_CFG_AUD_CARRIER: - return aud_ctrl_set_cfg_carrier(demod, - (struct drx_cfg_aud_carriers *) config-> - cfg_data); - case DRX_CFG_AUD_DEVIATION: - return aud_ctrl_set_cfg_dev(demod, - (enum drx_cfg_aud_deviation *) config-> - cfg_data); - case DRX_CFG_AUD_PRESCALE: - return aud_ctrl_set_cfg_prescale(demod, - (struct drx_cfg_aud_prescale *) config-> - cfg_data); - case DRX_CFG_AUD_MIXER: - return aud_ctrl_set_cfg_mixer(demod, - (struct drx_cfg_aud_mixer *) config->cfg_data); - case DRX_CFG_AUD_AVSYNC: - return aud_ctrl_set_cfg_av_sync(demod, - (enum drx_cfg_aud_av_sync *) config-> - cfg_data); - -#endif - default: - return -EINVAL; - } - - return 0; -rw_error: - return -EIO; -} - -/*============================================================================*/ - -/** -* \fn int ctrl_get_cfg() -* \brief Get 'some' configuration of the device. -* \param devmod Pointer to demodulator instance. -* \param config Pointer to configuration parameters (type and data). -* \return int. -*/ - -static int ctrl_get_cfg(struct drx_demod_instance *demod, struct drx_cfg *config) -{ - int rc; - - if (config == NULL) - return -EINVAL; - - 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); - - switch (config->cfg_type) { - case DRX_CFG_MPEG_OUTPUT: - return ctrl_get_cfg_mpeg_output(demod, - (struct drx_cfg_mpeg_output *) config-> - cfg_data); - case DRX_CFG_PINS_SAFE_MODE: - return ctrl_get_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data); - case DRXJ_CFG_AGC_RF: - return ctrl_get_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data); - case DRXJ_CFG_AGC_IF: - return ctrl_get_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data); - case DRXJ_CFG_AGC_INTERNAL: - return ctrl_get_cfg_agc_internal(demod, (u16 *)config->cfg_data); - case DRXJ_CFG_PRE_SAW: - return ctrl_get_cfg_pre_saw(demod, - (struct drxj_cfg_pre_saw *) config->cfg_data); - case DRXJ_CFG_AFE_GAIN: - return ctrl_get_cfg_afe_gain(demod, - (struct drxj_cfg_afe_gain *) config->cfg_data); - case DRXJ_CFG_ACCUM_CR_RS_CW_ERR: - return ctrl_get_accum_cr_rs_cw_err(demod, (u32 *)config->cfg_data); - case DRXJ_CFG_FEC_MERS_SEQ_COUNT: - return ctrl_get_fec_meas_seq_count(demod, (u16 *)config->cfg_data); - case DRXJ_CFG_VSB_MISC: - return ctrl_get_cfg_vsb_misc(demod, - (struct drxj_cfg_vsb_misc *) config->cfg_data); - case DRXJ_CFG_SYMBOL_CLK_OFFSET: - return ctrl_get_cfg_symbol_clock_offset(demod, - (s32 *)config->cfg_data); -#if 0 - case DRXJ_CFG_OOB_MISC: - return ctrl_get_cfg_oob_misc(demod, - (struct drxj_cfg_oob_misc *) config->cfg_data); - case DRXJ_CFG_OOB_PRE_SAW: - return ctrl_get_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data)); - case DRXJ_CFG_OOB_LO_POW: - return ctrl_get_cfg_oob_lo_power(demod, - (enum drxj_cfg_oob_lo_power *) (config-> - cfg_data)); - case DRXJ_CFG_ATV_EQU_COEF: - return ctrl_get_cfg_atv_equ_coef(demod, - (struct drxj_cfg_atv_equ_coef *) config-> - cfg_data); - case DRXJ_CFG_ATV_MISC: - return ctrl_get_cfg_atv_misc(demod, - (struct drxj_cfg_atv_misc *) config->cfg_data); - case DRXJ_CFG_ATV_OUTPUT: - return ctrl_get_cfg_atv_output(demod, - (struct drxj_cfg_atv_output *) config-> - cfg_data); - case DRXJ_CFG_ATV_AGC_STATUS: - return ctrl_get_cfg_atv_agc_status(demod, - (struct drxj_cfg_atv_agc_status *) config-> - cfg_data); -#endif - case DRXJ_CFG_MPEG_OUTPUT_MISC: - return ctrl_get_cfg_mpeg_output_misc(demod, - (struct drxj_cfg_mpeg_output_misc *) - config->cfg_data); - case DRXJ_CFG_HW_CFG: - return ctrl_get_cfg_hw_cfg(demod, - (struct drxj_cfg_hw_cfg *) config->cfg_data); -#ifndef DRXJ_EXCLUDE_AUDIO - case DRX_CFG_AUD_VOLUME: - return aud_ctrl_get_cfg_volume(demod, - (struct drx_cfg_aud_volume *) config-> - cfg_data); - case DRX_CFG_I2S_OUTPUT: - return aud_ctrl_get_cfg_output_i2s(demod, - (struct drx_cfg_i2s_output *) config-> - cfg_data); - - case DRX_CFG_AUD_RDS: - return aud_ctrl_get_cfg_rds(demod, - (struct drx_cfg_aud_rds *) config->cfg_data); - case DRX_CFG_AUD_AUTOSOUND: - return aud_ctrl_get_cfg_auto_sound(demod, - (enum drx_cfg_aud_auto_sound *) config-> - cfg_data); - case DRX_CFG_AUD_ASS_THRES: - return aud_ctrl_get_cfg_ass_thres(demod, - (struct drx_cfg_aud_ass_thres *) config-> - cfg_data); - case DRX_CFG_AUD_CARRIER: - return aud_ctrl_get_cfg_carrier(demod, - (struct drx_cfg_aud_carriers *) config-> - cfg_data); - case DRX_CFG_AUD_DEVIATION: - return aud_ctrl_get_cfg_dev(demod, - (enum drx_cfg_aud_deviation *) config-> - cfg_data); - case DRX_CFG_AUD_PRESCALE: - return aud_ctrl_get_cfg_prescale(demod, - (struct drx_cfg_aud_prescale *) config-> - cfg_data); - case DRX_CFG_AUD_MIXER: - return aud_ctrl_get_cfg_mixer(demod, - (struct drx_cfg_aud_mixer *) config->cfg_data); - case DRX_CFG_AUD_AVSYNC: - return aud_ctrl_get_cfg_av_sync(demod, - (enum drx_cfg_aud_av_sync *) config-> - cfg_data); -#endif - - default: - return -EINVAL; - } - - return 0; -rw_error: - return -EIO; -} -#endif /*============================================================================= ===== EXPORTED FUNCTIONS ====================================================*/ -- 2.20.1