aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-09 06:34:51 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 06:37:16 -0400
commitb6c4065eef7ce18d29870cbcf979e7d8c803c551 (patch)
treebb232bb04aba803f9f88dadfd6dfa5cc774bf38f
parent1d001c3fde34992bd3607ad57221655cbfc74068 (diff)
[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 <m.chehab@samsung.com>
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c8513
1 files changed, 0 insertions, 8513 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);
1028 1028
1029static int power_down_aud(struct drx_demod_instance *demod); 1029static int power_down_aud(struct drx_demod_instance *demod);
1030 1030
1031#if 0
1032static int power_up_aud(struct drx_demod_instance *demod, bool set_standard);
1033
1034static int
1035aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard);
1036#endif
1037
1038static int 1031static int
1039ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw); 1032ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1040 1033
@@ -1047,97 +1040,6 @@ ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain
1047/*============================================================================*/ 1040/*============================================================================*/
1048/*============================================================================*/ 1041/*============================================================================*/
1049 1042
1050#if 0
1051/**
1052* \fn void mult32(u32 a, u32 b, u32 *h, u32 *l)
1053* \brief 32bitsx32bits signed multiplication
1054* \param a 32 bits multiplicant, typecast from signed to unisgned
1055* \param b 32 bits multiplier, typecast from signed to unisgned
1056* \param h pointer to high part 64 bits result, typecast from signed to unisgned
1057* \param l pointer to low part 64 bits result
1058*
1059* For the 2n+n addition a + b:
1060* if a >= 0, then h += 0 (sign extension = 0)
1061* but if a < 0, then h += 2^n-1 ==> h -= 1.
1062*
1063* Also, if a + b < 2^n, then a + b >= a && a + b >= b
1064* but if a + b >= 2^n, then R = a + b - 2^n,
1065* and because a < 2^n && b < 2*n ==> R < a && R < b.
1066* Therefore, to detect overflow, simply compare the addition result with
1067* one of the operands; if the result is smaller, overflow has occurred and
1068* h must be incremented.
1069*
1070* Booth multiplication uses additions and subtractions to reduce the number
1071* of iterations. This is done by taking three subsequent bits abc and calculating
1072* the following multiplication factor: -2a + b + c. This factor is multiplied
1073* by the second operand and added to the result. Next, the first operand is
1074* shifted two bits (hence one of the three bits is reused) and the process
1075* repeated. The last iteration has only two bits left, but we simply add
1076* a zero to the end.
1077*
1078* Hence: (n=4)
1079* 1 * a = 0 * 4a + 1 * a
1080* 2 * a = 1 * 4a - 2 * a
1081* 3 * a = 1 * 4a - 1 * a
1082* -1 * a = 0 * 4a - 1 * a
1083* -5 * a = -1 * 4a - 1 * a
1084*
1085* etc.
1086*
1087* Note that the function is type size independent. Any unsigned integer type
1088* can be substituted for booth_t.
1089*
1090*/
1091
1092#define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0)
1093
1094static void mult32(u32 a, u32 b, u32 *h, u32 *l)
1095{
1096 unsigned int i;
1097 *h = *l = 0;
1098
1099 /* n/2 iterations; shift operand a left two bits after each iteration. */
1100 /* This automatically appends a zero to the operand for the last iteration. */
1101 for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) {
1102 /* Shift result left two bits */
1103 *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2));
1104 *l = (*l << 2);
1105
1106 /* Take the first three bits of operand a for the Booth conversion: */
1107 /* 0, 7: do nothing */
1108 /* 1, 2: add b */
1109 /* 3 : add 2b */
1110 /* 4 : subtract 2b */
1111 /* 5, 6: subtract b */
1112 switch (a >> (sizeof(a) * 8 - 3)) {
1113 case 3:
1114 *l += b;
1115 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1116 case 1:
1117 case 2:
1118 *l += b;
1119 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1120 break;
1121 case 4:
1122 *l -= b;
1123 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1124 ((u32)
1125 (-
1126 ((s32)
1127 b))));
1128 case 5:
1129 case 6:
1130 *l -= b;
1131 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1132 ((u32)
1133 (-
1134 ((s32)
1135 b))));
1136 break;
1137 }
1138 }
1139}
1140#endif
1141 1043
1142/*============================================================================*/ 1044/*============================================================================*/
1143 1045
@@ -1331,108 +1233,6 @@ static u32 frac_times1e6(u32 N, u32 D)
1331 1233
1332/*============================================================================*/ 1234/*============================================================================*/
1333 1235
1334#if 0
1335/**
1336* \brief Compute: 100 * 10^( gd_b / 200 ).
1337* \param u32 gd_b Gain in 0.1dB
1338* \return u32 Gainfactor in 0.01 resolution
1339*
1340*/
1341static u32 d_b2lin_times100(u32 gd_b)
1342{
1343 u32 result = 0;
1344 u32 nr6d_b_steps = 0;
1345 u32 remainder = 0;
1346 u32 remainder_fac = 0;
1347
1348 /* start with factors 2 (6.02dB) */
1349 nr6d_b_steps = gd_b * 1000UL / 60206UL;
1350 if (nr6d_b_steps > 17) {
1351 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1352 return MAX_U32;
1353 }
1354 result = (1 << nr6d_b_steps);
1355
1356 /* calculate remaining factor,
1357 poly approximation of 10^(gd_b/200):
1358
1359 y = 1E-04x2 + 0.0106x + 1.0026
1360
1361 max deviation < 0.005 for range x = [0 ... 60]
1362 */
1363 remainder = ((gd_b * 1000UL) % 60206UL) / 1000UL;
1364 /* using 1e-4 for poly calculation */
1365 remainder_fac = 1 * remainder * remainder;
1366 remainder_fac += 106 * remainder;
1367 remainder_fac += 10026;
1368
1369 /* multiply by remaining factor */
1370 result *= remainder_fac;
1371
1372 /* conversion from 1e-4 to 1e-2 */
1373 return (result + 50) / 100;
1374}
1375
1376#define FRAC_FLOOR 0
1377#define FRAC_CEIL 1
1378#define FRAC_ROUND 2
1379/**
1380* \fn u32 frac( u32 N, u32 D, u16 RC )
1381* \brief Compute: N/D.
1382* \param N nominator 32-bits.
1383* \param D denominator 32-bits.
1384* \param RC-result correction: 0-floor; 1-ceil; 2-round
1385* \return u32
1386* \retval N/D, 32 bits
1387*
1388* If D=0 returns 0
1389*/
1390static u32 frac(u32 N, u32 D, u16 RC)
1391{
1392 u32 remainder = 0;
1393 u32 frac = 0;
1394 u16 bit_cnt = 32;
1395
1396 if (D == 0) {
1397 frac = 0;
1398 remainder = 0;
1399
1400 return frac;
1401 }
1402
1403 if (D > N) {
1404 frac = 0;
1405 remainder = N;
1406 } else {
1407 remainder = 0;
1408 frac = N;
1409 while (bit_cnt-- > 0) {
1410 remainder <<= 1;
1411 remainder |= ((frac & 0x80000000) >> 31);
1412 frac <<= 1;
1413 if (remainder < D) {
1414 frac &= 0xFFFFFFFE;
1415 } else {
1416 remainder -= D;
1417 frac |= 0x1;
1418 }
1419 }
1420
1421 /* result correction if needed */
1422 if ((RC == FRAC_CEIL) && (remainder != 0)) {
1423 /* ceil the result */
1424 /*(remainder is not zero -> value behind decimal point exists) */
1425 frac++;
1426 }
1427 if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) {
1428 /* remainder is bigger from D/2 -> round the result */
1429 frac++;
1430 }
1431 }
1432
1433 return frac;
1434}
1435#endif
1436 1236
1437/** 1237/**
1438* \brief Values for NICAM prescaler gain. Computed from dB to integer 1238* \brief Values for NICAM prescaler gain. Computed from dB to integer
@@ -3542,67 +3342,6 @@ rw_error:
3542 3342
3543/*----------------------------------------------------------------------------*/ 3343/*----------------------------------------------------------------------------*/
3544 3344
3545#if 0
3546/**
3547* \fn int ctrl_get_cfg_mpeg_output()
3548* \brief Get MPEG output configuration of the device.
3549* \param devmod Pointer to demodulator instance.
3550* \param cfg_data Pointer to MPEG output configuaration struct.
3551* \return int.
3552*
3553* Retrieve MPEG output configuartion.
3554*
3555*/
3556static int
3557ctrl_get_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
3558{
3559 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3560 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
3561 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
3562 int rc;
3563 u32 rate_reg = 0;
3564 u32 data64hi = 0;
3565 u32 data64lo = 0;
3566
3567 if (cfg_data == NULL)
3568 return -EINVAL;
3569
3570 dev_addr = demod->my_i2c_dev_addr;
3571 common_attr = demod->my_common_attr;
3572
3573 cfg_data->enable_mpeg_output = common_attr->mpeg_cfg.enable_mpeg_output;
3574 cfg_data->insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
3575 cfg_data->enable_parallel = common_attr->mpeg_cfg.enable_parallel;
3576 cfg_data->invert_data = common_attr->mpeg_cfg.invert_data;
3577 cfg_data->invert_err = common_attr->mpeg_cfg.invert_err;
3578 cfg_data->invert_str = common_attr->mpeg_cfg.invert_str;
3579 cfg_data->invert_val = common_attr->mpeg_cfg.invert_val;
3580 cfg_data->invert_clk = common_attr->mpeg_cfg.invert_clk;
3581 cfg_data->static_clk = common_attr->mpeg_cfg.static_clk;
3582 cfg_data->bitrate = 0;
3583
3584 rc = ctrl_lock_status(demod, &lock_status);
3585 if (rc != 0) {
3586 pr_err("error %d\n", rc);
3587 goto rw_error;
3588 }
3589 if ((lock_status == DRX_LOCKED)) {
3590 rc = drxdap_fasi_read_reg32(dev_addr, FEC_OC_RCN_DYN_RATE_LO__A, &rate_reg, 0);
3591 if (rc != 0) {
3592 pr_err("error %d\n", rc);
3593 goto rw_error;
3594 }
3595 /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */
3596 mult32(rate_reg, common_attr->sys_clock_freq * 1000, &data64hi,
3597 &data64lo);
3598 cfg_data->bitrate = (data64hi << 7) | (data64lo >> 25);
3599 }
3600
3601 return 0;
3602rw_error:
3603 return -EIO;
3604}
3605#endif
3606 3345
3607/*----------------------------------------------------------------------------*/ 3346/*----------------------------------------------------------------------------*/
3608/* MPEG Output Configuration Functions - end */ 3347/* MPEG Output Configuration Functions - end */
@@ -3729,40 +3468,6 @@ rw_error:
3729 3468
3730/*----------------------------------------------------------------------------*/ 3469/*----------------------------------------------------------------------------*/
3731/** 3470/**
3732* \fn int set_mpeg_output_clock_rate()
3733* \brief Set MPEG output clock rate.
3734* \param devmod Pointer to demodulator instance.
3735* \return int.
3736*
3737* This routine should be called during a set channel of QAM/VSB
3738*
3739*/
3740#if 0
3741static int set_mpeg_output_clock_rate(struct drx_demod_instance *demod)
3742{
3743 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3744 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3745 int rc;
3746
3747 dev_addr = demod->my_i2c_dev_addr;
3748 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3749
3750 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3751 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, ext_attr->mpeg_output_clock_rate - 1, 0);
3752 if (rc != 0) {
3753 pr_err("error %d\n", rc);
3754 goto rw_error;
3755 }
3756 }
3757
3758 return 0;
3759rw_error:
3760 return -EIO;
3761}
3762#endif
3763
3764/*----------------------------------------------------------------------------*/
3765/**
3766* \fn int set_mpeg_start_width() 3471* \fn int set_mpeg_start_width()
3767* \brief Set MPEG start width. 3472* \brief Set MPEG start width.
3768* \param devmod Pointer to demodulator instance. 3473* \param devmod Pointer to demodulator instance.
@@ -3805,165 +3510,6 @@ rw_error:
3805 return -EIO; 3510 return -EIO;
3806} 3511}
3807 3512
3808#if 0
3809/*----------------------------------------------------------------------------*/
3810/**
3811* \fn int ctrl_set_cfg_mpeg_output_misc()
3812* \brief Set miscellaneous configuartions
3813* \param devmod Pointer to demodulator instance.
3814* \param cfg_data pDRXJCfgMisc_t
3815* \return int.
3816*
3817* This routine can be used to set configuartion options that are DRXJ
3818* specific and/or added to the requirements at a late stage.
3819*
3820*/
3821static int
3822ctrl_set_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3823 struct drxj_cfg_mpeg_output_misc *cfg_data)
3824{
3825 struct drxj_data *ext_attr = NULL;
3826 int rc;
3827
3828 if (cfg_data == NULL)
3829 return -EINVAL;
3830
3831 ext_attr = demod->my_ext_attr;
3832
3833 /*
3834 Set disable TEI bit handling flag.
3835 TEI must be left untouched by device in case of BER measurements using
3836 external equipment that is unable to ignore the TEI bit in the TS.
3837 Default will false (enable TEI bit handling).
3838 Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)).
3839 Set clock rate. Default is auto that is derived from symbol rate.
3840 The flags and values will also be used to set registers during a set channel.
3841 */
3842 ext_attr->disable_te_ihandling = cfg_data->disable_tei_handling;
3843 ext_attr->bit_reverse_mpeg_outout = cfg_data->bit_reverse_mpeg_outout;
3844 ext_attr->mpeg_output_clock_rate = cfg_data->mpeg_output_clock_rate;
3845 ext_attr->mpeg_start_width = cfg_data->mpeg_start_width;
3846 /* Don't care what the active standard is, activate setting immediatly */
3847 rc = set_mpegtei_handling(demod);
3848 if (rc != 0) {
3849 pr_err("error %d\n", rc);
3850 goto rw_error;
3851 }
3852 rc = bit_reverse_mpeg_output(demod);
3853 if (rc != 0) {
3854 pr_err("error %d\n", rc);
3855 goto rw_error;
3856 }
3857 rc = set_mpeg_output_clock_rate(demod);
3858 if (rc != 0) {
3859 pr_err("error %d\n", rc);
3860 goto rw_error;
3861 }
3862 rc = set_mpeg_start_width(demod);
3863 if (rc != 0) {
3864 pr_err("error %d\n", rc);
3865 goto rw_error;
3866 }
3867
3868 return 0;
3869rw_error:
3870 return -EIO;
3871}
3872
3873/*----------------------------------------------------------------------------*/
3874
3875/**
3876* \fn int ctrl_get_cfg_mpeg_output_misc()
3877* \brief Get miscellaneous configuartions.
3878* \param devmod Pointer to demodulator instance.
3879* \param cfg_data Pointer to DRXJCfgMisc_t.
3880* \return int.
3881*
3882* This routine can be used to retreive the current setting of the configuartion
3883* options that are DRXJ specific and/or added to the requirements at a
3884* late stage.
3885*
3886*/
3887static int
3888ctrl_get_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3889 struct drxj_cfg_mpeg_output_misc *cfg_data)
3890{
3891 struct drxj_data *ext_attr = NULL;
3892 int rc;
3893 u16 data = 0;
3894
3895 if (cfg_data == NULL)
3896 return -EINVAL;
3897
3898 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3899 cfg_data->disable_tei_handling = ext_attr->disable_te_ihandling;
3900 cfg_data->bit_reverse_mpeg_outout = ext_attr->bit_reverse_mpeg_outout;
3901 cfg_data->mpeg_start_width = ext_attr->mpeg_start_width;
3902 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3903 cfg_data->mpeg_output_clock_rate = ext_attr->mpeg_output_clock_rate;
3904 } else {
3905 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, FEC_OC_DTO_PERIOD__A, &data, 0);
3906 if (rc != 0) {
3907 pr_err("error %d\n", rc);
3908 goto rw_error;
3909 }
3910 cfg_data->mpeg_output_clock_rate =
3911 (enum drxj_mpeg_output_clock_rate) (data + 1);
3912 }
3913
3914 return 0;
3915rw_error:
3916 return -EIO;
3917}
3918
3919/*----------------------------------------------------------------------------*/
3920
3921/**
3922* \fn int ctrl_get_cfg_hw_cfg()
3923* \brief Get HW configuartions.
3924* \param devmod Pointer to demodulator instance.
3925* \param cfg_data Pointer to Bool.
3926* \return int.
3927*
3928* This routine can be used to retreive the current setting of the configuartion
3929* options that are DRXJ specific and/or added to the requirements at a
3930* late stage.
3931*
3932*/
3933static int
3934ctrl_get_cfg_hw_cfg(struct drx_demod_instance *demod, struct drxj_cfg_hw_cfg *cfg_data)
3935{
3936 int rc;
3937 u16 data = 0;
3938
3939 if (cfg_data == NULL)
3940 return -EINVAL;
3941
3942 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3943 if (rc != 0) {
3944 pr_err("error %d\n", rc);
3945 goto rw_error;
3946 }
3947 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_OHW_CFG__A, &data, 0);
3948 if (rc != 0) {
3949 pr_err("error %d\n", rc);
3950 goto rw_error;
3951 }
3952 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3953 if (rc != 0) {
3954 pr_err("error %d\n", rc);
3955 goto rw_error;
3956 }
3957
3958 cfg_data->i2c_speed = (enum drxji2c_speed) ((data >> 6) & 0x1);
3959 cfg_data->xtal_freq = (enum drxj_xtal_freq) (data & 0x3);
3960
3961 return 0;
3962rw_error:
3963 return -EIO;
3964}
3965#endif
3966
3967/*----------------------------------------------------------------------------*/ 3513/*----------------------------------------------------------------------------*/
3968/* miscellaneous configuartions - end */ 3514/* miscellaneous configuartions - end */
3969/*----------------------------------------------------------------------------*/ 3515/*----------------------------------------------------------------------------*/
@@ -4108,49 +3654,6 @@ rw_error:
4108 return -EIO; 3654 return -EIO;
4109} 3655}
4110 3656
4111#if 0
4112/*============================================================================*/
4113/**
4114* \fn int ctrl_getuio_cfg()
4115* \brief Get modus oprandi UIO.
4116* \param demod Pointer to demodulator instance.
4117* \param uio_cfg Pointer to a configuration setting for a certain UIO.
4118* \return int.
4119*/
4120static int ctrl_getuio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
4121{
4122
4123 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
4124 enum drxuio_mode *uio_mode[4] = { NULL };
4125 bool *uio_available[4] = { NULL };
4126
4127 ext_attr = demod->my_ext_attr;
4128
4129 uio_mode[DRX_UIO1] = &ext_attr->uio_sma_tx_mode;
4130 uio_mode[DRX_UIO2] = &ext_attr->uio_sma_rx_mode;
4131 uio_mode[DRX_UIO3] = &ext_attr->uio_gpio_mode;
4132 uio_mode[DRX_UIO4] = &ext_attr->uio_irqn_mode;
4133
4134 uio_available[DRX_UIO1] = &ext_attr->has_smatx;
4135 uio_available[DRX_UIO2] = &ext_attr->has_smarx;
4136 uio_available[DRX_UIO3] = &ext_attr->has_gpio;
4137 uio_available[DRX_UIO4] = &ext_attr->has_irqn;
4138
4139 if (uio_cfg == NULL)
4140 return -EINVAL;
4141
4142 if ((uio_cfg->uio > DRX_UIO4) || (uio_cfg->uio < DRX_UIO1))
4143 return -EINVAL;
4144
4145 if (!*uio_available[uio_cfg->uio])
4146 return -EIO;
4147
4148 uio_cfg->mode = *uio_mode[uio_cfg->uio];
4149
4150 return 0;
4151}
4152#endif
4153
4154/** 3657/**
4155* \fn int ctrl_uio_write() 3658* \fn int ctrl_uio_write()
4156* \brief Write to a UIO. 3659* \brief Write to a UIO.
@@ -4353,186 +3856,6 @@ rw_error:
4353 return -EIO; 3856 return -EIO;
4354} 3857}
4355 3858
4356#if 0
4357/**
4358*\fn int ctrl_uio_read
4359*\brief Read from a UIO.
4360* \param demod Pointer to demodulator instance.
4361* \param uio_data Pointer to data container for a certain UIO.
4362* \return int.
4363*/
4364static int ctrl_uio_read(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
4365{
4366 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
4367 int rc;
4368 u16 pin_cfg_value = 0;
4369 u16 value = 0;
4370
4371 if ((uio_data == NULL) || (demod == NULL))
4372 return -EINVAL;
4373
4374 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4375
4376 /* Write magic word to enable pdr reg write */
4377 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4378 if (rc != 0) {
4379 pr_err("error %d\n", rc);
4380 goto rw_error;
4381 }
4382 switch (uio_data->uio) {
4383 /*====================================================================*/
4384 case DRX_UIO1:
4385 /* DRX_UIO1: SMA_TX UIO-1 */
4386 if (!ext_attr->has_smatx)
4387 return -EIO;
4388
4389 if (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
4390 return -EIO;
4391
4392 pin_cfg_value = 0;
4393 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4394 pin_cfg_value |= 0x0110;
4395 /* io_pad_cfg_mode output mode is drive always */
4396 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4397
4398 /* write to io pad configuration register - input mode */
4399 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
4400 if (rc != 0) {
4401 pr_err("error %d\n", rc);
4402 goto rw_error;
4403 }
4404
4405 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4406 if (rc != 0) {
4407 pr_err("error %d\n", rc);
4408 goto rw_error;
4409 }
4410 if ((value & 0x8000) != 0) { /* check 15th bit - 1st UIO */
4411 uio_data->value = true;
4412 } else {
4413 uio_data->value = false;
4414 }
4415 break;
4416 /*======================================================================*/
4417 case DRX_UIO2:
4418 /* DRX_UIO2: SMA_RX UIO-2 */
4419 if (!ext_attr->has_smarx)
4420 return -EIO;
4421
4422 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
4423 return -EIO;
4424
4425 pin_cfg_value = 0;
4426 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4427 pin_cfg_value |= 0x0110;
4428 /* io_pad_cfg_mode output mode is drive always */
4429 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4430
4431 /* write to io pad configuration register - input mode */
4432 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
4433 if (rc != 0) {
4434 pr_err("error %d\n", rc);
4435 goto rw_error;
4436 }
4437
4438 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4439 if (rc != 0) {
4440 pr_err("error %d\n", rc);
4441 goto rw_error;
4442 }
4443
4444 if ((value & 0x4000) != 0) /* check 14th bit - 2nd UIO */
4445 uio_data->value = true;
4446 else
4447 uio_data->value = false;
4448
4449 break;
4450 /*=====================================================================*/
4451 case DRX_UIO3:
4452 /* DRX_UIO3: GPIO UIO-3 */
4453 if (!ext_attr->has_gpio)
4454 return -EIO;
4455
4456 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
4457 return -EIO;
4458
4459 pin_cfg_value = 0;
4460 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4461 pin_cfg_value |= 0x0110;
4462 /* io_pad_cfg_mode output mode is drive always */
4463 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4464
4465 /* write to io pad configuration register - input mode */
4466 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4467 if (rc != 0) {
4468 pr_err("error %d\n", rc);
4469 goto rw_error;
4470 }
4471
4472 /* read io input data registar */
4473 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_HI__A, &value, 0);
4474 if (rc != 0) {
4475 pr_err("error %d\n", rc);
4476 goto rw_error;
4477 }
4478 if ((value & 0x0004) != 0) { /* check 2nd bit - 3rd UIO */
4479 uio_data->value = true;
4480 } else {
4481 uio_data->value = false;
4482 }
4483 break;
4484 /*=====================================================================*/
4485 case DRX_UIO4:
4486 /* DRX_UIO4: IRQN UIO-4 */
4487 if (!ext_attr->has_irqn)
4488 return -EIO;
4489
4490 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4491 return -EIO;
4492
4493 pin_cfg_value = 0;
4494 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4495 pin_cfg_value |= 0x0110;
4496 /* io_pad_cfg_mode output mode is drive always */
4497 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4498
4499 /* write to io pad configuration register - input mode */
4500 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4501 if (rc != 0) {
4502 pr_err("error %d\n", rc);
4503 goto rw_error;
4504 }
4505
4506 /* read io input data registar */
4507 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4508 if (rc != 0) {
4509 pr_err("error %d\n", rc);
4510 goto rw_error;
4511 }
4512 if ((value & 0x1000) != 0) /* check 12th bit - 4th UIO */
4513 uio_data->value = true;
4514 else
4515 uio_data->value = false;
4516
4517 break;
4518 /*====================================================================*/
4519 default:
4520 return -EINVAL;
4521 } /* switch ( uio_data->uio ) */
4522
4523 /* Write magic word to disable pdr reg write */
4524 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4525 if (rc != 0) {
4526 pr_err("error %d\n", rc);
4527 goto rw_error;
4528 }
4529
4530 return 0;
4531rw_error:
4532 return -EIO;
4533}
4534#endif
4535
4536/*---------------------------------------------------------------------------*/ 3859/*---------------------------------------------------------------------------*/
4537/* UIO Configuration Functions - end */ 3860/* UIO Configuration Functions - end */
4538/*---------------------------------------------------------------------------*/ 3861/*---------------------------------------------------------------------------*/
@@ -4648,119 +3971,6 @@ rw_error:
4648 return -EIO; 3971 return -EIO;
4649} 3972}
4650 3973
4651#if 0
4652/**
4653* \fn int ctrl_set_cfg_smart_ant()
4654* \brief Set Smart Antenna.
4655* \param pointer to struct drxj_cfg_smart_ant.
4656* \return int.
4657*
4658*/
4659static int
4660ctrl_set_cfg_smart_ant(struct drx_demod_instance *demod, struct drxj_cfg_smart_ant *smart_ant)
4661{
4662 struct drxj_data *ext_attr = NULL;
4663 struct i2c_device_addr *dev_addr = NULL;
4664 int rc;
4665 u32 start_time = 0;
4666 u16 data = 0;
4667 static bool bit_inverted;
4668
4669 dev_addr = demod->my_i2c_dev_addr;
4670 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4671
4672 /* check arguments */
4673 if (smart_ant == NULL)
4674 return -EINVAL;
4675
4676 if (bit_inverted != ext_attr->smart_ant_inverted
4677 || ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SMA) {
4678 rc = smart_ant_init(demod);
4679 if (rc != 0) {
4680 pr_err("error %d\n", rc);
4681 goto rw_error;
4682 }
4683 bit_inverted = ext_attr->smart_ant_inverted;
4684 }
4685
4686 /* Write magic word to enable pdr reg write */
4687 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4688 if (rc != 0) {
4689 pr_err("error %d\n", rc);
4690 goto rw_error;
4691 }
4692
4693 switch (smart_ant->io) {
4694 case DRXJ_SMT_ANT_OUTPUT:
4695 /* enable Tx if Mode B (input) is supported */
4696 /*
4697 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4698 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
4699 */
4700 start_time = jiffies_to_msecs(jiffies);
4701 do {
4702 rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_STATUS__A, &data, 0);
4703 if (rc != 0) {
4704 pr_err("error %d\n", rc);
4705 goto rw_error;
4706 }
4707 } while ((data & SIO_SA_TX_STATUS_BUSY__M) && ((jiffies_to_msecs(jiffies) - start_time) < DRXJ_MAX_WAITTIME));
4708
4709 if (data & SIO_SA_TX_STATUS_BUSY__M)
4710 return -EIO;
4711
4712 /* write to smart antenna configuration register */
4713 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);
4714 if (rc != 0) {
4715 pr_err("error %d\n", rc);
4716 goto rw_error;
4717 }
4718 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);
4719 if (rc != 0) {
4720 pr_err("error %d\n", rc);
4721 goto rw_error;
4722 }
4723 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);
4724 if (rc != 0) {
4725 pr_err("error %d\n", rc);
4726 goto rw_error;
4727 }
4728 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_DATA3__A, 0xff8d, 0);
4729 if (rc != 0) {
4730 pr_err("error %d\n", rc);
4731 goto rw_error;
4732 }
4733
4734 /* trigger the sending */
4735 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_LENGTH__A, 56, 0);
4736 if (rc != 0) {
4737 pr_err("error %d\n", rc);
4738 goto rw_error;
4739 }
4740
4741 break;
4742 case DRXJ_SMT_ANT_INPUT:
4743 /* disable Tx if Mode B (input) is supported */
4744 /*
4745 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4746 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
4747 */
4748 default:
4749 return -EINVAL;
4750 }
4751 /* Write magic word to enable pdr reg write */
4752 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4753 if (rc != 0) {
4754 pr_err("error %d\n", rc);
4755 goto rw_error;
4756 }
4757
4758 return 0;
4759rw_error:
4760 return -EIO;
4761}
4762#endif
4763
4764static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd) 3974static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
4765{ 3975{
4766 int rc; 3976 int rc;
@@ -5141,321 +4351,6 @@ rw_error:
5141 return -EIO; 4351 return -EIO;
5142} 4352}
5143 4353
5144#if 0
5145/**
5146* \brief Configure IQM AF registers
5147* \param demod instance of demodulator.
5148* \param active
5149* \return int.
5150*/
5151static int iqm_set_af(struct drx_demod_instance *demod, bool active)
5152{
5153 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5154 int rc;
5155 u16 data = 0;
5156
5157 /* Configure IQM */
5158 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5159 if (rc != 0) {
5160 pr_err("error %d\n", rc);
5161 goto rw_error;
5162 }
5163 if (!active)
5164 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));
5165 else
5166 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);
5167 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5168 if (rc != 0) {
5169 pr_err("error %d\n", rc);
5170 goto rw_error;
5171 }
5172
5173 return 0;
5174rw_error:
5175 return -EIO;
5176}
5177
5178/* -------------------------------------------------------------------------- */
5179static int
5180ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg);
5181
5182/**
5183* \brief set configuration of pin-safe mode
5184* \param demod instance of demodulator.
5185* \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m.
5186* \return int.
5187*/
5188static int
5189ctrl_set_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enable)
5190{
5191 struct drxj_data *ext_attr = NULL;
5192 struct i2c_device_addr *dev_addr = NULL;
5193 int rc;
5194
5195 if (enable == NULL)
5196 return -EINVAL;
5197
5198 dev_addr = demod->my_i2c_dev_addr;
5199 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5200
5201 /* Write magic word to enable pdr reg write */
5202 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
5203 if (rc != 0) {
5204 pr_err("error %d\n", rc);
5205 goto rw_error;
5206 }
5207
5208 if (*enable) {
5209 bool bridge_enabled = false;
5210
5211 /* MPEG pins to input */
5212 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5213 if (rc != 0) {
5214 pr_err("error %d\n", rc);
5215 goto rw_error;
5216 }
5217 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5218 if (rc != 0) {
5219 pr_err("error %d\n", rc);
5220 goto rw_error;
5221 }
5222 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5223 if (rc != 0) {
5224 pr_err("error %d\n", rc);
5225 goto rw_error;
5226 }
5227 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5228 if (rc != 0) {
5229 pr_err("error %d\n", rc);
5230 goto rw_error;
5231 }
5232 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5233 if (rc != 0) {
5234 pr_err("error %d\n", rc);
5235 goto rw_error;
5236 }
5237 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5238 if (rc != 0) {
5239 pr_err("error %d\n", rc);
5240 goto rw_error;
5241 }
5242 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5243 if (rc != 0) {
5244 pr_err("error %d\n", rc);
5245 goto rw_error;
5246 }
5247 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5248 if (rc != 0) {
5249 pr_err("error %d\n", rc);
5250 goto rw_error;
5251 }
5252 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5253 if (rc != 0) {
5254 pr_err("error %d\n", rc);
5255 goto rw_error;
5256 }
5257 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5258 if (rc != 0) {
5259 pr_err("error %d\n", rc);
5260 goto rw_error;
5261 }
5262 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5263 if (rc != 0) {
5264 pr_err("error %d\n", rc);
5265 goto rw_error;
5266 }
5267 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5268 if (rc != 0) {
5269 pr_err("error %d\n", rc);
5270 goto rw_error;
5271 }
5272
5273 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
5274 PD_I2C_SCL2 Bridge off, Port2 Inactive */
5275 rc = ctrl_i2c_bridge(demod, &bridge_enabled);
5276 if (rc != 0) {
5277 pr_err("error %d\n", rc);
5278 goto rw_error;
5279 }
5280 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5281 if (rc != 0) {
5282 pr_err("error %d\n", rc);
5283 goto rw_error;
5284 }
5285 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5286 if (rc != 0) {
5287 pr_err("error %d\n", rc);
5288 goto rw_error;
5289 }
5290
5291 /* PD_GPIO Store and set to input
5292 PD_VSYNC Store and set to input
5293 PD_SMA_RX Store and set to input
5294 PD_SMA_TX Store and set to input */
5295 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_GPIO_CFG__A, &ext_attr->pdr_safe_restore_val_gpio, 0);
5296 if (rc != 0) {
5297 pr_err("error %d\n", rc);
5298 goto rw_error;
5299 }
5300 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_VSYNC_CFG__A, &ext_attr->pdr_safe_restore_val_v_sync, 0);
5301 if (rc != 0) {
5302 pr_err("error %d\n", rc);
5303 goto rw_error;
5304 }
5305 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_SMA_RX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_rx, 0);
5306 if (rc != 0) {
5307 pr_err("error %d\n", rc);
5308 goto rw_error;
5309 }
5310 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_SMA_TX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_tx, 0);
5311 if (rc != 0) {
5312 pr_err("error %d\n", rc);
5313 goto rw_error;
5314 }
5315 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5316 if (rc != 0) {
5317 pr_err("error %d\n", rc);
5318 goto rw_error;
5319 }
5320 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5321 if (rc != 0) {
5322 pr_err("error %d\n", rc);
5323 goto rw_error;
5324 }
5325 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5326 if (rc != 0) {
5327 pr_err("error %d\n", rc);
5328 goto rw_error;
5329 }
5330 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5331 if (rc != 0) {
5332 pr_err("error %d\n", rc);
5333 goto rw_error;
5334 }
5335
5336 /* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate!
5337 PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */
5338 rc = iqm_set_af(demod, false);
5339 if (rc != 0) {
5340 pr_err("error %d\n", rc);
5341 goto rw_error;
5342 }
5343
5344 /* PD_CVBS Analog DAC output, standby mode
5345 PD_SIF Analog DAC output, standby mode */
5346 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);
5347 if (rc != 0) {
5348 pr_err("error %d\n", rc);
5349 goto rw_error;
5350 }
5351
5352 /* PD_I2S_CL Input
5353 PD_I2S_DA Input
5354 PD_I2S_WS Input */
5355 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5356 if (rc != 0) {
5357 pr_err("error %d\n", rc);
5358 goto rw_error;
5359 }
5360 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5361 if (rc != 0) {
5362 pr_err("error %d\n", rc);
5363 goto rw_error;
5364 }
5365 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5366 if (rc != 0) {
5367 pr_err("error %d\n", rc);
5368 goto rw_error;
5369 }
5370 } else {
5371 /* No need to restore MPEG pins;
5372 is done in SetStandard/SetChannel */
5373
5374 /* PD_I2C_SDA2 Port2 active
5375 PD_I2C_SCL2 Port2 active */
5376 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, SIO_PDR_I2C_SDA2_CFG__PRE, 0);
5377 if (rc != 0) {
5378 pr_err("error %d\n", rc);
5379 goto rw_error;
5380 }
5381 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, SIO_PDR_I2C_SCL2_CFG__PRE, 0);
5382 if (rc != 0) {
5383 pr_err("error %d\n", rc);
5384 goto rw_error;
5385 }
5386
5387 /* PD_GPIO Restore
5388 PD_VSYNC Restore
5389 PD_SMA_RX Restore
5390 PD_SMA_TX Restore */
5391 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_GPIO_CFG__A, ext_attr->pdr_safe_restore_val_gpio, 0);
5392 if (rc != 0) {
5393 pr_err("error %d\n", rc);
5394 goto rw_error;
5395 }
5396 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_VSYNC_CFG__A, ext_attr->pdr_safe_restore_val_v_sync, 0);
5397 if (rc != 0) {
5398 pr_err("error %d\n", rc);
5399 goto rw_error;
5400 }
5401 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_RX_CFG__A, ext_attr->pdr_safe_restore_val_sma_rx, 0);
5402 if (rc != 0) {
5403 pr_err("error %d\n", rc);
5404 goto rw_error;
5405 }
5406 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_SMA_TX_CFG__A, ext_attr->pdr_safe_restore_val_sma_tx, 0);
5407 if (rc != 0) {
5408 pr_err("error %d\n", rc);
5409 goto rw_error;
5410 }
5411
5412 /* PD_RF_AGC, PD_IF_AGC
5413 No need to restore; will be restored in SetStandard/SetChannel */
5414
5415 /* PD_CVBS, PD_SIF
5416 No need to restore; will be restored in SetStandard/SetChannel */
5417
5418 /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
5419 Should be restored via DRX_CTRL_SET_AUD */
5420 }
5421
5422 /* Write magic word to disable pdr reg write */
5423 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
5424 if (rc != 0) {
5425 pr_err("error %d\n", rc);
5426 goto rw_error;
5427 }
5428 ext_attr->pdr_safe_mode = *enable;
5429
5430 return 0;
5431
5432rw_error:
5433 return -EIO;
5434}
5435
5436/* -------------------------------------------------------------------------- */
5437
5438/**
5439* \brief get configuration of pin-safe mode
5440* \param demod instance of demodulator.
5441* \param enable boolean indicating whether pin-safe mode is active
5442* \return int.
5443*/
5444static int
5445ctrl_get_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enabled)
5446{
5447 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
5448
5449 if (enabled == NULL)
5450 return -EINVAL;
5451
5452 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5453 *enabled = ext_attr->pdr_safe_mode;
5454
5455 return 0;
5456}
5457#endif
5458
5459/*============================================================================*/ 4354/*============================================================================*/
5460/*== END AUXILIARY FUNCTIONS ==*/ 4355/*== END AUXILIARY FUNCTIONS ==*/
5461/*============================================================================*/ 4356/*============================================================================*/
@@ -5667,72 +4562,6 @@ static int init_agc(struct drx_demod_instance *demod)
5667 } 4562 }
5668 break; 4563 break;
5669#endif 4564#endif
5670#if 0
5671 case DRX_STANDARD_FM:
5672 clp_sum_max = 1023;
5673 sns_sum_max = 1023;
5674 ki_innergain_min = (u16) (-32768);
5675 if_iaccu_hi_tgt_min = 2047;
5676 agc_ki_dgain = 0x7;
5677 ki_min = 0x0225;
5678 ki_max = 0x0547;
5679 clp_dir_to = (u16) (-9);
5680 sns_dir_to = (u16) (-9);
5681 ingain_tgt_max = 9000;
5682 clp_ctrl_mode = 1;
5683 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5684 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5685 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5686 if (rc != 0) {
5687 pr_err("error %d\n", rc);
5688 goto rw_error;
5689 }
5690 break;
5691 case DRX_STANDARD_NTSC:
5692 case DRX_STANDARD_PAL_SECAM_BG:
5693 case DRX_STANDARD_PAL_SECAM_DK:
5694 case DRX_STANDARD_PAL_SECAM_I:
5695 clp_sum_max = 1023;
5696 sns_sum_max = 1023;
5697 ki_innergain_min = (u16) (-32768);
5698 if_iaccu_hi_tgt_min = 2047;
5699 agc_ki_dgain = 0x7;
5700 ki_min = 0x0225;
5701 ki_max = 0x0547;
5702 clp_dir_to = (u16) (-9);
5703 ingain_tgt_max = 9000;
5704 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5705 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5706 sns_dir_to = (u16) (-9);
5707 clp_ctrl_mode = 1;
5708 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5709 if (rc != 0) {
5710 pr_err("error %d\n", rc);
5711 goto rw_error;
5712 }
5713 break;
5714 case DRX_STANDARD_PAL_SECAM_L:
5715 case DRX_STANDARD_PAL_SECAM_LP:
5716 clp_sum_max = 1023;
5717 sns_sum_max = 1023;
5718 ki_innergain_min = (u16) (-32768);
5719 if_iaccu_hi_tgt_min = 2047;
5720 agc_ki_dgain = 0x7;
5721 ki_min = 0x0225;
5722 ki_max = 0x0547;
5723 clp_dir_to = (u16) (-9);
5724 sns_dir_to = (u16) (-9);
5725 ingain_tgt_max = 9000;
5726 clp_ctrl_mode = 1;
5727 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5728 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5729 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5730 if (rc != 0) {
5731 pr_err("error %d\n", rc);
5732 goto rw_error;
5733 }
5734 break;
5735#endif
5736 default: 4565 default:
5737 return -EINVAL; 4566 return -EINVAL;
5738 } 4567 }
@@ -6004,85 +4833,6 @@ rw_error:
6004 return -EIO; 4833 return -EIO;
6005} 4834}
6006 4835
6007#if 0
6008/**
6009* \fn int get_sig_strength()
6010* \brief Retrieve signal strength for VSB and QAM.
6011* \param demod Pointer to demod instance
6012* \param u16-t Pointer to signal strength data; range 0, .. , 100.
6013* \return int.
6014* \retval 0 sig_strength contains valid data.
6015* \retval -EINVAL sig_strength is NULL.
6016* \retval -EIO Erroneous data, sig_strength contains invalid data.
6017*/
6018#define DRXJ_AGC_TOP 0x2800
6019#define DRXJ_AGC_SNS 0x1600
6020#define DRXJ_RFAGC_MAX 0x3fff
6021#define DRXJ_RFAGC_MIN 0x800
6022
6023static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
6024{
6025 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6026 int rc;
6027 u16 rf_gain = 0;
6028 u16 if_gain = 0;
6029 u16 if_agc_sns = 0;
6030 u16 if_agc_top = 0;
6031 u16 rf_agc_max = 0;
6032 u16 rf_agc_min = 0;
6033
6034 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
6035 if (rc != 0) {
6036 pr_err("error %d\n", rc);
6037 goto rw_error;
6038 }
6039 if_gain &= IQM_AF_AGC_IF__M;
6040 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
6041 if (rc != 0) {
6042 pr_err("error %d\n", rc);
6043 goto rw_error;
6044 }
6045 rf_gain &= IQM_AF_AGC_RF__M;
6046
6047 if_agc_sns = DRXJ_AGC_SNS;
6048 if_agc_top = DRXJ_AGC_TOP;
6049 rf_agc_max = DRXJ_RFAGC_MAX;
6050 rf_agc_min = DRXJ_RFAGC_MIN;
6051
6052 if (if_gain > if_agc_top) {
6053 if (rf_gain > rf_agc_max)
6054 *sig_strength = 100;
6055 else if (rf_gain > rf_agc_min) {
6056 if (rf_agc_max == rf_agc_min) {
6057 pr_err("error: rf_agc_max == rf_agc_min\n");
6058 return -EIO;
6059 }
6060 *sig_strength =
6061 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
6062 rf_agc_min);
6063 } else
6064 *sig_strength = 75;
6065 } else if (if_gain > if_agc_sns) {
6066 if (if_agc_top == if_agc_sns) {
6067 pr_err("error: if_agc_top == if_agc_sns\n");
6068 return -EIO;
6069 }
6070 *sig_strength =
6071 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
6072 } else {
6073 if (!if_agc_sns) {
6074 pr_err("error: if_agc_sns is zero!\n");
6075 return -EIO;
6076 }
6077 *sig_strength = (20 * if_gain / if_agc_sns);
6078 }
6079
6080 return 0;
6081rw_error:
6082 return -EIO;
6083}
6084#endif
6085
6086/** 4836/**
6087* \fn int get_acc_pkt_err() 4837* \fn int get_acc_pkt_err()
6088* \brief Retrieve signal strength for VSB and QAM. 4838* \brief Retrieve signal strength for VSB and QAM.
@@ -6132,130 +4882,6 @@ rw_error:
6132} 4882}
6133#endif 4883#endif
6134 4884
6135#if 0
6136/**
6137* \fn int ResetAccPktErr()
6138* \brief Reset Accumulating packet error count.
6139* \param demod Pointer to demod instance
6140* \return int.
6141* \retval 0.
6142* \retval -EIO Erroneous data.
6143*/
6144static int ctrl_set_cfg_reset_pkt_err(struct drx_demod_instance *demod)
6145{
6146 struct drxj_data *ext_attr = NULL;
6147 int rc;
6148 u16 packet_error = 0;
6149
6150 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6151 ext_attr->reset_pkt_err_acc = true;
6152 /* call to reset counter */
6153 rc = get_acc_pkt_err(demod, &packet_error);
6154 if (rc != 0) {
6155 pr_err("error %d\n", rc);
6156 goto rw_error;
6157 }
6158
6159 return 0;
6160rw_error:
6161 return -EIO;
6162}
6163
6164/**
6165* \fn static short get_str_freq_offset()
6166* \brief Get symbol rate offset in QAM & 8VSB mode
6167* \return Error code
6168*/
6169static int get_str_freq_offset(struct drx_demod_instance *demod, s32 *str_freq)
6170{
6171 int rc;
6172 u32 symbol_frequency_ratio = 0;
6173 u32 symbol_nom_frequency_ratio = 0;
6174
6175 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6176 struct drxj_data *ext_attr = demod->my_ext_attr;
6177
6178 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &symbol_frequency_ratio, 0);
6179 if (rc != 0) {
6180 pr_err("error %d\n", rc);
6181 goto rw_error;
6182 }
6183 symbol_nom_frequency_ratio = ext_attr->iqm_rc_rate_ofs;
6184
6185 if (symbol_frequency_ratio > symbol_nom_frequency_ratio)
6186 *str_freq =
6187 -1 *
6188 frac_times1e6((symbol_frequency_ratio -
6189 symbol_nom_frequency_ratio),
6190 (symbol_frequency_ratio + (1 << 23)));
6191 else
6192 *str_freq =
6193 frac_times1e6((symbol_nom_frequency_ratio -
6194 symbol_frequency_ratio),
6195 (symbol_frequency_ratio + (1 << 23)));
6196
6197 return 0;
6198rw_error:
6199 return -EIO;
6200}
6201
6202/**
6203* \fn static short get_ctl_freq_offset
6204* \brief Get the value of ctl_freq in QAM & ATSC mode
6205* \return Error code
6206*/
6207static int get_ctl_freq_offset(struct drx_demod_instance *demod, s32 *ctl_freq)
6208{
6209 s32 sampling_frequency = 0;
6210 s32 current_frequency = 0;
6211 s32 nominal_frequency = 0;
6212 s32 carrier_frequency_shift = 0;
6213 s32 sign = 1;
6214 u32 data64hi = 0;
6215 u32 data64lo = 0;
6216 struct drxj_data *ext_attr = NULL;
6217 struct drx_common_attr *common_attr = NULL;
6218 struct i2c_device_addr *dev_addr = NULL;
6219 int rc;
6220
6221 dev_addr = demod->my_i2c_dev_addr;
6222 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6223 common_attr = (struct drx_common_attr *) demod->my_common_attr;
6224
6225 sampling_frequency = common_attr->sys_clock_freq / 3;
6226
6227 /* both registers are sign extended */
6228 nominal_frequency = ext_attr->iqm_fs_rate_ofs;
6229 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, (u32 *)&current_frequency, 0);
6230 if (rc != 0) {
6231 pr_err("error %d\n", rc);
6232 goto rw_error;
6233 }
6234
6235 if (ext_attr->pos_image) {
6236 /* negative image */
6237 carrier_frequency_shift = nominal_frequency - current_frequency;
6238 } else {
6239 /* positive image */
6240 carrier_frequency_shift = current_frequency - nominal_frequency;
6241 }
6242
6243 /* carrier Frequency Shift In Hz */
6244 if (carrier_frequency_shift < 0) {
6245 sign = -1;
6246 carrier_frequency_shift *= sign;
6247 }
6248
6249 /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */
6250 mult32(carrier_frequency_shift, sampling_frequency, &data64hi, &data64lo);
6251 *ctl_freq =
6252 (s32) ((((data64lo >> 28) & 0xf) | (data64hi << 4)) * sign);
6253
6254 return 0;
6255rw_error:
6256 return -EIO;
6257}
6258#endif
6259 4885
6260/*============================================================================*/ 4886/*============================================================================*/
6261 4887
@@ -6464,17 +5090,6 @@ set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings,
6464 ext_attr->qam_rf_agc_cfg = *agc_settings; 5090 ext_attr->qam_rf_agc_cfg = *agc_settings;
6465 break; 5091 break;
6466#endif 5092#endif
6467#if 0
6468 case DRX_STANDARD_PAL_SECAM_BG:
6469 case DRX_STANDARD_PAL_SECAM_DK:
6470 case DRX_STANDARD_PAL_SECAM_I:
6471 case DRX_STANDARD_PAL_SECAM_L:
6472 case DRX_STANDARD_PAL_SECAM_LP:
6473 case DRX_STANDARD_NTSC:
6474 case DRX_STANDARD_FM:
6475 ext_attr->atv_rf_agc_cfg = *agc_settings;
6476 break;
6477#endif
6478 default: 5093 default:
6479 return -EIO; 5094 return -EIO;
6480 } 5095 }
@@ -6484,73 +5099,6 @@ rw_error:
6484 return -EIO; 5099 return -EIO;
6485} 5100}
6486 5101
6487#if 0
6488/**
6489* \fn int get_agc_rf ()
6490* \brief get configuration of RF AGC
6491* \param demod instance of demodulator.
6492* \param agc_settings AGC configuration structure
6493* \return int.
6494*/
6495static int
6496get_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6497{
6498 struct i2c_device_addr *dev_addr = NULL;
6499 struct drxj_data *ext_attr = NULL;
6500 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6501 int rc;
6502
6503 dev_addr = demod->my_i2c_dev_addr;
6504 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6505
6506 /* Return stored AGC settings */
6507 standard = agc_settings->standard;
6508 switch (agc_settings->standard) {
6509 case DRX_STANDARD_8VSB:
6510 *agc_settings = ext_attr->vsb_rf_agc_cfg;
6511 break;
6512#ifndef DRXJ_VSB_ONLY
6513 case DRX_STANDARD_ITU_A:
6514 case DRX_STANDARD_ITU_B:
6515 case DRX_STANDARD_ITU_C:
6516 *agc_settings = ext_attr->qam_rf_agc_cfg;
6517 break;
6518#endif
6519#if 0
6520 case DRX_STANDARD_PAL_SECAM_BG:
6521 case DRX_STANDARD_PAL_SECAM_DK:
6522 case DRX_STANDARD_PAL_SECAM_I:
6523 case DRX_STANDARD_PAL_SECAM_L:
6524 case DRX_STANDARD_PAL_SECAM_LP:
6525 case DRX_STANDARD_NTSC:
6526 case DRX_STANDARD_FM:
6527 *agc_settings = ext_attr->atv_rf_agc_cfg;
6528 break;
6529#endif
6530 default:
6531 return -EIO;
6532 }
6533 agc_settings->standard = standard;
6534
6535 /* Get AGC output only if standard is currently active. */
6536 if ((ext_attr->standard == agc_settings->standard) ||
6537 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6538 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6539 (DRXJ_ISATVSTD(ext_attr->standard) &&
6540 DRXJ_ISATVSTD(agc_settings->standard))) {
6541 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, &(agc_settings->output_level), 0);
6542 if (rc != 0) {
6543 pr_err("error %d\n", rc);
6544 goto rw_error;
6545 }
6546 }
6547
6548 return 0;
6549rw_error:
6550 return -EIO;
6551}
6552#endif
6553
6554/** 5102/**
6555* \fn int set_agc_if () 5103* \fn int set_agc_if ()
6556* \brief Configure If AGC 5104* \brief Configure If AGC
@@ -6771,17 +5319,6 @@ set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings,
6771 ext_attr->qam_if_agc_cfg = *agc_settings; 5319 ext_attr->qam_if_agc_cfg = *agc_settings;
6772 break; 5320 break;
6773#endif 5321#endif
6774#if 0
6775 case DRX_STANDARD_PAL_SECAM_BG:
6776 case DRX_STANDARD_PAL_SECAM_DK:
6777 case DRX_STANDARD_PAL_SECAM_I:
6778 case DRX_STANDARD_PAL_SECAM_L:
6779 case DRX_STANDARD_PAL_SECAM_LP:
6780 case DRX_STANDARD_NTSC:
6781 case DRX_STANDARD_FM:
6782 ext_attr->atv_if_agc_cfg = *agc_settings;
6783 break;
6784#endif
6785 default: 5322 default:
6786 return -EIO; 5323 return -EIO;
6787 } 5324 }
@@ -6791,72 +5328,6 @@ rw_error:
6791 return -EIO; 5328 return -EIO;
6792} 5329}
6793 5330
6794#if 0
6795/**
6796* \fn int get_agc_if ()
6797* \brief get configuration of If AGC
6798* \param demod instance of demodulator.
6799* \param agc_settings AGC configuration structure
6800* \return int.
6801*/
6802static int
6803get_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6804{
6805 struct i2c_device_addr *dev_addr = NULL;
6806 struct drxj_data *ext_attr = NULL;
6807 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6808 int rc;
6809
6810 dev_addr = demod->my_i2c_dev_addr;
6811 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6812
6813 /* Return stored ATV AGC settings */
6814 standard = agc_settings->standard;
6815 switch (agc_settings->standard) {
6816 case DRX_STANDARD_8VSB:
6817 *agc_settings = ext_attr->vsb_if_agc_cfg;
6818 break;
6819#ifndef DRXJ_VSB_ONLY
6820 case DRX_STANDARD_ITU_A:
6821 case DRX_STANDARD_ITU_B:
6822 case DRX_STANDARD_ITU_C:
6823 *agc_settings = ext_attr->qam_if_agc_cfg;
6824 break;
6825#endif
6826 case DRX_STANDARD_PAL_SECAM_BG:
6827 case DRX_STANDARD_PAL_SECAM_DK:
6828 case DRX_STANDARD_PAL_SECAM_I:
6829 case DRX_STANDARD_PAL_SECAM_L:
6830 case DRX_STANDARD_PAL_SECAM_LP:
6831 case DRX_STANDARD_NTSC:
6832 case DRX_STANDARD_FM:
6833 *agc_settings = ext_attr->atv_if_agc_cfg;
6834 break;
6835 default:
6836 return -EIO;
6837 }
6838 agc_settings->standard = standard;
6839
6840 /* Get AGC output only if standard is currently active */
6841 if ((ext_attr->standard == agc_settings->standard) ||
6842 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6843 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6844 (DRXJ_ISATVSTD(ext_attr->standard) &&
6845 DRXJ_ISATVSTD(agc_settings->standard))) {
6846 /* read output level */
6847 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, &(agc_settings->output_level), 0);
6848 if (rc != 0) {
6849 pr_err("error %d\n", rc);
6850 goto rw_error;
6851 }
6852 }
6853
6854 return 0;
6855rw_error:
6856 return -EIO;
6857}
6858#endif
6859
6860/** 5331/**
6861* \fn int set_iqm_af () 5332* \fn int set_iqm_af ()
6862* \brief Configure IQM AF registers 5333* \brief Configure IQM AF registers
@@ -7832,46 +6303,6 @@ rw_error:
7832 return -EIO; 6303 return -EIO;
7833} 6304}
7834 6305
7835#if 0
7836/**
7837* \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber)
7838* \brief Get the values of ber in VSB mode
7839* \return Error code
7840*/
7841static int get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ser)
7842{
7843 int rc;
7844 u16 data = 0;
7845 u16 period = 0;
7846 u16 prescale = 0;
7847 u16 symb_errors_mant = 0;
7848 u16 symb_errors_exp = 0;
7849
7850 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &data, 0);
7851 if (rc != 0) {
7852 pr_err("error %d\n", rc);
7853 goto rw_error;
7854 }
7855 period = FEC_RS_MEASUREMENT_PERIOD;
7856 prescale = FEC_RS_MEASUREMENT_PRESCALE;
7857
7858 symb_errors_mant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
7859 symb_errors_exp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
7860 >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
7861
7862 if (period * prescale == 0) {
7863 pr_err("error: period and/or prescale is zero!\n");
7864 return -EIO;
7865 }
7866 *ser = (u32) frac_times1e6((symb_errors_mant << symb_errors_exp) * 1000,
7867 (period * prescale * 77318));
7868
7869 return 0;
7870rw_error:
7871 return -EIO;
7872}
7873#endif
7874
7875/** 6306/**
7876* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer) 6307* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7877* \brief Get the values of MER 6308* \brief Get the values of MER
@@ -7895,88 +6326,6 @@ rw_error:
7895 return -EIO; 6326 return -EIO;
7896} 6327}
7897 6328
7898#if 0
7899/*============================================================================*/
7900/**
7901* \fn int ctrl_get_vsb_constel()
7902* \brief Retreive a VSB constellation point via I2C.
7903* \param demod Pointer to demodulator instance.
7904* \param complex_nr Pointer to the structure in which to store the
7905 constellation point.
7906* \return int.
7907*/
7908static int
7909ctrl_get_vsb_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
7910{
7911 struct i2c_device_addr *dev_addr = NULL;
7912 int rc;
7913 /**< device address */
7914 u16 vsb_top_comm_mb = 0; /**< VSB SL MB configuration */
7915 u16 vsb_top_comm_mb_init = 0; /**< VSB SL MB intial configuration */
7916 u16 re = 0; /**< constellation Re part */
7917 u32 data = 0;
7918
7919 /* read device info */
7920 dev_addr = demod->my_i2c_dev_addr;
7921
7922 /* TODO: */
7923 /* Monitor bus grabbing is an open external interface issue */
7924 /* Needs to be checked when external interface PG is updated */
7925
7926 /* Configure MB (Monitor bus) */
7927 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_COMM_MB__A, &vsb_top_comm_mb_init, 0);
7928 if (rc != 0) {
7929 pr_err("error %d\n", rc);
7930 goto rw_error;
7931 }
7932 /* set observe flag & MB mux */
7933 vsb_top_comm_mb = (vsb_top_comm_mb_init |
7934 VSB_TOP_COMM_MB_OBS_OBS_ON |
7935 VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2);
7936 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb, 0);
7937 if (rc != 0) {
7938 pr_err("error %d\n", rc);
7939 goto rw_error;
7940 }
7941
7942 /* Enable MB grabber in the FEC OC */
7943 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M, 0);
7944 if (rc != 0) {
7945 pr_err("error %d\n", rc);
7946 goto rw_error;
7947 }
7948
7949 /* Disable MB grabber in the FEC OC */
7950 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, 0x0, 0);
7951 if (rc != 0) {
7952 pr_err("error %d\n", rc);
7953 goto rw_error;
7954 }
7955
7956 /* read data */
7957 rc = drxdap_fasi_read_reg32(dev_addr, FEC_OC_OCR_GRAB_RD1__A, &data, 0);
7958 if (rc != 0) {
7959 pr_err("error %d\n", rc);
7960 goto rw_error;
7961 }
7962 re = (u16) (((data >> 10) & 0x300) | ((data >> 2) & 0xff));
7963 if (re & 0x0200)
7964 re |= 0xfc00;
7965 complex_nr->re = re;
7966 complex_nr->im = 0;
7967
7968 /* Restore MB (Monitor bus) */
7969 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb_init, 0);
7970 if (rc != 0) {
7971 pr_err("error %d\n", rc);
7972 goto rw_error;
7973 }
7974
7975 return 0;
7976rw_error:
7977 return -EIO;
7978}
7979#endif
7980 6329
7981/*============================================================================*/ 6330/*============================================================================*/
7982/*== END 8VSB DATAPATH FUNCTIONS ==*/ 6331/*== END 8VSB DATAPATH FUNCTIONS ==*/
@@ -11202,112 +9551,6 @@ rw_error:
11202 return -EIO; 9551 return -EIO;
11203} 9552}
11204 9553
11205#if 0
11206/**
11207* \fn int ctrl_get_qam_constel()
11208* \brief Retreive a QAM constellation point via I2C.
11209* \param demod Pointer to demodulator instance.
11210* \param complex_nr Pointer to the structure in which to store the
11211 constellation point.
11212* \return int.
11213*/
11214static int
11215ctrl_get_qam_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
11216{
11217 struct i2c_device_addr *dev_addr = NULL;
11218 int rc;
11219 u32 data = 0;
11220 u16 fec_oc_ocr_mode = 0;
11221 /**< FEC OCR grabber configuration */
11222 u16 qam_sl_comm_mb = 0;/**< QAM SL MB configuration */
11223 u16 qam_sl_comm_mb_init = 0;
11224 /**< QAM SL MB intial configuration */
11225 u16 im = 0; /**< constellation Im part */
11226 u16 re = 0; /**< constellation Re part */
11227 /**< device address */
11228
11229 /* read device info */
11230 dev_addr = demod->my_i2c_dev_addr;
11231
11232 /* TODO: */
11233 /* Monitor bus grabbing is an open external interface issue */
11234 /* Needs to be checked when external interface PG is updated */
11235
11236 /* Configure MB (Monitor bus) */
11237 rc = drxj_dap_read_reg16(dev_addr, QAM_SL_COMM_MB__A, &qam_sl_comm_mb_init, 0);
11238 if (rc != 0) {
11239 pr_err("error %d\n", rc);
11240 goto rw_error;
11241 }
11242 /* set observe flag & MB mux */
11243 qam_sl_comm_mb = qam_sl_comm_mb_init & (~(QAM_SL_COMM_MB_OBS__M +
11244 QAM_SL_COMM_MB_MUX_OBS__M));
11245 qam_sl_comm_mb |= (QAM_SL_COMM_MB_OBS_ON +
11246 QAM_SL_COMM_MB_MUX_OBS_CONST_CORR);
11247 rc = drxj_dap_write_reg16(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb, 0);
11248 if (rc != 0) {
11249 pr_err("error %d\n", rc);
11250 goto rw_error;
11251 }
11252
11253 /* Enable MB grabber in the FEC OC */
11254 fec_oc_ocr_mode = (/* output select: observe bus */
11255 (FEC_OC_OCR_MODE_MB_SELECT__M &
11256 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) |
11257 /* grabber enable: on */
11258 (FEC_OC_OCR_MODE_GRAB_ENABLE__M &
11259 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) |
11260 /* grabber select: observe bus */
11261 (FEC_OC_OCR_MODE_GRAB_SELECT__M &
11262 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) |
11263 /* grabber mode: continuous */
11264 (FEC_OC_OCR_MODE_GRAB_COUNTED__M &
11265 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B)));
11266 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, fec_oc_ocr_mode, 0);
11267 if (rc != 0) {
11268 pr_err("error %d\n", rc);
11269 goto rw_error;
11270 }
11271
11272 /* Disable MB grabber in the FEC OC */
11273 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_MODE__A, 0x00, 0);
11274 if (rc != 0) {
11275 pr_err("error %d\n", rc);
11276 goto rw_error;
11277 }
11278
11279 /* read data */
11280 rc = drxdap_fasi_read_reg32(dev_addr, FEC_OC_OCR_GRAB_RD0__A, &data, 0);
11281 if (rc != 0) {
11282 pr_err("error %d\n", rc);
11283 goto rw_error;
11284 }
11285 re = (u16) (data & FEC_OC_OCR_GRAB_RD0__M);
11286 im = (u16) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
11287
11288 /* TODO: */
11289 /* interpret data (re & im) according to the Monitor bus mapping ?? */
11290
11291 /* sign extension, 10th bit is sign bit */
11292 if ((re & 0x0200) == 0x0200)
11293 re |= 0xFC00;
11294 if ((im & 0x0200) == 0x0200)
11295 im |= 0xFC00;
11296 complex_nr->re = ((s16) re);
11297 complex_nr->im = ((s16) im);
11298
11299 /* Restore MB (Monitor bus) */
11300 rc = drxj_dap_write_reg16(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb_init, 0);
11301 if (rc != 0) {
11302 pr_err("error %d\n", rc);
11303 goto rw_error;
11304 }
11305
11306 return 0;
11307rw_error:
11308 return -EIO;
11309}
11310#endif /* #if 0 */
11311#endif /* #ifndef DRXJ_VSB_ONLY */ 9554#endif /* #ifndef DRXJ_VSB_ONLY */
11312 9555
11313/*============================================================================*/ 9556/*============================================================================*/
@@ -11376,655 +9619,6 @@ rw_error:
11376*/ 9619*/
11377/* -------------------------------------------------------------------------- */ 9620/* -------------------------------------------------------------------------- */
11378 9621
11379#if 0
11380/**
11381* \brief Get array index for atv coef (ext_attr->atvTopCoefX[index])
11382* \param standard
11383* \param pointer to index
11384* \return int.
11385*
11386*/
11387static int atv_equ_coef_index(enum drx_standard standard, int *index)
11388{
11389 switch (standard) {
11390 case DRX_STANDARD_PAL_SECAM_BG:
11391 *index = (int)DRXJ_COEF_IDX_BG;
11392 break;
11393 case DRX_STANDARD_PAL_SECAM_DK:
11394 *index = (int)DRXJ_COEF_IDX_DK;
11395 break;
11396 case DRX_STANDARD_PAL_SECAM_I:
11397 *index = (int)DRXJ_COEF_IDX_I;
11398 break;
11399 case DRX_STANDARD_PAL_SECAM_L:
11400 *index = (int)DRXJ_COEF_IDX_L;
11401 break;
11402 case DRX_STANDARD_PAL_SECAM_LP:
11403 *index = (int)DRXJ_COEF_IDX_LP;
11404 break;
11405 case DRX_STANDARD_NTSC:
11406 *index = (int)DRXJ_COEF_IDX_MN;
11407 break;
11408 case DRX_STANDARD_FM:
11409 *index = (int)DRXJ_COEF_IDX_FM;
11410 break;
11411 default:
11412 *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */
11413 return -EIO;
11414 break;
11415 }
11416
11417 return 0;
11418}
11419
11420/* -------------------------------------------------------------------------- */
11421/**
11422* \fn int atv_update_config ()
11423* \brief Flush changes in ATV shadow registers to physical registers.
11424* \param demod instance of demodulator
11425* \param force_update don't look at standard or change flags, flush all.
11426* \return int.
11427*
11428*/
11429static int
11430atv_update_config(struct drx_demod_instance *demod, bool force_update)
11431{
11432 struct i2c_device_addr *dev_addr = NULL;
11433 struct drxj_data *ext_attr = NULL;
11434 int rc;
11435
11436 dev_addr = demod->my_i2c_dev_addr;
11437 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11438
11439 /* equalizer coefficients */
11440 if (force_update ||
11441 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_COEF) != 0)) {
11442 int index = 0;
11443
11444 rc = atv_equ_coef_index(ext_attr->standard, &index);
11445 if (rc != 0) {
11446 pr_err("error %d\n", rc);
11447 goto rw_error;
11448 }
11449 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU0__A, ext_attr->atv_top_equ0[index], 0);
11450 if (rc != 0) {
11451 pr_err("error %d\n", rc);
11452 goto rw_error;
11453 }
11454 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU1__A, ext_attr->atv_top_equ1[index], 0);
11455 if (rc != 0) {
11456 pr_err("error %d\n", rc);
11457 goto rw_error;
11458 }
11459 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU2__A, ext_attr->atv_top_equ2[index], 0);
11460 if (rc != 0) {
11461 pr_err("error %d\n", rc);
11462 goto rw_error;
11463 }
11464 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_EQU3__A, ext_attr->atv_top_equ3[index], 0);
11465 if (rc != 0) {
11466 pr_err("error %d\n", rc);
11467 goto rw_error;
11468 }
11469 }
11470
11471 /* bypass fast carrier recovery */
11472 if (force_update) {
11473 u16 data = 0;
11474
11475 rc = drxj_dap_read_reg16(dev_addr, IQM_RT_ROT_BP__A, &data, 0);
11476 if (rc != 0) {
11477 pr_err("error %d\n", rc);
11478 goto rw_error;
11479 }
11480 data &= (~((u16) IQM_RT_ROT_BP_ROT_OFF__M));
11481 if (ext_attr->phase_correction_bypass)
11482 data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
11483 else
11484 data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
11485 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ROT_BP__A, data, 0);
11486 if (rc != 0) {
11487 pr_err("error %d\n", rc);
11488 goto rw_error;
11489 }
11490 }
11491
11492 /* peak filter setting */
11493 if (force_update ||
11494 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) {
11495 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_PEAK__A, ext_attr->atv_top_vid_peak, 0);
11496 if (rc != 0) {
11497 pr_err("error %d\n", rc);
11498 goto rw_error;
11499 }
11500 }
11501
11502 /* noise filter setting */
11503 if (force_update ||
11504 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) {
11505 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_NOISE_TH__A, ext_attr->atv_top_noise_th, 0);
11506 if (rc != 0) {
11507 pr_err("error %d\n", rc);
11508 goto rw_error;
11509 }
11510 }
11511
11512 /* SIF attenuation */
11513 if (force_update ||
11514 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) {
11515 u16 attenuation = 0;
11516
11517 switch (ext_attr->sif_attenuation) {
11518 case DRXJ_SIF_ATTENUATION_0DB:
11519 attenuation = ATV_TOP_AF_SIF_ATT_0DB;
11520 break;
11521 case DRXJ_SIF_ATTENUATION_3DB:
11522 attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
11523 break;
11524 case DRXJ_SIF_ATTENUATION_6DB:
11525 attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
11526 break;
11527 case DRXJ_SIF_ATTENUATION_9DB:
11528 attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
11529 break;
11530 default:
11531 return -EIO;
11532 break;
11533 }
11534 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_AF_SIF_ATT__A, attenuation, 0);
11535 if (rc != 0) {
11536 pr_err("error %d\n", rc);
11537 goto rw_error;
11538 }
11539 }
11540
11541 /* SIF & CVBS enable */
11542 if (force_update ||
11543 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) {
11544 u16 data = 0;
11545
11546 rc = drxj_dap_read_reg16(dev_addr, ATV_TOP_STDBY__A, &data, 0);
11547 if (rc != 0) {
11548 pr_err("error %d\n", rc);
11549 goto rw_error;
11550 }
11551 if (ext_attr->enable_cvbs_output)
11552 data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
11553 else
11554 data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
11555
11556 if (ext_attr->enable_sif_output)
11557 data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
11558 else
11559 data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
11560 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, data, 0);
11561 if (rc != 0) {
11562 pr_err("error %d\n", rc);
11563 goto rw_error;
11564 }
11565 }
11566
11567 ext_attr->atv_cfg_changed_flags = 0;
11568
11569 return 0;
11570rw_error:
11571 return -EIO;
11572}
11573
11574/* -------------------------------------------------------------------------- */
11575/**
11576* \fn int ctrl_set_cfg_atv_output()
11577* \brief Configure ATV ouputs
11578* \param demod instance of demodulator
11579* \param output_cfg output configuaration
11580* \return int.
11581*
11582*/
11583static int
11584ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11585{
11586 struct drxj_data *ext_attr = NULL;
11587 int rc;
11588
11589 /* Check arguments */
11590 if (output_cfg == NULL)
11591 return -EINVAL;
11592
11593 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11594 if (output_cfg->enable_sif_output) {
11595 switch (output_cfg->sif_attenuation) {
11596 case DRXJ_SIF_ATTENUATION_0DB: /* fallthrough */
11597 case DRXJ_SIF_ATTENUATION_3DB: /* fallthrough */
11598 case DRXJ_SIF_ATTENUATION_6DB: /* fallthrough */
11599 case DRXJ_SIF_ATTENUATION_9DB:
11600 /* Do nothing */
11601 break;
11602 default:
11603 return -EINVAL;
11604 break;
11605 }
11606
11607 if (ext_attr->sif_attenuation != output_cfg->sif_attenuation) {
11608 ext_attr->sif_attenuation = output_cfg->sif_attenuation;
11609 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_SIF_ATT;
11610 }
11611 }
11612
11613 if (ext_attr->enable_cvbs_output != output_cfg->enable_cvbs_output) {
11614 ext_attr->enable_cvbs_output = output_cfg->enable_cvbs_output;
11615 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11616 }
11617
11618 if (ext_attr->enable_sif_output != output_cfg->enable_sif_output) {
11619 ext_attr->enable_sif_output = output_cfg->enable_sif_output;
11620 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11621 }
11622
11623 rc = atv_update_config(demod, false);
11624 if (rc != 0) {
11625 pr_err("error %d\n", rc);
11626 goto rw_error;
11627 }
11628
11629 return 0;
11630rw_error:
11631 return -EIO;
11632}
11633
11634/* -------------------------------------------------------------------------- */
11635/**
11636* \fn int ctrl_set_cfg_atv_equ_coef()
11637* \brief Set ATV equalizer coefficients
11638* \param demod instance of demodulator
11639* \param coef the equalizer coefficients
11640* \return int.
11641*
11642*/
11643static int
11644ctrl_set_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11645{
11646 struct drxj_data *ext_attr = NULL;
11647 int rc;
11648 int index;
11649
11650 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11651
11652 /* current standard needs to be an ATV standard */
11653 if (!DRXJ_ISATVSTD(ext_attr->standard))
11654 return -EIO;
11655
11656 /* Check arguments */
11657 if ((coef == NULL) ||
11658 (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) ||
11659 (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) ||
11660 (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) ||
11661 (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) ||
11662 (coef->coef0 < ((s16) ~(ATV_TOP_EQU0_EQU_C0__M >> 1))) ||
11663 (coef->coef1 < ((s16) ~(ATV_TOP_EQU1_EQU_C1__M >> 1))) ||
11664 (coef->coef2 < ((s16) ~(ATV_TOP_EQU2_EQU_C2__M >> 1))) ||
11665 (coef->coef3 < ((s16) ~(ATV_TOP_EQU3_EQU_C3__M >> 1)))) {
11666 return -EINVAL;
11667 }
11668
11669 rc = atv_equ_coef_index(ext_attr->standard, &index);
11670 if (rc != 0) {
11671 pr_err("error %d\n", rc);
11672 goto rw_error;
11673 }
11674 ext_attr->atv_top_equ0[index] = coef->coef0;
11675 ext_attr->atv_top_equ1[index] = coef->coef1;
11676 ext_attr->atv_top_equ2[index] = coef->coef2;
11677 ext_attr->atv_top_equ3[index] = coef->coef3;
11678 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_COEF;
11679
11680 rc = atv_update_config(demod, false);
11681 if (rc != 0) {
11682 pr_err("error %d\n", rc);
11683 goto rw_error;
11684 }
11685
11686 return 0;
11687rw_error:
11688 return -EIO;
11689}
11690
11691/* -------------------------------------------------------------------------- */
11692/**
11693* \fn int ctrl_get_cfg_atv_equ_coef()
11694* \brief Get ATV equ coef settings
11695* \param demod instance of demodulator
11696* \param coef The ATV equ coefficients
11697* \return int.
11698*
11699* The values are read from the shadow registers maintained by the drxdriver
11700* If registers are manipulated outside of the drxdriver scope the reported
11701* settings will not reflect these changes because of the use of shadow
11702* regitsers.
11703*
11704*/
11705static int
11706ctrl_get_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11707{
11708 struct drxj_data *ext_attr = NULL;
11709 int rc;
11710 int index = 0;
11711
11712 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11713
11714 /* current standard needs to be an ATV standard */
11715 if (!DRXJ_ISATVSTD(ext_attr->standard))
11716 return -EIO;
11717
11718 /* Check arguments */
11719 if (coef == NULL)
11720 return -EINVAL;
11721
11722 rc = atv_equ_coef_index(ext_attr->standard, &index);
11723 if (rc != 0) {
11724 pr_err("error %d\n", rc);
11725 goto rw_error;
11726 }
11727 coef->coef0 = ext_attr->atv_top_equ0[index];
11728 coef->coef1 = ext_attr->atv_top_equ1[index];
11729 coef->coef2 = ext_attr->atv_top_equ2[index];
11730 coef->coef3 = ext_attr->atv_top_equ3[index];
11731
11732 return 0;
11733rw_error:
11734 return -EIO;
11735}
11736
11737/* -------------------------------------------------------------------------- */
11738/**
11739* \fn int ctrl_set_cfg_atv_misc()
11740* \brief Set misc. settings for ATV.
11741* \param demod instance of demodulator
11742* \param
11743* \return int.
11744*
11745*/
11746static int
11747ctrl_set_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11748{
11749 struct drxj_data *ext_attr = NULL;
11750 int rc;
11751
11752 /* Check arguments */
11753 if ((settings == NULL) ||
11754 ((settings->peak_filter) < (s16) (-8)) ||
11755 ((settings->peak_filter) > (s16) (15)) ||
11756 ((settings->noise_filter) > 15)) {
11757 return -EINVAL;
11758 }
11759 /* if */
11760 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11761
11762 if (settings->peak_filter != ext_attr->atv_top_vid_peak) {
11763 ext_attr->atv_top_vid_peak = settings->peak_filter;
11764 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_PEAK_FLT;
11765 }
11766
11767 if (settings->noise_filter != ext_attr->atv_top_noise_th) {
11768 ext_attr->atv_top_noise_th = settings->noise_filter;
11769 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_NOISE_FLT;
11770 }
11771
11772 rc = atv_update_config(demod, false);
11773 if (rc != 0) {
11774 pr_err("error %d\n", rc);
11775 goto rw_error;
11776 }
11777
11778 return 0;
11779rw_error:
11780 return -EIO;
11781}
11782
11783/* -------------------------------------------------------------------------- */
11784/**
11785* \fn int ctrl_get_cfg_atv_misc()
11786* \brief Get misc settings of ATV.
11787* \param demod instance of demodulator
11788* \param settings misc. ATV settings
11789* \return int.
11790*
11791* The values are read from the shadow registers maintained by the drxdriver
11792* If registers are manipulated outside of the drxdriver scope the reported
11793* settings will not reflect these changes because of the use of shadow
11794* regitsers.
11795*/
11796static int
11797ctrl_get_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11798{
11799 struct drxj_data *ext_attr = NULL;
11800
11801 /* Check arguments */
11802 if (settings == NULL)
11803 return -EINVAL;
11804
11805 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11806
11807 settings->peak_filter = ext_attr->atv_top_vid_peak;
11808 settings->noise_filter = ext_attr->atv_top_noise_th;
11809
11810 return 0;
11811}
11812
11813/* -------------------------------------------------------------------------- */
11814
11815/* -------------------------------------------------------------------------- */
11816/**
11817* \fn int ctrl_get_cfg_atv_output()
11818* \brief
11819* \param demod instance of demodulator
11820* \param output_cfg output configuaration
11821* \return int.
11822*
11823*/
11824static int
11825ctrl_get_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11826{
11827 int rc;
11828 u16 data = 0;
11829
11830 /* Check arguments */
11831 if (output_cfg == NULL)
11832 return -EINVAL;
11833
11834 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, ATV_TOP_STDBY__A, &data, 0);
11835 if (rc != 0) {
11836 pr_err("error %d\n", rc);
11837 goto rw_error;
11838 }
11839 if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
11840 output_cfg->enable_cvbs_output = true;
11841 else
11842 output_cfg->enable_cvbs_output = false;
11843
11844 if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) {
11845 output_cfg->enable_sif_output = false;
11846 } else {
11847 output_cfg->enable_sif_output = true;
11848 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, ATV_TOP_AF_SIF_ATT__A, &data, 0);
11849 if (rc != 0) {
11850 pr_err("error %d\n", rc);
11851 goto rw_error;
11852 }
11853 output_cfg->sif_attenuation = (enum drxjsif_attenuation) data;
11854 }
11855
11856 return 0;
11857rw_error:
11858 return -EIO;
11859}
11860
11861/* -------------------------------------------------------------------------- */
11862/**
11863* \fn int ctrl_get_cfg_atv_agc_status()
11864* \brief
11865* \param demod instance of demodulator
11866* \param agc_status agc status
11867* \return int.
11868*
11869*/
11870static int
11871ctrl_get_cfg_atv_agc_status(struct drx_demod_instance *demod,
11872 struct drxj_cfg_atv_agc_status *agc_status)
11873{
11874 struct i2c_device_addr *dev_addr = NULL;
11875 int rc;
11876 u16 data = 0;
11877 u32 tmp = 0;
11878
11879 /* Check arguments */
11880 if (agc_status == NULL)
11881 return -EINVAL;
11882
11883 dev_addr = demod->my_i2c_dev_addr;
11884
11885 /*
11886 RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
11887 = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
11888
11889 IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
11890 */
11891 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &data, 0);
11892 if (rc != 0) {
11893 pr_err("error %d\n", rc);
11894 goto rw_error;
11895 }
11896 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
11897 agc_status->rf_agc_gain = (u16) (tmp / 1000); /* uA */
11898 /* rounding */
11899 if (tmp % 1000 >= 500)
11900 (agc_status->rf_agc_gain)++;
11901
11902 /*
11903 IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
11904 = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
11905
11906 IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
11907 */
11908 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &data, 0);
11909 if (rc != 0) {
11910 pr_err("error %d\n", rc);
11911 goto rw_error;
11912 }
11913 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
11914 agc_status->if_agc_gain = (u16) (tmp / 1000); /* uA */
11915 /* rounding */
11916 if (tmp % 1000 >= 500)
11917 (agc_status->if_agc_gain)++;
11918
11919 /*
11920 videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
11921 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
11922 = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
11923 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
11924 = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
11925 */
11926
11927 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &data, 0);
11928 if (rc != 0) {
11929 pr_err("error %d\n", rc);
11930 goto rw_error;
11931 }
11932 /* dividing by 32 inclusive rounding */
11933 data >>= 4;
11934 if ((data & 1) != 0)
11935 data++;
11936 data >>= 1;
11937 agc_status->video_agc_gain = ((s16) data) - 75; /* 0.1 dB */
11938
11939 /*
11940 audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
11941 = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
11942 = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
11943 = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
11944 = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
11945 */
11946
11947 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &data, 0);
11948 if (rc != 0) {
11949 pr_err("error %d\n", rc);
11950 goto rw_error;
11951 }
11952 data &= SCU_RAM_ATV_SIF_GAIN__M;
11953 /* dividing by 2 inclusive rounding */
11954 if ((data & 1) != 0)
11955 data++;
11956 data >>= 1;
11957 agc_status->audio_agc_gain = ((s16) data) - 4; /* 0.1 dB */
11958
11959 /* Loop gain's */
11960 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
11961 if (rc != 0) {
11962 pr_err("error %d\n", rc);
11963 goto rw_error;
11964 }
11965 agc_status->video_agc_loop_gain =
11966 ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B);
11967 agc_status->rf_agc_loop_gain =
11968 ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B);
11969 agc_status->if_agc_loop_gain =
11970 ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B);
11971
11972 return 0;
11973rw_error:
11974 return -EIO;
11975}
11976
11977/* -------------------------------------------------------------------------- */
11978
11979/**
11980* \fn int power_up_atv ()
11981* \brief Power up ATV.
11982* \param demod instance of demodulator
11983* \param standard either NTSC or FM (sub strandard for ATV )
11984* \return int.
11985*
11986* * Starts ATV and IQM
11987* * AUdio already started during standard init for ATV.
11988*/
11989static int power_up_atv(struct drx_demod_instance *demod, enum drx_standard standard)
11990{
11991 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11992 int rc;
11993
11994 /* ATV NTSC */
11995 rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE, 0);
11996 if (rc != 0) {
11997 pr_err("error %d\n", rc);
11998 goto rw_error;
11999 }
12000 /* turn on IQM_AF */
12001 rc = set_iqm_af(demod, true);
12002 if (rc != 0) {
12003 pr_err("error %d\n", rc);
12004 goto rw_error;
12005 }
12006 rc = adc_synchronization(demod);
12007 if (rc != 0) {
12008 pr_err("error %d\n", rc);
12009 goto rw_error;
12010 }
12011
12012 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
12013 if (rc != 0) {
12014 pr_err("error %d\n", rc);
12015 goto rw_error;
12016 }
12017
12018 /* Audio, already done during set standard */
12019
12020 return 0;
12021rw_error:
12022 return -EIO;
12023}
12024#endif
12025
12026/* -------------------------------------------------------------------------- */
12027
12028/** 9622/**
12029* \fn int power_down_atv () 9623* \fn int power_down_atv ()
12030* \brief Power down ATV. 9624* \brief Power down ATV.
@@ -12124,1481 +9718,6 @@ rw_error:
12124 return -EIO; 9718 return -EIO;
12125} 9719}
12126 9720
12127/* -------------------------------------------------------------------------- */
12128/**
12129* \fn int set_atv_standard ()
12130* \brief Set up ATV demodulator.
12131* \param demod instance of demodulator
12132* \param standard either NTSC or FM (sub strandard for ATV )
12133* \return int.
12134*
12135* Init all channel independent registers.
12136* Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
12137*
12138*/
12139#if 0
12140#define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
12141static int
12142set_atv_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
12143{
12144/* TODO: enable alternative for tap settings via external file
12145
12146something like:
12147#ifdef DRXJ_ATV_COEF_FILE
12148#include DRXJ_ATV_COEF_FILE
12149#else
12150... code defining fixed coef's ...
12151#endif
12152
12153Cutsomer must create file "customer_coefs.c.inc" containing
12154modified copy off the constants below, and define the compiler
12155switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
12156
12157Still to check if this will work; DRXJ_16TO8 macro may cause
12158trouble ?
12159*/
12160 const u8 ntsc_taps_re[] = {
12161 DRXJ_16TO8(-12), /* re0 */
12162 DRXJ_16TO8(-9), /* re1 */
12163 DRXJ_16TO8(9), /* re2 */
12164 DRXJ_16TO8(19), /* re3 */
12165 DRXJ_16TO8(-4), /* re4 */
12166 DRXJ_16TO8(-24), /* re5 */
12167 DRXJ_16TO8(-6), /* re6 */
12168 DRXJ_16TO8(16), /* re7 */
12169 DRXJ_16TO8(6), /* re8 */
12170 DRXJ_16TO8(-16), /* re9 */
12171 DRXJ_16TO8(-5), /* re10 */
12172 DRXJ_16TO8(13), /* re11 */
12173 DRXJ_16TO8(-2), /* re12 */
12174 DRXJ_16TO8(-20), /* re13 */
12175 DRXJ_16TO8(4), /* re14 */
12176 DRXJ_16TO8(25), /* re15 */
12177 DRXJ_16TO8(-6), /* re16 */
12178 DRXJ_16TO8(-36), /* re17 */
12179 DRXJ_16TO8(2), /* re18 */
12180 DRXJ_16TO8(38), /* re19 */
12181 DRXJ_16TO8(-10), /* re20 */
12182 DRXJ_16TO8(-48), /* re21 */
12183 DRXJ_16TO8(35), /* re22 */
12184 DRXJ_16TO8(94), /* re23 */
12185 DRXJ_16TO8(-59), /* re24 */
12186 DRXJ_16TO8(-217), /* re25 */
12187 DRXJ_16TO8(50), /* re26 */
12188 DRXJ_16TO8(679) /* re27 */
12189 };
12190 const u8 ntsc_taps_im[] = {
12191 DRXJ_16TO8(11), /* im0 */
12192 DRXJ_16TO8(1), /* im1 */
12193 DRXJ_16TO8(-10), /* im2 */
12194 DRXJ_16TO8(2), /* im3 */
12195 DRXJ_16TO8(24), /* im4 */
12196 DRXJ_16TO8(21), /* im5 */
12197 DRXJ_16TO8(1), /* im6 */
12198 DRXJ_16TO8(-4), /* im7 */
12199 DRXJ_16TO8(7), /* im8 */
12200 DRXJ_16TO8(14), /* im9 */
12201 DRXJ_16TO8(27), /* im10 */
12202 DRXJ_16TO8(42), /* im11 */
12203 DRXJ_16TO8(22), /* im12 */
12204 DRXJ_16TO8(-20), /* im13 */
12205 DRXJ_16TO8(2), /* im14 */
12206 DRXJ_16TO8(98), /* im15 */
12207 DRXJ_16TO8(122), /* im16 */
12208 DRXJ_16TO8(0), /* im17 */
12209 DRXJ_16TO8(-85), /* im18 */
12210 DRXJ_16TO8(51), /* im19 */
12211 DRXJ_16TO8(247), /* im20 */
12212 DRXJ_16TO8(192), /* im21 */
12213 DRXJ_16TO8(-55), /* im22 */
12214 DRXJ_16TO8(-95), /* im23 */
12215 DRXJ_16TO8(217), /* im24 */
12216 DRXJ_16TO8(544), /* im25 */
12217 DRXJ_16TO8(553), /* im26 */
12218 DRXJ_16TO8(302) /* im27 */
12219 };
12220 const u8 bg_taps_re[] = {
12221 DRXJ_16TO8(-18), /* re0 */
12222 DRXJ_16TO8(18), /* re1 */
12223 DRXJ_16TO8(19), /* re2 */
12224 DRXJ_16TO8(-26), /* re3 */
12225 DRXJ_16TO8(-20), /* re4 */
12226 DRXJ_16TO8(36), /* re5 */
12227 DRXJ_16TO8(5), /* re6 */
12228 DRXJ_16TO8(-51), /* re7 */
12229 DRXJ_16TO8(15), /* re8 */
12230 DRXJ_16TO8(45), /* re9 */
12231 DRXJ_16TO8(-46), /* re10 */
12232 DRXJ_16TO8(-24), /* re11 */
12233 DRXJ_16TO8(71), /* re12 */
12234 DRXJ_16TO8(-17), /* re13 */
12235 DRXJ_16TO8(-83), /* re14 */
12236 DRXJ_16TO8(74), /* re15 */
12237 DRXJ_16TO8(75), /* re16 */
12238 DRXJ_16TO8(-134), /* re17 */
12239 DRXJ_16TO8(-40), /* re18 */
12240 DRXJ_16TO8(191), /* re19 */
12241 DRXJ_16TO8(-11), /* re20 */
12242 DRXJ_16TO8(-233), /* re21 */
12243 DRXJ_16TO8(74), /* re22 */
12244 DRXJ_16TO8(271), /* re23 */
12245 DRXJ_16TO8(-132), /* re24 */
12246 DRXJ_16TO8(-341), /* re25 */
12247 DRXJ_16TO8(172), /* re26 */
12248 DRXJ_16TO8(801) /* re27 */
12249 };
12250 const u8 bg_taps_im[] = {
12251 DRXJ_16TO8(-24), /* im0 */
12252 DRXJ_16TO8(-10), /* im1 */
12253 DRXJ_16TO8(9), /* im2 */
12254 DRXJ_16TO8(-5), /* im3 */
12255 DRXJ_16TO8(-51), /* im4 */
12256 DRXJ_16TO8(-17), /* im5 */
12257 DRXJ_16TO8(31), /* im6 */
12258 DRXJ_16TO8(-48), /* im7 */
12259 DRXJ_16TO8(-95), /* im8 */
12260 DRXJ_16TO8(25), /* im9 */
12261 DRXJ_16TO8(37), /* im10 */
12262 DRXJ_16TO8(-123), /* im11 */
12263 DRXJ_16TO8(-77), /* im12 */
12264 DRXJ_16TO8(94), /* im13 */
12265 DRXJ_16TO8(-10), /* im14 */
12266 DRXJ_16TO8(-149), /* im15 */
12267 DRXJ_16TO8(10), /* im16 */
12268 DRXJ_16TO8(108), /* im17 */
12269 DRXJ_16TO8(-49), /* im18 */
12270 DRXJ_16TO8(-59), /* im19 */
12271 DRXJ_16TO8(90), /* im20 */
12272 DRXJ_16TO8(73), /* im21 */
12273 DRXJ_16TO8(55), /* im22 */
12274 DRXJ_16TO8(148), /* im23 */
12275 DRXJ_16TO8(86), /* im24 */
12276 DRXJ_16TO8(146), /* im25 */
12277 DRXJ_16TO8(687), /* im26 */
12278 DRXJ_16TO8(877) /* im27 */
12279 };
12280 const u8 dk_i_l_lp_taps_re[] = {
12281 DRXJ_16TO8(-23), /* re0 */
12282 DRXJ_16TO8(9), /* re1 */
12283 DRXJ_16TO8(16), /* re2 */
12284 DRXJ_16TO8(-26), /* re3 */
12285 DRXJ_16TO8(-3), /* re4 */
12286 DRXJ_16TO8(13), /* re5 */
12287 DRXJ_16TO8(-19), /* re6 */
12288 DRXJ_16TO8(-3), /* re7 */
12289 DRXJ_16TO8(13), /* re8 */
12290 DRXJ_16TO8(-26), /* re9 */
12291 DRXJ_16TO8(-4), /* re10 */
12292 DRXJ_16TO8(28), /* re11 */
12293 DRXJ_16TO8(-15), /* re12 */
12294 DRXJ_16TO8(-14), /* re13 */
12295 DRXJ_16TO8(10), /* re14 */
12296 DRXJ_16TO8(1), /* re15 */
12297 DRXJ_16TO8(39), /* re16 */
12298 DRXJ_16TO8(-18), /* re17 */
12299 DRXJ_16TO8(-90), /* re18 */
12300 DRXJ_16TO8(109), /* re19 */
12301 DRXJ_16TO8(113), /* re20 */
12302 DRXJ_16TO8(-235), /* re21 */
12303 DRXJ_16TO8(-49), /* re22 */
12304 DRXJ_16TO8(359), /* re23 */
12305 DRXJ_16TO8(-79), /* re24 */
12306 DRXJ_16TO8(-459), /* re25 */
12307 DRXJ_16TO8(206), /* re26 */
12308 DRXJ_16TO8(894) /* re27 */
12309 };
12310 const u8 dk_i_l_lp_taps_im[] = {
12311 DRXJ_16TO8(-8), /* im0 */
12312 DRXJ_16TO8(-20), /* im1 */
12313 DRXJ_16TO8(17), /* im2 */
12314 DRXJ_16TO8(-14), /* im3 */
12315 DRXJ_16TO8(-52), /* im4 */
12316 DRXJ_16TO8(4), /* im5 */
12317 DRXJ_16TO8(9), /* im6 */
12318 DRXJ_16TO8(-62), /* im7 */
12319 DRXJ_16TO8(-47), /* im8 */
12320 DRXJ_16TO8(0), /* im9 */
12321 DRXJ_16TO8(-20), /* im10 */
12322 DRXJ_16TO8(-48), /* im11 */
12323 DRXJ_16TO8(-65), /* im12 */
12324 DRXJ_16TO8(-23), /* im13 */
12325 DRXJ_16TO8(44), /* im14 */
12326 DRXJ_16TO8(-60), /* im15 */
12327 DRXJ_16TO8(-113), /* im16 */
12328 DRXJ_16TO8(92), /* im17 */
12329 DRXJ_16TO8(81), /* im18 */
12330 DRXJ_16TO8(-125), /* im19 */
12331 DRXJ_16TO8(28), /* im20 */
12332 DRXJ_16TO8(182), /* im21 */
12333 DRXJ_16TO8(35), /* im22 */
12334 DRXJ_16TO8(94), /* im23 */
12335 DRXJ_16TO8(180), /* im24 */
12336 DRXJ_16TO8(134), /* im25 */
12337 DRXJ_16TO8(657), /* im26 */
12338 DRXJ_16TO8(1023) /* im27 */
12339 };
12340 const u8 fm_taps_re[] = {
12341 DRXJ_16TO8(0), /* re0 */
12342 DRXJ_16TO8(0), /* re1 */
12343 DRXJ_16TO8(0), /* re2 */
12344 DRXJ_16TO8(0), /* re3 */
12345 DRXJ_16TO8(0), /* re4 */
12346 DRXJ_16TO8(0), /* re5 */
12347 DRXJ_16TO8(0), /* re6 */
12348 DRXJ_16TO8(0), /* re7 */
12349 DRXJ_16TO8(0), /* re8 */
12350 DRXJ_16TO8(0), /* re9 */
12351 DRXJ_16TO8(0), /* re10 */
12352 DRXJ_16TO8(0), /* re11 */
12353 DRXJ_16TO8(0), /* re12 */
12354 DRXJ_16TO8(0), /* re13 */
12355 DRXJ_16TO8(0), /* re14 */
12356 DRXJ_16TO8(0), /* re15 */
12357 DRXJ_16TO8(0), /* re16 */
12358 DRXJ_16TO8(0), /* re17 */
12359 DRXJ_16TO8(0), /* re18 */
12360 DRXJ_16TO8(0), /* re19 */
12361 DRXJ_16TO8(0), /* re20 */
12362 DRXJ_16TO8(0), /* re21 */
12363 DRXJ_16TO8(0), /* re22 */
12364 DRXJ_16TO8(0), /* re23 */
12365 DRXJ_16TO8(0), /* re24 */
12366 DRXJ_16TO8(0), /* re25 */
12367 DRXJ_16TO8(0), /* re26 */
12368 DRXJ_16TO8(0) /* re27 */
12369 };
12370 const u8 fm_taps_im[] = {
12371 DRXJ_16TO8(-6), /* im0 */
12372 DRXJ_16TO8(2), /* im1 */
12373 DRXJ_16TO8(14), /* im2 */
12374 DRXJ_16TO8(-38), /* im3 */
12375 DRXJ_16TO8(58), /* im4 */
12376 DRXJ_16TO8(-62), /* im5 */
12377 DRXJ_16TO8(42), /* im6 */
12378 DRXJ_16TO8(0), /* im7 */
12379 DRXJ_16TO8(-45), /* im8 */
12380 DRXJ_16TO8(73), /* im9 */
12381 DRXJ_16TO8(-65), /* im10 */
12382 DRXJ_16TO8(23), /* im11 */
12383 DRXJ_16TO8(34), /* im12 */
12384 DRXJ_16TO8(-77), /* im13 */
12385 DRXJ_16TO8(80), /* im14 */
12386 DRXJ_16TO8(-39), /* im15 */
12387 DRXJ_16TO8(-25), /* im16 */
12388 DRXJ_16TO8(78), /* im17 */
12389 DRXJ_16TO8(-90), /* im18 */
12390 DRXJ_16TO8(52), /* im19 */
12391 DRXJ_16TO8(16), /* im20 */
12392 DRXJ_16TO8(-77), /* im21 */
12393 DRXJ_16TO8(97), /* im22 */
12394 DRXJ_16TO8(-62), /* im23 */
12395 DRXJ_16TO8(-8), /* im24 */
12396 DRXJ_16TO8(75), /* im25 */
12397 DRXJ_16TO8(-100), /* im26 */
12398 DRXJ_16TO8(70) /* im27 */
12399 };
12400
12401 struct i2c_device_addr *dev_addr = NULL;
12402 struct drxjscu_cmd cmd_scu = { /* command */ 0,
12403 /* parameter_len */ 0,
12404 /* result_len */ 0,
12405 /* *parameter */ NULL,
12406 /* *result */ NULL
12407 };
12408 u16 cmd_result = 0;
12409 u16 cmd_param = 0;
12410 struct drxj_data *ext_attr = NULL;
12411 int rc;
12412
12413 ext_attr = (struct drxj_data *) demod->my_ext_attr;
12414 dev_addr = demod->my_i2c_dev_addr;
12415
12416 rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
12417 if (rc != 0) {
12418 pr_err("error %d\n", rc);
12419 goto rw_error;
12420 }
12421 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
12422 if (rc != 0) {
12423 pr_err("error %d\n", rc);
12424 goto rw_error;
12425 }
12426 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
12427 if (rc != 0) {
12428 pr_err("error %d\n", rc);
12429 goto rw_error;
12430 }
12431 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
12432 if (rc != 0) {
12433 pr_err("error %d\n", rc);
12434 goto rw_error;
12435 }
12436 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
12437 if (rc != 0) {
12438 pr_err("error %d\n", rc);
12439 goto rw_error;
12440 }
12441 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
12442 if (rc != 0) {
12443 pr_err("error %d\n", rc);
12444 goto rw_error;
12445 }
12446 /* Reset ATV SCU */
12447 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12448 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
12449 cmd_scu.parameter_len = 0;
12450 cmd_scu.result_len = 1;
12451 cmd_scu.parameter = NULL;
12452 cmd_scu.result = &cmd_result;
12453 rc = scu_command(dev_addr, &cmd_scu);
12454 if (rc != 0) {
12455 pr_err("error %d\n", rc);
12456 goto rw_error;
12457 }
12458
12459 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE, 0);
12460 if (rc != 0) {
12461 pr_err("error %d\n", rc);
12462 goto rw_error;
12463 }
12464
12465 /* TODO remove AUTO/OFF patches after ucode fix. */
12466 switch (*standard) {
12467 case DRX_STANDARD_NTSC:
12468 /* NTSC */
12469 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_MN;
12470
12471 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN, 0);
12472 if (rc != 0) {
12473 pr_err("error %d\n", rc);
12474 goto rw_error;
12475 }
12476 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12477 if (rc != 0) {
12478 pr_err("error %d\n", rc);
12479 goto rw_error;
12480 }
12481 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(ntsc_taps_re), ((u8 *)ntsc_taps_re), 0);
12482 if (rc != 0) {
12483 pr_err("error %d\n", rc);
12484 goto rw_error;
12485 }
12486 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im), ((u8 *)ntsc_taps_im), 0);
12487 if (rc != 0) {
12488 pr_err("error %d\n", rc);
12489 goto rw_error;
12490 }
12491
12492 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN, 0);
12493 if (rc != 0) {
12494 pr_err("error %d\n", rc);
12495 goto rw_error;
12496 }
12497 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);
12498 if (rc != 0) {
12499 pr_err("error %d\n", rc);
12500 goto rw_error;
12501 }
12502 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_MN, 0);
12503 if (rc != 0) {
12504 pr_err("error %d\n", rc);
12505 goto rw_error;
12506 }
12507 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_MN | ATV_TOP_STD_VID_POL_MN), 0);
12508 if (rc != 0) {
12509 pr_err("error %d\n", rc);
12510 goto rw_error;
12511 }
12512 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_MN, 0);
12513 if (rc != 0) {
12514 pr_err("error %d\n", rc);
12515 goto rw_error;
12516 }
12517
12518 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);
12519 if (rc != 0) {
12520 pr_err("error %d\n", rc);
12521 goto rw_error;
12522 }
12523 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12524 if (rc != 0) {
12525 pr_err("error %d\n", rc);
12526 goto rw_error;
12527 }
12528 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12529 if (rc != 0) {
12530 pr_err("error %d\n", rc);
12531 goto rw_error;
12532 }
12533 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);
12534 if (rc != 0) {
12535 pr_err("error %d\n", rc);
12536 goto rw_error;
12537 }
12538 ext_attr->phase_correction_bypass = false;
12539 ext_attr->enable_cvbs_output = true;
12540 break;
12541 case DRX_STANDARD_FM:
12542 /* FM */
12543 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_FM;
12544
12545 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2994, 0);
12546 if (rc != 0) {
12547 pr_err("error %d\n", rc);
12548 goto rw_error;
12549 }
12550 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 0, 0);
12551 if (rc != 0) {
12552 pr_err("error %d\n", rc);
12553 goto rw_error;
12554 }
12555 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re), ((u8 *)fm_taps_re), 0);
12556 if (rc != 0) {
12557 pr_err("error %d\n", rc);
12558 goto rw_error;
12559 }
12560 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im), ((u8 *)fm_taps_im), 0);
12561 if (rc != 0) {
12562 pr_err("error %d\n", rc);
12563 goto rw_error;
12564 }
12565 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM | ATV_TOP_STD_VID_POL_FM), 0);
12566 if (rc != 0) {
12567 pr_err("error %d\n", rc);
12568 goto rw_error;
12569 }
12570 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_MOD_CONTROL__A, 0, 0);
12571 if (rc != 0) {
12572 pr_err("error %d\n", rc);
12573 goto rw_error;
12574 }
12575 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_CONT__A, 0, 0);
12576 if (rc != 0) {
12577 pr_err("error %d\n", rc);
12578 goto rw_error;
12579 }
12580
12581 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);
12582 if (rc != 0) {
12583 pr_err("error %d\n", rc);
12584 goto rw_error;
12585 }
12586 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF, 0);
12587 if (rc != 0) {
12588 pr_err("error %d\n", rc);
12589 goto rw_error;
12590 }
12591 ext_attr->phase_correction_bypass = true;
12592 ext_attr->enable_cvbs_output = false;
12593 break;
12594 case DRX_STANDARD_PAL_SECAM_BG:
12595 /* PAL/SECAM B/G */
12596 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_B;
12597
12598 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 1820, 0);
12599 if (rc != 0) {
12600 pr_err("error %d\n", rc);
12601 goto rw_error;
12602 } /* TODO check with IS */
12603 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12604 if (rc != 0) {
12605 pr_err("error %d\n", rc);
12606 goto rw_error;
12607 }
12608 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re), ((u8 *)bg_taps_re), 0);
12609 if (rc != 0) {
12610 pr_err("error %d\n", rc);
12611 goto rw_error;
12612 }
12613 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im), ((u8 *)bg_taps_im), 0);
12614 if (rc != 0) {
12615 pr_err("error %d\n", rc);
12616 goto rw_error;
12617 }
12618 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG, 0);
12619 if (rc != 0) {
12620 pr_err("error %d\n", rc);
12621 goto rw_error;
12622 }
12623 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG, 0);
12624 if (rc != 0) {
12625 pr_err("error %d\n", rc);
12626 goto rw_error;
12627 }
12628 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);
12629 if (rc != 0) {
12630 pr_err("error %d\n", rc);
12631 goto rw_error;
12632 }
12633 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG, 0);
12634 if (rc != 0) {
12635 pr_err("error %d\n", rc);
12636 goto rw_error;
12637 }
12638 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG | ATV_TOP_STD_VID_POL_BG), 0);
12639 if (rc != 0) {
12640 pr_err("error %d\n", rc);
12641 goto rw_error;
12642 }
12643 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);
12644 if (rc != 0) {
12645 pr_err("error %d\n", rc);
12646 goto rw_error;
12647 }
12648 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12649 if (rc != 0) {
12650 pr_err("error %d\n", rc);
12651 goto rw_error;
12652 }
12653 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12654 if (rc != 0) {
12655 pr_err("error %d\n", rc);
12656 goto rw_error;
12657 }
12658 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);
12659 if (rc != 0) {
12660 pr_err("error %d\n", rc);
12661 goto rw_error;
12662 }
12663 ext_attr->phase_correction_bypass = false;
12664 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12665 ext_attr->enable_cvbs_output = true;
12666 break;
12667 case DRX_STANDARD_PAL_SECAM_DK:
12668 /* PAL/SECAM D/K */
12669 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_DK;
12670
12671 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12672 if (rc != 0) {
12673 pr_err("error %d\n", rc);
12674 goto rw_error;
12675 } /* TODO check with IS */
12676 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12677 if (rc != 0) {
12678 pr_err("error %d\n", rc);
12679 goto rw_error;
12680 }
12681 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);
12682 if (rc != 0) {
12683 pr_err("error %d\n", rc);
12684 goto rw_error;
12685 }
12686 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);
12687 if (rc != 0) {
12688 pr_err("error %d\n", rc);
12689 goto rw_error;
12690 }
12691 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK, 0);
12692 if (rc != 0) {
12693 pr_err("error %d\n", rc);
12694 goto rw_error;
12695 }
12696 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK, 0);
12697 if (rc != 0) {
12698 pr_err("error %d\n", rc);
12699 goto rw_error;
12700 }
12701 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);
12702 if (rc != 0) {
12703 pr_err("error %d\n", rc);
12704 goto rw_error;
12705 }
12706 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK, 0);
12707 if (rc != 0) {
12708 pr_err("error %d\n", rc);
12709 goto rw_error;
12710 }
12711 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK | ATV_TOP_STD_VID_POL_DK), 0);
12712 if (rc != 0) {
12713 pr_err("error %d\n", rc);
12714 goto rw_error;
12715 }
12716 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);
12717 if (rc != 0) {
12718 pr_err("error %d\n", rc);
12719 goto rw_error;
12720 }
12721 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12722 if (rc != 0) {
12723 pr_err("error %d\n", rc);
12724 goto rw_error;
12725 }
12726 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12727 if (rc != 0) {
12728 pr_err("error %d\n", rc);
12729 goto rw_error;
12730 }
12731 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);
12732 if (rc != 0) {
12733 pr_err("error %d\n", rc);
12734 goto rw_error;
12735 }
12736 ext_attr->phase_correction_bypass = false;
12737 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12738 ext_attr->enable_cvbs_output = true;
12739 break;
12740 case DRX_STANDARD_PAL_SECAM_I:
12741 /* PAL/SECAM I */
12742 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_I;
12743
12744 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12745 if (rc != 0) {
12746 pr_err("error %d\n", rc);
12747 goto rw_error;
12748 } /* TODO check with IS */
12749 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12750 if (rc != 0) {
12751 pr_err("error %d\n", rc);
12752 goto rw_error;
12753 }
12754 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);
12755 if (rc != 0) {
12756 pr_err("error %d\n", rc);
12757 goto rw_error;
12758 }
12759 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);
12760 if (rc != 0) {
12761 pr_err("error %d\n", rc);
12762 goto rw_error;
12763 }
12764 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I, 0);
12765 if (rc != 0) {
12766 pr_err("error %d\n", rc);
12767 goto rw_error;
12768 }
12769 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I, 0);
12770 if (rc != 0) {
12771 pr_err("error %d\n", rc);
12772 goto rw_error;
12773 }
12774 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);
12775 if (rc != 0) {
12776 pr_err("error %d\n", rc);
12777 goto rw_error;
12778 }
12779 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I, 0);
12780 if (rc != 0) {
12781 pr_err("error %d\n", rc);
12782 goto rw_error;
12783 }
12784 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I | ATV_TOP_STD_VID_POL_I), 0);
12785 if (rc != 0) {
12786 pr_err("error %d\n", rc);
12787 goto rw_error;
12788 }
12789 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);
12790 if (rc != 0) {
12791 pr_err("error %d\n", rc);
12792 goto rw_error;
12793 }
12794 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12795 if (rc != 0) {
12796 pr_err("error %d\n", rc);
12797 goto rw_error;
12798 }
12799 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12800 if (rc != 0) {
12801 pr_err("error %d\n", rc);
12802 goto rw_error;
12803 }
12804 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);
12805 if (rc != 0) {
12806 pr_err("error %d\n", rc);
12807 goto rw_error;
12808 }
12809 ext_attr->phase_correction_bypass = false;
12810 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12811 ext_attr->enable_cvbs_output = true;
12812 break;
12813 case DRX_STANDARD_PAL_SECAM_L:
12814 /* PAL/SECAM L with negative modulation */
12815 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_L;
12816
12817 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12818 if (rc != 0) {
12819 pr_err("error %d\n", rc);
12820 goto rw_error;
12821 } /* TODO check with IS */
12822 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L, 0);
12823 if (rc != 0) {
12824 pr_err("error %d\n", rc);
12825 goto rw_error;
12826 }
12827 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12828 if (rc != 0) {
12829 pr_err("error %d\n", rc);
12830 goto rw_error;
12831 }
12832 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);
12833 if (rc != 0) {
12834 pr_err("error %d\n", rc);
12835 goto rw_error;
12836 }
12837 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);
12838 if (rc != 0) {
12839 pr_err("error %d\n", rc);
12840 goto rw_error;
12841 }
12842 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12843 if (rc != 0) {
12844 pr_err("error %d\n", rc);
12845 goto rw_error;
12846 } /* TODO check with IS */
12847 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);
12848 if (rc != 0) {
12849 pr_err("error %d\n", rc);
12850 goto rw_error;
12851 }
12852 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L, 0);
12853 if (rc != 0) {
12854 pr_err("error %d\n", rc);
12855 goto rw_error;
12856 }
12857 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L | ATV_TOP_STD_VID_POL_L), 0);
12858 if (rc != 0) {
12859 pr_err("error %d\n", rc);
12860 goto rw_error;
12861 }
12862 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);
12863 if (rc != 0) {
12864 pr_err("error %d\n", rc);
12865 goto rw_error;
12866 }
12867 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12868 if (rc != 0) {
12869 pr_err("error %d\n", rc);
12870 goto rw_error;
12871 }
12872 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12873 if (rc != 0) {
12874 pr_err("error %d\n", rc);
12875 goto rw_error;
12876 }
12877 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);
12878 if (rc != 0) {
12879 pr_err("error %d\n", rc);
12880 goto rw_error;
12881 }
12882 ext_attr->phase_correction_bypass = false;
12883 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12884 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12885 ext_attr->enable_cvbs_output = true;
12886 break;
12887 case DRX_STANDARD_PAL_SECAM_LP:
12888 /* PAL/SECAM L with positive modulation */
12889 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_LP;
12890
12891 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_LP, 0);
12892 if (rc != 0) {
12893 pr_err("error %d\n", rc);
12894 goto rw_error;
12895 }
12896 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12897 if (rc != 0) {
12898 pr_err("error %d\n", rc);
12899 goto rw_error;
12900 } /* TODO check with IS */
12901 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12902 if (rc != 0) {
12903 pr_err("error %d\n", rc);
12904 goto rw_error;
12905 }
12906 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);
12907 if (rc != 0) {
12908 pr_err("error %d\n", rc);
12909 goto rw_error;
12910 }
12911 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);
12912 if (rc != 0) {
12913 pr_err("error %d\n", rc);
12914 goto rw_error;
12915 }
12916 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12917 if (rc != 0) {
12918 pr_err("error %d\n", rc);
12919 goto rw_error;
12920 } /* TODO check with IS */
12921 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);
12922 if (rc != 0) {
12923 pr_err("error %d\n", rc);
12924 goto rw_error;
12925 }
12926 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP, 0);
12927 if (rc != 0) {
12928 pr_err("error %d\n", rc);
12929 goto rw_error;
12930 }
12931 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP | ATV_TOP_STD_VID_POL_LP), 0);
12932 if (rc != 0) {
12933 pr_err("error %d\n", rc);
12934 goto rw_error;
12935 }
12936 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);
12937 if (rc != 0) {
12938 pr_err("error %d\n", rc);
12939 goto rw_error;
12940 }
12941 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12942 if (rc != 0) {
12943 pr_err("error %d\n", rc);
12944 goto rw_error;
12945 }
12946 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12947 if (rc != 0) {
12948 pr_err("error %d\n", rc);
12949 goto rw_error;
12950 }
12951 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);
12952 if (rc != 0) {
12953 pr_err("error %d\n", rc);
12954 goto rw_error;
12955 }
12956 ext_attr->phase_correction_bypass = false;
12957 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12958 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12959 ext_attr->enable_cvbs_output = true;
12960 break;
12961 default:
12962 return -EIO;
12963 }
12964
12965 /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
12966 if (!ext_attr->has_lna) {
12967 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x01, 0);
12968 if (rc != 0) {
12969 pr_err("error %d\n", rc);
12970 goto rw_error;
12971 }
12972 }
12973
12974 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_STANDARD__A, 0x002, 0);
12975 if (rc != 0) {
12976 pr_err("error %d\n", rc);
12977 goto rw_error;
12978 }
12979 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV, 0);
12980 if (rc != 0) {
12981 pr_err("error %d\n", rc);
12982 goto rw_error;
12983 }
12984 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV, 0);
12985 if (rc != 0) {
12986 pr_err("error %d\n", rc);
12987 goto rw_error;
12988 }
12989 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV, 0);
12990 if (rc != 0) {
12991 pr_err("error %d\n", rc);
12992 goto rw_error;
12993 }
12994 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12995 if (rc != 0) {
12996 pr_err("error %d\n", rc);
12997 goto rw_error;
12998 }
12999 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, 10248, 0);
13000 if (rc != 0) {
13001 pr_err("error %d\n", rc);
13002 goto rw_error;
13003 }
13004
13005 ext_attr->iqm_rc_rate_ofs = 0x00200000L;
13006 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
13007 if (rc != 0) {
13008 pr_err("error %d\n", rc);
13009 goto rw_error;
13010 }
13011 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF, 0);
13012 if (rc != 0) {
13013 pr_err("error %d\n", rc);
13014 goto rw_error;
13015 }
13016 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV, 0);
13017 if (rc != 0) {
13018 pr_err("error %d\n", rc);
13019 goto rw_error;
13020 }
13021
13022 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);
13023 if (rc != 0) {
13024 pr_err("error %d\n", rc);
13025 goto rw_error;
13026 }
13027
13028 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M, 0);
13029 if (rc != 0) {
13030 pr_err("error %d\n", rc);
13031 goto rw_error;
13032 }
13033 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M, 0);
13034 if (rc != 0) {
13035 pr_err("error %d\n", rc);
13036 goto rw_error;
13037 }
13038 /* default: SIF in standby */
13039 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN, 0);
13040 if (rc != 0) {
13041 pr_err("error %d\n", rc);
13042 goto rw_error;
13043 }
13044 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE, 0);
13045 if (rc != 0) {
13046 pr_err("error %d\n", rc);
13047 goto rw_error;
13048 }
13049
13050 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, 0x080, 0);
13051 if (rc != 0) {
13052 pr_err("error %d\n", rc);
13053 goto rw_error;
13054 }
13055 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_FAGC_TH_RED__A, 10, 0);
13056 if (rc != 0) {
13057 pr_err("error %d\n", rc);
13058 goto rw_error;
13059 }
13060 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AAGC_CNT__A, 7, 0);
13061 if (rc != 0) {
13062 pr_err("error %d\n", rc);
13063 goto rw_error;
13064 }
13065 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225, 0);
13066 if (rc != 0) {
13067 pr_err("error %d\n", rc);
13068 goto rw_error;
13069 }
13070 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547, 0);
13071 if (rc != 0) {
13072 pr_err("error %d\n", rc);
13073 goto rw_error;
13074 }
13075 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_KI_CHANGE_TH__A, 20, 0);
13076 if (rc != 0) {
13077 pr_err("error %d\n", rc);
13078 goto rw_error;
13079 }
13080 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_LOCK__A, 0, 0);
13081 if (rc != 0) {
13082 pr_err("error %d\n", rc);
13083 goto rw_error;
13084 }
13085
13086 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE, 0);
13087 if (rc != 0) {
13088 pr_err("error %d\n", rc);
13089 goto rw_error;
13090 }
13091 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BPC_KI_MIN__A, 531, 0);
13092 if (rc != 0) {
13093 pr_err("error %d\n", rc);
13094 goto rw_error;
13095 }
13096 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061, 0);
13097 if (rc != 0) {
13098 pr_err("error %d\n", rc);
13099 goto rw_error;
13100 }
13101 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BP_REF_MIN__A, 100, 0);
13102 if (rc != 0) {
13103 pr_err("error %d\n", rc);
13104 goto rw_error;
13105 }
13106 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BP_REF_MAX__A, 260, 0);
13107 if (rc != 0) {
13108 pr_err("error %d\n", rc);
13109 goto rw_error;
13110 }
13111 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_BP_LVL__A, 0, 0);
13112 if (rc != 0) {
13113 pr_err("error %d\n", rc);
13114 goto rw_error;
13115 }
13116 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MAX__A, 0, 0);
13117 if (rc != 0) {
13118 pr_err("error %d\n", rc);
13119 goto rw_error;
13120 }
13121 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_AMS_MIN__A, 2047, 0);
13122 if (rc != 0) {
13123 pr_err("error %d\n", rc);
13124 goto rw_error;
13125 }
13126 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
13127 if (rc != 0) {
13128 pr_err("error %d\n", rc);
13129 goto rw_error;
13130 }
13131
13132 /* Override reset values with current shadow settings */
13133 rc = atv_update_config(demod, true);
13134 if (rc != 0) {
13135 pr_err("error %d\n", rc);
13136 goto rw_error;
13137 }
13138
13139 /* Configure/restore AGC settings */
13140 rc = init_agc(demod);
13141 if (rc != 0) {
13142 pr_err("error %d\n", rc);
13143 goto rw_error;
13144 }
13145 rc = set_agc_if(demod, &(ext_attr->atv_if_agc_cfg), false);
13146 if (rc != 0) {
13147 pr_err("error %d\n", rc);
13148 goto rw_error;
13149 }
13150 rc = set_agc_rf(demod, &(ext_attr->atv_rf_agc_cfg), false);
13151 if (rc != 0) {
13152 pr_err("error %d\n", rc);
13153 goto rw_error;
13154 }
13155 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
13156 if (rc != 0) {
13157 pr_err("error %d\n", rc);
13158 goto rw_error;
13159 }
13160
13161 /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
13162 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
13163 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
13164 cmd_scu.parameter_len = 1;
13165 cmd_scu.result_len = 1;
13166 cmd_scu.parameter = &cmd_param;
13167 cmd_scu.result = &cmd_result;
13168 rc = scu_command(dev_addr, &cmd_scu);
13169 if (rc != 0) {
13170 pr_err("error %d\n", rc);
13171 goto rw_error;
13172 }
13173
13174 /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
13175 if (ext_attr->mfx == 0x03) {
13176 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0, 0);
13177 if (rc != 0) {
13178 pr_err("error %d\n", rc);
13179 goto rw_error;
13180 }
13181 } else {
13182 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1, 0);
13183 if (rc != 0) {
13184 pr_err("error %d\n", rc);
13185 goto rw_error;
13186 }
13187 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ATV_IIR_CRIT__A, 225, 0);
13188 if (rc != 0) {
13189 pr_err("error %d\n", rc);
13190 goto rw_error;
13191 }
13192 }
13193
13194 return 0;
13195rw_error:
13196 return -EIO;
13197}
13198
13199/* -------------------------------------------------------------------------- */
13200
13201/**
13202* \fn int set_atv_channel ()
13203* \brief Set ATV channel.
13204* \param demod: instance of demod.
13205* \return int.
13206*
13207* Not much needs to be done here, only start the SCU for NTSC/FM.
13208* Mirrored channels are not expected in the RF domain, so IQM FS setting
13209* doesn't need to be remembered.
13210* The channel->mirror parameter is therefor ignored.
13211*
13212*/
13213static int
13214set_atv_channel(struct drx_demod_instance *demod,
13215 s32 tuner_freq_offset,
13216 struct drx_channel *channel, enum drx_standard standard)
13217{
13218 struct drxjscu_cmd cmd_scu = { /* command */ 0,
13219 /* parameter_len */ 0,
13220 /* result_len */ 0,
13221 /* parameter */ NULL,
13222 /* result */ NULL
13223 };
13224 u16 cmd_result = 0;
13225 struct drxj_data *ext_attr = NULL;
13226 struct i2c_device_addr *dev_addr = NULL;
13227 int rc;
13228
13229 dev_addr = demod->my_i2c_dev_addr;
13230 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13231
13232 /*
13233 Program frequency shifter
13234 No need to account for mirroring on RF
13235 */
13236 if (channel->mirror == DRX_MIRROR_AUTO)
13237 ext_attr->mirror = DRX_MIRROR_NO;
13238 else
13239 ext_attr->mirror = channel->mirror;
13240
13241 rc = set_frequency(demod, channel, tuner_freq_offset);
13242 if (rc != 0) {
13243 pr_err("error %d\n", rc);
13244 goto rw_error;
13245 }
13246 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE, 0);
13247 if (rc != 0) {
13248 pr_err("error %d\n", rc);
13249 goto rw_error;
13250 }
13251
13252 /* Start ATV SCU */
13253 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
13254 SCU_RAM_COMMAND_CMD_DEMOD_START;
13255 cmd_scu.parameter_len = 0;
13256 cmd_scu.result_len = 1;
13257 cmd_scu.parameter = NULL;
13258 cmd_scu.result = &cmd_result;
13259 rc = scu_command(dev_addr, &cmd_scu);
13260 if (rc != 0) {
13261 pr_err("error %d\n", rc);
13262 goto rw_error;
13263 }
13264
13265/* if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
13266 {
13267 ext_attr->detectedRDS = (bool)false;
13268 }*/
13269
13270 return 0;
13271rw_error:
13272 return -EIO;
13273}
13274
13275/* -------------------------------------------------------------------------- */
13276
13277/**
13278* \fn int get_atv_channel ()
13279* \brief Set ATV channel.
13280* \param demod: instance of demod.
13281* \param channel: pointer to channel data.
13282* \param standard: NTSC or FM.
13283* \return int.
13284*
13285* Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
13286* Computes the frequency offset in te RF domain and adds it to
13287* channel->frequency. Determines the value for channel->bandwidth.
13288*
13289*/
13290static int
13291get_atv_channel(struct drx_demod_instance *demod,
13292 struct drx_channel *channel, enum drx_standard standard)
13293{
13294 s32 offset = 0;
13295 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
13296 int rc;
13297
13298 /* Bandwidth */
13299 channel->bandwidth = ((struct drxj_data *) demod->my_ext_attr)->curr_bandwidth;
13300
13301 switch (standard) {
13302 case DRX_STANDARD_NTSC:
13303 case DRX_STANDARD_PAL_SECAM_BG:
13304 case DRX_STANDARD_PAL_SECAM_DK:
13305 case DRX_STANDARD_PAL_SECAM_I:
13306 case DRX_STANDARD_PAL_SECAM_L:
13307 {
13308 u16 measured_offset = 0;
13309
13310 /* get measured frequency offset */
13311 rc = drxj_dap_read_reg16(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13312 if (rc != 0) {
13313 pr_err("error %d\n", rc);
13314 goto rw_error;
13315 }
13316 /* Signed 8 bit register => sign extension needed */
13317 if ((measured_offset & 0x0080) != 0)
13318 measured_offset |= 0xFF80;
13319 offset +=
13320 (s32) (((s16) measured_offset) * 10);
13321 break;
13322 }
13323 case DRX_STANDARD_PAL_SECAM_LP:
13324 {
13325 u16 measured_offset = 0;
13326
13327 /* get measured frequency offset */
13328 rc = drxj_dap_read_reg16(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13329 if (rc != 0) {
13330 pr_err("error %d\n", rc);
13331 goto rw_error;
13332 }
13333 /* Signed 8 bit register => sign extension needed */
13334 if ((measured_offset & 0x0080) != 0)
13335 measured_offset |= 0xFF80;
13336 offset -=
13337 (s32) (((s16) measured_offset) * 10);
13338 }
13339 break;
13340 case DRX_STANDARD_FM:
13341 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
13342 AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
13343 */
13344 /* No bandwidth know for FM */
13345 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
13346 break;
13347 default:
13348 return -EIO;
13349 }
13350
13351 channel->frequency -= offset;
13352
13353 return 0;
13354rw_error:
13355 return -EIO;
13356}
13357
13358/* -------------------------------------------------------------------------- */
13359/**
13360* \fn int get_atv_sig_strength()
13361* \brief Retrieve signal strength for ATV & FM.
13362* \param devmod Pointer to demodulator instance.
13363* \param sig_quality Pointer to signal strength data; range 0, .. , 100.
13364* \return int.
13365* \retval 0 sig_strength contains valid data.
13366* \retval -EIO Erroneous data, sig_strength equals 0.
13367*
13368* Taking into account:
13369* * digital gain
13370* * IF gain (not implemented yet, waiting for IF gain control by ucode)
13371* * RF gain
13372*
13373* All weights (digital, if, rf) must add up to 100.
13374*
13375* TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
13376* is not used ?
13377*/
13378static int
13379get_atv_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
13380{
13381 struct i2c_device_addr *dev_addr = NULL;
13382 struct drxj_data *ext_attr = NULL;
13383 int rc;
13384
13385 /* All weights must add up to 100 (%)
13386 TODO: change weights when IF ctrl is available */
13387 u32 digital_weight = 50; /* 0 .. 100 */
13388 u32 rf_weight = 50; /* 0 .. 100 */
13389 u32 if_weight = 0; /* 0 .. 100 */
13390
13391 u16 digital_curr_gain = 0;
13392 u32 digital_max_gain = 0;
13393 u32 digital_min_gain = 0;
13394 u16 rf_curr_gain = 0;
13395 u32 rf_max_gain = 0x800; /* taken from ucode */
13396 u32 rf_min_gain = 0x7fff;
13397 u16 if_curr_gain = 0;
13398 u32 if_max_gain = 0x800; /* taken from ucode */
13399 u32 if_min_gain = 0x7fff;
13400
13401 u32 digital_strength = 0; /* 0.. 100 */
13402 u32 rf_strength = 0; /* 0.. 100 */
13403 u32 if_strength = 0; /* 0.. 100 */
13404
13405 dev_addr = demod->my_i2c_dev_addr;
13406 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13407
13408 *sig_strength = 0;
13409
13410 switch (ext_attr->standard) {
13411 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13412 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13413 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13414 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13415 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
13416 case DRX_STANDARD_NTSC:
13417 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &digital_curr_gain, 0);
13418 if (rc != 0) {
13419 pr_err("error %d\n", rc);
13420 goto rw_error;
13421 }
13422 digital_max_gain = 22512; /* taken from ucode */
13423 digital_min_gain = 2400; /* taken from ucode */
13424 break;
13425 case DRX_STANDARD_FM:
13426 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &digital_curr_gain, 0);
13427 if (rc != 0) {
13428 pr_err("error %d\n", rc);
13429 goto rw_error;
13430 }
13431 digital_max_gain = 0x4ff; /* taken from ucode */
13432 digital_min_gain = 0; /* taken from ucode */
13433 break;
13434 default:
13435 return -EIO;
13436 break;
13437 }
13438 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_curr_gain, 0);
13439 if (rc != 0) {
13440 pr_err("error %d\n", rc);
13441 goto rw_error;
13442 }
13443 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_curr_gain, 0);
13444 if (rc != 0) {
13445 pr_err("error %d\n", rc);
13446 goto rw_error;
13447 }
13448
13449 /* clipping */
13450 if (digital_curr_gain >= digital_max_gain)
13451 digital_curr_gain = (u16)digital_max_gain;
13452 if (digital_curr_gain <= digital_min_gain)
13453 digital_curr_gain = (u16)digital_min_gain;
13454 if (if_curr_gain <= if_max_gain)
13455 if_curr_gain = (u16)if_max_gain;
13456 if (if_curr_gain >= if_min_gain)
13457 if_curr_gain = (u16)if_min_gain;
13458 if (rf_curr_gain <= rf_max_gain)
13459 rf_curr_gain = (u16)rf_max_gain;
13460 if (rf_curr_gain >= rf_min_gain)
13461 rf_curr_gain = (u16)rf_min_gain;
13462
13463 /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
13464 of clipping at ADC */
13465
13466 /* Compute signal strength (in %) per "gain domain" */
13467
13468 /* Digital gain */
13469 /* TODO: ADC clipping not handled */
13470 digital_strength = (100 * (digital_max_gain - (u32) digital_curr_gain)) /
13471 (digital_max_gain - digital_min_gain);
13472
13473 /* TODO: IF gain not implemented yet in microcode, check after impl. */
13474 if_strength = (100 * ((u32) if_curr_gain - if_max_gain)) /
13475 (if_min_gain - if_max_gain);
13476
13477 /* Rf gain */
13478 /* TODO: ADC clipping not handled */
13479 rf_strength = (100 * ((u32) rf_curr_gain - rf_max_gain)) /
13480 (rf_min_gain - rf_max_gain);
13481
13482 /* Compute a weighted signal strength (in %) */
13483 *sig_strength = (u16) (digital_weight * digital_strength +
13484 rf_weight * rf_strength + if_weight * if_strength);
13485 *sig_strength /= 100;
13486
13487 return 0;
13488rw_error:
13489 return -EIO;
13490}
13491
13492/* -------------------------------------------------------------------------- */
13493/**
13494* \fn int atv_sig_quality()
13495* \brief Retrieve signal quality indication for ATV.
13496* \param devmod Pointer to demodulator instance.
13497* \param sig_quality Pointer to signal quality structure.
13498* \return int.
13499* \retval 0 sig_quality contains valid data.
13500* \retval -EIO Erroneous data, sig_quality indicator equals 0.
13501*
13502*
13503*/
13504static int
13505atv_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
13506{
13507 struct i2c_device_addr *dev_addr = NULL;
13508 u16 quality_indicator = 0;
13509 int rc;
13510
13511 dev_addr = demod->my_i2c_dev_addr;
13512
13513 /* defined values for fields not used */
13514 sig_quality->MER = 0;
13515 sig_quality->pre_viterbi_ber = 0;
13516 sig_quality->post_viterbi_ber = 0;
13517 sig_quality->scale_factor_ber = 1;
13518 sig_quality->packet_error = 0;
13519 sig_quality->post_reed_solomon_ber = 0;
13520
13521 /*
13522 Mapping:
13523 0x000..0x080: strong signal => 80% .. 100%
13524 0x080..0x700: weak signal => 30% .. 80%
13525 0x700..0x7ff: no signal => 0% .. 30%
13526 */
13527
13528 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_CR_LOCK__A, &quality_indicator, 0);
13529 if (rc != 0) {
13530 pr_err("error %d\n", rc);
13531 goto rw_error;
13532 }
13533 quality_indicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
13534 if (quality_indicator <= 0x80) {
13535 sig_quality->indicator =
13536 80 + ((20 * (0x80 - quality_indicator)) / 0x80);
13537 } else if (quality_indicator <= 0x700)
13538 sig_quality->indicator = 30 + ((50 * (0x700 - quality_indicator)) / (0x700 - 0x81));
13539 else
13540 sig_quality->indicator = (30 * (0x7FF - quality_indicator)) / (0x7FF - 0x701);
13541
13542 return 0;
13543rw_error:
13544 return -EIO;
13545}
13546
13547/*============================================================================*/
13548/*== END ATV DATAPATH FUNCTIONS ==*/
13549/*============================================================================*/
13550
13551/*===========================================================================*/
13552/*===========================================================================*/
13553/*== AUDIO DATAPATH FUNCTIONS ==*/
13554/*===========================================================================*/
13555/*===========================================================================*/
13556
13557/*
13558* \brief Power up AUD.
13559* \param demod instance of demodulator
13560* \return int.
13561*
13562*/
13563static int power_up_aud(struct drx_demod_instance *demod, bool set_standard)
13564{
13565 enum drx_aud_standard aud_standard = DRX_AUD_STANDARD_AUTO;
13566 struct i2c_device_addr *dev_addr = NULL;
13567 int rc;
13568
13569 dev_addr = demod->my_i2c_dev_addr;
13570
13571 rc = drxj_dap_write_reg16(dev_addr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE, 0);
13572 if (rc != 0) {
13573 pr_err("error %d\n", rc);
13574 goto rw_error;
13575 }
13576 /* setup TR interface: R/W mode, fifosize=8 */
13577 rc = drxj_dap_write_reg16(dev_addr, AUD_TOP_TR_MDE__A, 8, 0);
13578 if (rc != 0) {
13579 pr_err("error %d\n", rc);
13580 goto rw_error;
13581 }
13582 rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE, 0);
13583 if (rc != 0) {
13584 pr_err("error %d\n", rc);
13585 goto rw_error;
13586 }
13587
13588 if (set_standard) {
13589 rc = aud_ctrl_set_standard(demod, &aud_standard);
13590 if (rc != 0) {
13591 pr_err("error %d\n", rc);
13592 goto rw_error;
13593 }
13594 }
13595
13596 return 0;
13597rw_error:
13598 return -EIO;
13599}
13600#endif
13601
13602/*============================================================================*/ 9721/*============================================================================*/
13603 9722
13604/** 9723/**
@@ -13629,2960 +9748,6 @@ rw_error:
13629 return -EIO; 9748 return -EIO;
13630} 9749}
13631 9750
13632#if 0
13633/*============================================================================*/
13634/**
13635* \brief Get Modus data from audio RAM
13636* \param demod instance of demodulator
13637* \param pointer to modus
13638* \return int.
13639*
13640*/
13641static int aud_get_modus(struct drx_demod_instance *demod, u16 *modus)
13642{
13643 struct i2c_device_addr *dev_addr = NULL;
13644 struct drxj_data *ext_attr = NULL;
13645 int rc;
13646
13647 u16 r_modus = 0;
13648 u16 r_modus_hi = 0;
13649 u16 r_modus_lo = 0;
13650
13651 if (modus == NULL)
13652 return -EINVAL;
13653
13654 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13655 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13656
13657 /* power up */
13658 if (ext_attr->aud_data.audio_is_active == false) {
13659 rc = power_up_aud(demod, true);
13660 if (rc != 0) {
13661 pr_err("error %d\n", rc);
13662 goto rw_error;
13663 }
13664 ext_attr->aud_data.audio_is_active = true;
13665 }
13666
13667 /* Modus register is combined in to RAM location */
13668 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_MODUS_HI__A, &r_modus_hi, 0);
13669 if (rc != 0) {
13670 pr_err("error %d\n", rc);
13671 goto rw_error;
13672 }
13673 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_MODUS_LO__A, &r_modus_lo, 0);
13674 if (rc != 0) {
13675 pr_err("error %d\n", rc);
13676 goto rw_error;
13677 }
13678
13679 r_modus = ((r_modus_hi << 12) & AUD_DEM_RAM_MODUS_HI__M)
13680 | (((r_modus_lo & AUD_DEM_RAM_MODUS_LO__M)));
13681
13682 *modus = r_modus;
13683
13684 return 0;
13685rw_error:
13686 return -EIO;
13687
13688}
13689
13690/*============================================================================*/
13691/**
13692* \brief Get audio RDS dat
13693* \param demod instance of demodulator
13694* \param pointer to struct drx_cfg_aud_rds * \return int.
13695*
13696*/
13697static int
13698aud_ctrl_get_cfg_rds(struct drx_demod_instance *demod, struct drx_cfg_aud_rds *status)
13699{
13700 struct i2c_device_addr *addr = NULL;
13701 struct drxj_data *ext_attr = NULL;
13702 int rc;
13703
13704 u16 r_rds_array_cnt_init = 0;
13705 u16 r_rds_array_cnt_check = 0;
13706 u16 r_rds_data = 0;
13707 u16 rds_data_cnt = 0;
13708
13709 addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13710 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13711
13712 if (status == NULL)
13713 return -EINVAL;
13714
13715 /* power up */
13716 if (ext_attr->aud_data.audio_is_active == false) {
13717 rc = power_up_aud(demod, true);
13718 if (rc != 0) {
13719 pr_err("error %d\n", rc);
13720 goto rw_error;
13721 }
13722 ext_attr->aud_data.audio_is_active = true;
13723 }
13724
13725 status->valid = false;
13726
13727 rc = drxj_dap_read_reg16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_init, 0);
13728 if (rc != 0) {
13729 pr_err("error %d\n", rc);
13730 goto rw_error;
13731 }
13732
13733 if (r_rds_array_cnt_init ==
13734 AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
13735 /* invalid data */
13736 return 0;
13737 }
13738
13739 if (ext_attr->aud_data.rds_data_counter == r_rds_array_cnt_init) {
13740 /* no new data */
13741 return 0;
13742 }
13743
13744 /* RDS is detected, as long as FM radio is selected assume
13745 RDS will be available */
13746 ext_attr->aud_data.rds_data_present = true;
13747
13748 /* new data */
13749 /* read the data */
13750 for (rds_data_cnt = 0; rds_data_cnt < AUD_RDS_ARRAY_SIZE; rds_data_cnt++) {
13751 rc = drxj_dap_read_reg16(addr, AUD_DEM_RD_RDS_DATA__A, &r_rds_data, 0);
13752 if (rc != 0) {
13753 pr_err("error %d\n", rc);
13754 goto rw_error;
13755 }
13756 status->data[rds_data_cnt] = r_rds_data;
13757 }
13758
13759 rc = drxj_dap_read_reg16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_check, 0);
13760 if (rc != 0) {
13761 pr_err("error %d\n", rc);
13762 goto rw_error;
13763 }
13764
13765 if (r_rds_array_cnt_check == r_rds_array_cnt_init) {
13766 status->valid = true;
13767 ext_attr->aud_data.rds_data_counter = r_rds_array_cnt_check;
13768 }
13769
13770 return 0;
13771rw_error:
13772 return -EIO;
13773}
13774
13775/*============================================================================*/
13776/**
13777* \brief Get the current audio carrier detection status
13778* \param demod instance of demodulator
13779* \param pointer to aud_ctrl_get_status
13780* \return int.
13781*
13782*/
13783static int
13784aud_ctrl_get_carrier_detect_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13785{
13786 struct drxj_data *ext_attr = NULL;
13787 struct i2c_device_addr *dev_addr = NULL;
13788 int rc;
13789 u16 r_data = 0;
13790
13791 if (status == NULL)
13792 return -EINVAL;
13793
13794 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13795 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13796
13797 /* power up */
13798 if (ext_attr->aud_data.audio_is_active == false) {
13799 rc = power_up_aud(demod, true);
13800 if (rc != 0) {
13801 pr_err("error %d\n", rc);
13802 goto rw_error;
13803 }
13804 ext_attr->aud_data.audio_is_active = true;
13805 }
13806
13807 /* initialize the variables */
13808 status->carrier_a = false;
13809 status->carrier_b = false;
13810 status->nicam_status = DRX_AUD_NICAM_NOT_DETECTED;
13811 status->sap = false;
13812 status->stereo = false;
13813
13814 /* read stereo sound mode indication */
13815 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RD_STATUS__A, &r_data, 0);
13816 if (rc != 0) {
13817 pr_err("error %d\n", rc);
13818 goto rw_error;
13819 }
13820
13821 /* carrier a detected */
13822 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_A__M) == AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED)
13823 status->carrier_a = true;
13824
13825 /* carrier b detected */
13826 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_B__M) == AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED)
13827 status->carrier_b = true;
13828 /* nicam detected */
13829 if ((r_data & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
13830 AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
13831 if ((r_data & AUD_DEM_RD_STATUS_BAD_NICAM__M) == AUD_DEM_RD_STATUS_BAD_NICAM_OK)
13832 status->nicam_status = DRX_AUD_NICAM_DETECTED;
13833 else
13834 status->nicam_status = DRX_AUD_NICAM_BAD;
13835 }
13836
13837 /* audio mode bilingual or SAP detected */
13838 if ((r_data & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) == AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP)
13839 status->sap = true;
13840
13841 /* stereo detected */
13842 if ((r_data & AUD_DEM_RD_STATUS_STAT_STEREO__M) == AUD_DEM_RD_STATUS_STAT_STEREO_STEREO)
13843 status->stereo = true;
13844
13845 return 0;
13846rw_error:
13847 return -EIO;
13848}
13849
13850/*============================================================================*/
13851/**
13852* \brief Get the current audio status parameters
13853* \param demod instance of demodulator
13854* \param pointer to aud_ctrl_get_status
13855* \return int.
13856*
13857*/
13858static int
13859aud_ctrl_get_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13860{
13861 struct drxj_data *ext_attr = NULL;
13862 struct i2c_device_addr *dev_addr = NULL;
13863 struct drx_cfg_aud_rds rds = { false, {0} };
13864 int rc;
13865 u16 r_data = 0;
13866
13867 if (status == NULL)
13868 return -EINVAL;
13869
13870 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13871 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13872
13873 /* carrier detection */
13874 rc = aud_ctrl_get_carrier_detect_status(demod, status);
13875 if (rc != 0) {
13876 pr_err("error %d\n", rc);
13877 goto rw_error;
13878 }
13879
13880 /* rds data */
13881 status->rds = false;
13882 rc = aud_ctrl_get_cfg_rds(demod, &rds);
13883 if (rc != 0) {
13884 pr_err("error %d\n", rc);
13885 goto rw_error;
13886 }
13887 status->rds = ext_attr->aud_data.rds_data_present;
13888
13889 /* fm_ident */
13890 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_FM_IDENT_VALUE__A, &r_data, 0);
13891 if (rc != 0) {
13892 pr_err("error %d\n", rc);
13893 goto rw_error;
13894 }
13895 r_data >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
13896 status->fm_ident = (s8) r_data;
13897
13898 return 0;
13899rw_error:
13900 return -EIO;
13901}
13902
13903/*============================================================================*/
13904/**
13905* \brief Get the current volume settings
13906* \param demod instance of demodulator
13907* \param pointer to struct drx_cfg_aud_volume * \return int.
13908*
13909*/
13910static int
13911aud_ctrl_get_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13912{
13913 struct i2c_device_addr *dev_addr = NULL;
13914 struct drxj_data *ext_attr = NULL;
13915 int rc;
13916
13917 u16 r_volume = 0;
13918 u16 r_avc = 0;
13919 u16 r_strength_left = 0;
13920 u16 r_strength_right = 0;
13921
13922 if (volume == NULL)
13923 return -EINVAL;
13924
13925 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13926 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13927
13928 /* power up */
13929 if (ext_attr->aud_data.audio_is_active == false) {
13930 rc = power_up_aud(demod, true);
13931 if (rc != 0) {
13932 pr_err("error %d\n", rc);
13933 goto rw_error;
13934 }
13935 ext_attr->aud_data.audio_is_active = true;
13936 }
13937
13938 /* volume */
13939 volume->mute = ext_attr->aud_data.volume.mute;
13940 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, &r_volume, 0);
13941 if (rc != 0) {
13942 pr_err("error %d\n", rc);
13943 goto rw_error;
13944 }
13945 if (r_volume == 0) {
13946 volume->mute = true;
13947 volume->volume = ext_attr->aud_data.volume.volume;
13948 } else {
13949 volume->mute = false;
13950 volume->volume = ((r_volume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
13951 AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
13952 AUD_VOLUME_ZERO_DB;
13953 if (volume->volume < AUD_VOLUME_DB_MIN)
13954 volume->volume = AUD_VOLUME_DB_MIN;
13955 if (volume->volume > AUD_VOLUME_DB_MAX)
13956 volume->volume = AUD_VOLUME_DB_MAX;
13957 }
13958
13959 /* automatic volume control */
13960 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AVC__A, &r_avc, 0);
13961 if (rc != 0) {
13962 pr_err("error %d\n", rc);
13963 goto rw_error;
13964 }
13965
13966 if ((r_avc & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF) {
13967 volume->avc_mode = DRX_AUD_AVC_OFF;
13968 } else {
13969 switch (r_avc & AUD_DSP_WR_AVC_AVC_DECAY__M) {
13970 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
13971 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_20MS;
13972 break;
13973 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
13974 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_8S;
13975 break;
13976 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
13977 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_4S;
13978 break;
13979 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
13980 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_2S;
13981 break;
13982 default:
13983 return -EIO;
13984 break;
13985 }
13986 }
13987
13988 /* max attenuation */
13989 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
13990 case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
13991 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_12DB;
13992 break;
13993 case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
13994 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_18DB;
13995 break;
13996 case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
13997 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_24DB;
13998 break;
13999 default:
14000 return -EIO;
14001 break;
14002 }
14003
14004 /* max gain */
14005 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
14006 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
14007 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_0DB;
14008 break;
14009 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
14010 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_6DB;
14011 break;
14012 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
14013 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_12DB;
14014 break;
14015 default:
14016 return -EIO;
14017 break;
14018 }
14019
14020 /* reference level */
14021 volume->avc_ref_level = (u16) ((r_avc & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
14022 AUD_DSP_WR_AVC_AVC_REF_LEV__B);
14023
14024 /* read qpeak registers and calculate strength of left and right carrier */
14025 /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
14026 /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
14027 /* left carrier */
14028
14029 /* QP vaues */
14030 /* left carrier */
14031 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_QPEAK_L__A, &r_strength_left, 0);
14032 if (rc != 0) {
14033 pr_err("error %d\n", rc);
14034 goto rw_error;
14035 }
14036 volume->strength_left = (((s16) log1_times100(r_strength_left)) -
14037 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
14038
14039 /* right carrier */
14040 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_QPEAK_R__A, &r_strength_right, 0);
14041 if (rc != 0) {
14042 pr_err("error %d\n", rc);
14043 goto rw_error;
14044 }
14045 volume->strength_right = (((s16) log1_times100(r_strength_right)) -
14046 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
14047
14048 return 0;
14049rw_error:
14050 return -EIO;
14051}
14052
14053/*============================================================================*/
14054/**
14055* \brief Set the current volume settings
14056* \param demod instance of demodulator
14057* \param pointer to struct drx_cfg_aud_volume * \return int.
14058*
14059*/
14060static int
14061aud_ctrl_set_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
14062{
14063 struct i2c_device_addr *dev_addr = NULL;
14064 struct drxj_data *ext_attr = NULL;
14065 int rc;
14066
14067 u16 w_volume = 0;
14068 u16 w_avc = 0;
14069
14070 if (volume == NULL)
14071 return -EINVAL;
14072
14073 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14074 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14075
14076 /* power up */
14077 if (ext_attr->aud_data.audio_is_active == false) {
14078 rc = power_up_aud(demod, true);
14079 if (rc != 0) {
14080 pr_err("error %d\n", rc);
14081 goto rw_error;
14082 }
14083 ext_attr->aud_data.audio_is_active = true;
14084 }
14085
14086 /* volume */
14087 /* volume range from -60 to 12 (expressed in dB) */
14088 if ((volume->volume < AUD_VOLUME_DB_MIN) ||
14089 (volume->volume > AUD_VOLUME_DB_MAX))
14090 return -EINVAL;
14091
14092 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, &w_volume, 0);
14093 if (rc != 0) {
14094 pr_err("error %d\n", rc);
14095 goto rw_error;
14096 }
14097
14098 /* clear the volume mask */
14099 w_volume &= (u16) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
14100 if (volume->mute == true)
14101 w_volume |= (u16)(0);
14102 else
14103 w_volume |= (u16)((volume->volume + AUD_VOLUME_ZERO_DB) << AUD_DSP_WR_VOLUME_VOL_MAIN__B);
14104
14105 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
14106 if (rc != 0) {
14107 pr_err("error %d\n", rc);
14108 goto rw_error;
14109 }
14110
14111 /* automatic volume control */
14112 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AVC__A, &w_avc, 0);
14113 if (rc != 0) {
14114 pr_err("error %d\n", rc);
14115 goto rw_error;
14116 }
14117
14118 /* clear masks that require writing */
14119 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_ON__M;
14120 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
14121
14122 if (volume->avc_mode == DRX_AUD_AVC_OFF) {
14123 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
14124 } else {
14125
14126 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_ON);
14127
14128 /* avc decay */
14129 switch (volume->avc_mode) {
14130 case DRX_AUD_AVC_DECAYTIME_20MS:
14131 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
14132 break;
14133 case DRX_AUD_AVC_DECAYTIME_8S:
14134 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
14135 break;
14136 case DRX_AUD_AVC_DECAYTIME_4S:
14137 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
14138 break;
14139 case DRX_AUD_AVC_DECAYTIME_2S:
14140 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
14141 break;
14142 default:
14143 return -EINVAL;
14144 }
14145 }
14146
14147 /* max attenuation */
14148 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
14149 switch (volume->avc_max_atten) {
14150 case DRX_AUD_AVC_MAX_ATTEN_12DB:
14151 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
14152 break;
14153 case DRX_AUD_AVC_MAX_ATTEN_18DB:
14154 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
14155 break;
14156 case DRX_AUD_AVC_MAX_ATTEN_24DB:
14157 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
14158 break;
14159 default:
14160 return -EINVAL;
14161 }
14162
14163 /* max gain */
14164 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
14165 switch (volume->avc_max_gain) {
14166 case DRX_AUD_AVC_MAX_GAIN_0DB:
14167 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
14168 break;
14169 case DRX_AUD_AVC_MAX_GAIN_6DB:
14170 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
14171 break;
14172 case DRX_AUD_AVC_MAX_GAIN_12DB:
14173 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
14174 break;
14175 default:
14176 return -EINVAL;
14177 }
14178
14179 /* avc reference level */
14180 if (volume->avc_ref_level > AUD_MAX_AVC_REF_LEVEL)
14181 return -EINVAL;
14182
14183 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
14184 w_avc |= (u16) (volume->avc_ref_level << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
14185
14186 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_AVC__A, w_avc, 0);
14187 if (rc != 0) {
14188 pr_err("error %d\n", rc);
14189 goto rw_error;
14190 }
14191
14192 /* all done, store config in data structure */
14193 ext_attr->aud_data.volume = *volume;
14194
14195 return 0;
14196rw_error:
14197 return -EIO;
14198}
14199
14200/*============================================================================*/
14201/**
14202* \brief Get the I2S settings
14203* \param demod instance of demodulator
14204* \param pointer to struct drx_cfg_i2s_output * \return int.
14205*
14206*/
14207static int
14208aud_ctrl_get_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14209{
14210 struct i2c_device_addr *dev_addr = NULL;
14211 struct drxj_data *ext_attr = NULL;
14212 int rc;
14213 u16 w_i2s_config = 0;
14214 u16 r_i2s_freq = 0;
14215
14216 if (output == NULL)
14217 return -EINVAL;
14218
14219 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14220 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14221
14222 /* power up */
14223 if (ext_attr->aud_data.audio_is_active == false) {
14224 rc = power_up_aud(demod, true);
14225 if (rc != 0) {
14226 pr_err("error %d\n", rc);
14227 goto rw_error;
14228 }
14229 ext_attr->aud_data.audio_is_active = true;
14230 }
14231
14232 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14233 if (rc != 0) {
14234 pr_err("error %d\n", rc);
14235 goto rw_error;
14236 }
14237 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, &r_i2s_freq, 0);
14238 if (rc != 0) {
14239 pr_err("error %d\n", rc);
14240 goto rw_error;
14241 }
14242
14243 /* I2S mode */
14244 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
14245 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
14246 output->mode = DRX_I2S_MODE_MASTER;
14247 break;
14248 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
14249 output->mode = DRX_I2S_MODE_SLAVE;
14250 break;
14251 default:
14252 return -EIO;
14253 }
14254
14255 /* I2S format */
14256 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
14257 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
14258 output->format = DRX_I2S_FORMAT_WS_ADVANCED;
14259 break;
14260 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
14261 output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
14262 break;
14263 default:
14264 return -EIO;
14265 }
14266
14267 /* I2S word length */
14268 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
14269 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
14270 output->word_length = DRX_I2S_WORDLENGTH_16;
14271 break;
14272 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
14273 output->word_length = DRX_I2S_WORDLENGTH_32;
14274 break;
14275 default:
14276 return -EIO;
14277 }
14278
14279 /* I2S polarity */
14280 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
14281 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
14282 output->polarity = DRX_I2S_POLARITY_LEFT;
14283 break;
14284 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
14285 output->polarity = DRX_I2S_POLARITY_RIGHT;
14286 break;
14287 default:
14288 return -EIO;
14289 }
14290
14291 /* I2S output enabled */
14292 if ((w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M) == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE)
14293 output->output_enable = true;
14294 else
14295 output->output_enable = false;
14296
14297 if (r_i2s_freq > 0) {
14298 output->frequency = 6144UL * 48000 / r_i2s_freq;
14299 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14300 output->frequency *= 2;
14301 } else {
14302 output->frequency = AUD_I2S_FREQUENCY_MAX;
14303 }
14304
14305 return 0;
14306rw_error:
14307 return -EIO;
14308}
14309
14310/*============================================================================*/
14311/**
14312* \brief Set the I2S settings
14313* \param demod instance of demodulator
14314* \param pointer to struct drx_cfg_i2s_output * \return int.
14315*
14316*/
14317static int
14318aud_ctrl_set_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14319{
14320 struct i2c_device_addr *dev_addr = NULL;
14321 struct drxj_data *ext_attr = NULL;
14322 int rc;
14323 u16 w_i2s_config = 0;
14324 u16 w_i2s_pads_data_da = 0;
14325 u16 w_i2s_pads_data_cl = 0;
14326 u16 w_i2s_pads_data_ws = 0;
14327 u32 w_i2s_freq = 0;
14328
14329 if (output == NULL)
14330 return -EINVAL;
14331
14332 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14333 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14334
14335 /* power up */
14336 if (ext_attr->aud_data.audio_is_active == false) {
14337 rc = power_up_aud(demod, true);
14338 if (rc != 0) {
14339 pr_err("error %d\n", rc);
14340 goto rw_error;
14341 }
14342 ext_attr->aud_data.audio_is_active = true;
14343 }
14344
14345 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14346 if (rc != 0) {
14347 pr_err("error %d\n", rc);
14348 goto rw_error;
14349 }
14350
14351 /* I2S mode */
14352 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
14353
14354 switch (output->mode) {
14355 case DRX_I2S_MODE_MASTER:
14356 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
14357 break;
14358 case DRX_I2S_MODE_SLAVE:
14359 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
14360 break;
14361 default:
14362 return -EINVAL;
14363 }
14364
14365 /* I2S format */
14366 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
14367
14368 switch (output->format) {
14369 case DRX_I2S_FORMAT_WS_ADVANCED:
14370 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
14371 break;
14372 case DRX_I2S_FORMAT_WS_WITH_DATA:
14373 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
14374 break;
14375 default:
14376 return -EINVAL;
14377 }
14378
14379 /* I2S word length */
14380 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
14381
14382 switch (output->word_length) {
14383 case DRX_I2S_WORDLENGTH_16:
14384 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
14385 break;
14386 case DRX_I2S_WORDLENGTH_32:
14387 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
14388 break;
14389 default:
14390 return -EINVAL;
14391 }
14392
14393 /* I2S polarity */
14394 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
14395 switch (output->polarity) {
14396 case DRX_I2S_POLARITY_LEFT:
14397 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
14398 break;
14399 case DRX_I2S_POLARITY_RIGHT:
14400 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
14401 break;
14402 default:
14403 return -EINVAL;
14404 }
14405
14406 /* I2S output enabled */
14407 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
14408 if (output->output_enable == true)
14409 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
14410 else
14411 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
14412
14413 /*
14414 I2S frequency
14415
14416 w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
14417
14418 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
14419 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
14420 */
14421 if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
14422 output->frequency < AUD_I2S_FREQUENCY_MIN) {
14423 return -EINVAL;
14424 }
14425
14426 w_i2s_freq = (6144UL * 48000UL) + (output->frequency >> 1);
14427 w_i2s_freq /= output->frequency;
14428
14429 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14430 w_i2s_freq *= 2;
14431
14432 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_I2S_CONFIG2__A, w_i2s_config, 0);
14433 if (rc != 0) {
14434 pr_err("error %d\n", rc);
14435 goto rw_error;
14436 }
14437 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, (u16)w_i2s_freq, 0);
14438 if (rc != 0) {
14439 pr_err("error %d\n", rc);
14440 goto rw_error;
14441 }
14442
14443 /* configure I2S output pads for master or slave mode */
14444 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
14445 if (rc != 0) {
14446 pr_err("error %d\n", rc);
14447 goto rw_error;
14448 }
14449
14450 if (output->mode == DRX_I2S_MODE_MASTER) {
14451 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
14452 SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
14453 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
14454 SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
14455 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
14456 SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
14457 } else {
14458 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
14459 SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
14460 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
14461 SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
14462 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
14463 SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
14464 }
14465
14466 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_DA_CFG__A, w_i2s_pads_data_da, 0);
14467 if (rc != 0) {
14468 pr_err("error %d\n", rc);
14469 goto rw_error;
14470 }
14471 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_CL_CFG__A, w_i2s_pads_data_cl, 0);
14472 if (rc != 0) {
14473 pr_err("error %d\n", rc);
14474 goto rw_error;
14475 }
14476 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_I2S_WS_CFG__A, w_i2s_pads_data_ws, 0);
14477 if (rc != 0) {
14478 pr_err("error %d\n", rc);
14479 goto rw_error;
14480 }
14481
14482 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
14483 if (rc != 0) {
14484 pr_err("error %d\n", rc);
14485 goto rw_error;
14486 }
14487
14488 /* all done, store config in data structure */
14489 ext_attr->aud_data.i2sdata = *output;
14490
14491 return 0;
14492rw_error:
14493 return -EIO;
14494}
14495
14496/*============================================================================*/
14497/**
14498* \brief Get the Automatic Standard Select (ASS)
14499* and Automatic Sound Change (ASC)
14500* \param demod instance of demodulator
14501* \param pointer to pDRXAudAutoSound_t
14502* \return int.
14503*
14504*/
14505static int
14506aud_ctrl_get_cfg_auto_sound(struct drx_demod_instance *demod,
14507 enum drx_cfg_aud_auto_sound *auto_sound)
14508{
14509 struct drxj_data *ext_attr = NULL;
14510 int rc;
14511 u16 r_modus = 0;
14512
14513 if (auto_sound == NULL)
14514 return -EINVAL;
14515
14516 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14517
14518 /* power up */
14519 if (ext_attr->aud_data.audio_is_active == false) {
14520 rc = power_up_aud(demod, true);
14521 if (rc != 0) {
14522 pr_err("error %d\n", rc);
14523 goto rw_error;
14524 }
14525 ext_attr->aud_data.audio_is_active = true;
14526 }
14527
14528 rc = aud_get_modus(demod, &r_modus);
14529 if (rc != 0) {
14530 pr_err("error %d\n", rc);
14531 goto rw_error;
14532 }
14533
14534 switch (r_modus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
14535 AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
14536 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14537 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14538 *auto_sound =
14539 DRX_AUD_AUTO_SOUND_OFF;
14540 break;
14541 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14542 *auto_sound =
14543 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
14544 break;
14545 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14546 *auto_sound =
14547 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
14548 break;
14549 default:
14550 return -EIO;
14551 }
14552
14553 return 0;
14554rw_error:
14555 return -EIO;
14556}
14557
14558/*============================================================================*/
14559/**
14560* \brief Set the Automatic Standard Select (ASS)
14561* and Automatic Sound Change (ASC)
14562* \param demod instance of demodulator
14563* \param pointer to pDRXAudAutoSound_t
14564* \return int.
14565*
14566*/
14567static int
14568aud_ctr_setl_cfg_auto_sound(struct drx_demod_instance *demod,
14569 enum drx_cfg_aud_auto_sound *auto_sound)
14570{
14571 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14572 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14573 int rc;
14574 u16 r_modus = 0;
14575 u16 w_modus = 0;
14576
14577 if (auto_sound == NULL)
14578 return -EINVAL;
14579
14580 dev_addr = demod->my_i2c_dev_addr;
14581 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14582
14583 /* power up */
14584 if (ext_attr->aud_data.audio_is_active == false) {
14585 rc = power_up_aud(demod, true);
14586 if (rc != 0) {
14587 pr_err("error %d\n", rc);
14588 goto rw_error;
14589 }
14590 ext_attr->aud_data.audio_is_active = true;
14591 }
14592
14593 rc = aud_get_modus(demod, &r_modus);
14594 if (rc != 0) {
14595 pr_err("error %d\n", rc);
14596 goto rw_error;
14597 }
14598
14599 w_modus = r_modus;
14600 /* clear ASS & ASC bits */
14601 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_ASS__M;
14602 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
14603
14604 switch (*auto_sound) {
14605 case DRX_AUD_AUTO_SOUND_OFF:
14606 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
14607 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14608 break;
14609 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
14610 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14611 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
14612 break;
14613 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
14614 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14615 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14616 break;
14617 default:
14618 return -EINVAL;
14619 }
14620
14621 if (w_modus != r_modus) {
14622 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14623 if (rc != 0) {
14624 pr_err("error %d\n", rc);
14625 goto rw_error;
14626 }
14627 }
14628 /* copy to data structure */
14629 ext_attr->aud_data.auto_sound = *auto_sound;
14630
14631 return 0;
14632rw_error:
14633 return -EIO;
14634}
14635
14636/*============================================================================*/
14637/**
14638* \brief Get the Automatic Standard Select thresholds
14639* \param demod instance of demodulator
14640* \param pointer to pDRXAudASSThres_t
14641* \return int.
14642*
14643*/
14644static int
14645aud_ctrl_get_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14646{
14647 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14648 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14649 int rc;
14650 u16 thres_a2 = 0;
14651 u16 thres_btsc = 0;
14652 u16 thres_nicam = 0;
14653
14654 if (thres == NULL)
14655 return -EINVAL;
14656
14657 dev_addr = demod->my_i2c_dev_addr;
14658 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14659
14660 /* power up */
14661 if (ext_attr->aud_data.audio_is_active == false) {
14662 rc = power_up_aud(demod, true);
14663 if (rc != 0) {
14664 pr_err("error %d\n", rc);
14665 goto rw_error;
14666 }
14667 ext_attr->aud_data.audio_is_active = true;
14668 }
14669
14670 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_A2_THRSHLD__A, &thres_a2, 0);
14671 if (rc != 0) {
14672 pr_err("error %d\n", rc);
14673 goto rw_error;
14674 }
14675 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thres_btsc, 0);
14676 if (rc != 0) {
14677 pr_err("error %d\n", rc);
14678 goto rw_error;
14679 }
14680 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thres_nicam, 0);
14681 if (rc != 0) {
14682 pr_err("error %d\n", rc);
14683 goto rw_error;
14684 }
14685
14686 thres->a2 = thres_a2;
14687 thres->btsc = thres_btsc;
14688 thres->nicam = thres_nicam;
14689
14690 return 0;
14691rw_error:
14692 return -EIO;
14693}
14694
14695/*============================================================================*/
14696/**
14697* \brief Get the Automatic Standard Select thresholds
14698* \param demod instance of demodulator
14699* \param pointer to pDRXAudASSThres_t
14700* \return int.
14701*
14702*/
14703static int
14704aud_ctrl_set_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14705{
14706 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14707 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14708 int rc;
14709 if (thres == NULL)
14710 return -EINVAL;
14711
14712 dev_addr = demod->my_i2c_dev_addr;
14713 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14714
14715 /* power up */
14716 if (ext_attr->aud_data.audio_is_active == false) {
14717 rc = power_up_aud(demod, true);
14718 if (rc != 0) {
14719 pr_err("error %d\n", rc);
14720 goto rw_error;
14721 }
14722 ext_attr->aud_data.audio_is_active = true;
14723 }
14724
14725 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2, 0);
14726 if (rc != 0) {
14727 pr_err("error %d\n", rc);
14728 goto rw_error;
14729 }
14730 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc, 0);
14731 if (rc != 0) {
14732 pr_err("error %d\n", rc);
14733 goto rw_error;
14734 }
14735 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam, 0);
14736 if (rc != 0) {
14737 pr_err("error %d\n", rc);
14738 goto rw_error;
14739 }
14740
14741 /* update DRXK data structure with hardware values */
14742 ext_attr->aud_data.ass_thresholds = *thres;
14743
14744 return 0;
14745rw_error:
14746 return -EIO;
14747}
14748
14749/*============================================================================*/
14750/**
14751* \brief Get Audio Carrier settings
14752* \param demod instance of demodulator
14753* \param pointer to struct drx_aud_carrier ** \return int.
14754*
14755*/
14756static int
14757aud_ctrl_get_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14758{
14759 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14760 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14761 int rc;
14762 u16 w_modus = 0;
14763
14764 u16 dco_a_hi = 0;
14765 u16 dco_a_lo = 0;
14766 u16 dco_b_hi = 0;
14767 u16 dco_b_lo = 0;
14768
14769 u32 valA = 0;
14770 u32 valB = 0;
14771
14772 u16 dc_lvl_a = 0;
14773 u16 dc_lvl_b = 0;
14774
14775 u16 cm_thes_a = 0;
14776 u16 cm_thes_b = 0;
14777
14778 if (carriers == NULL)
14779 return -EINVAL;
14780
14781 dev_addr = demod->my_i2c_dev_addr;
14782 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14783
14784 /* power up */
14785 if (ext_attr->aud_data.audio_is_active == false) {
14786 rc = power_up_aud(demod, true);
14787 if (rc != 0) {
14788 pr_err("error %d\n", rc);
14789 goto rw_error;
14790 }
14791 ext_attr->aud_data.audio_is_active = true;
14792 }
14793
14794 rc = aud_get_modus(demod, &w_modus);
14795 if (rc != 0) {
14796 pr_err("error %d\n", rc);
14797 goto rw_error;
14798 }
14799
14800 /* Behaviour of primary audio channel */
14801 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
14802 case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
14803 carriers->a.opt = DRX_NO_CARRIER_MUTE;
14804 break;
14805 case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
14806 carriers->a.opt = DRX_NO_CARRIER_NOISE;
14807 break;
14808 default:
14809 return -EIO;
14810 break;
14811 }
14812
14813 /* Behaviour of secondary audio channel */
14814 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
14815 case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
14816 carriers->b.opt = DRX_NO_CARRIER_MUTE;
14817 break;
14818 case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
14819 carriers->b.opt = DRX_NO_CARRIER_NOISE;
14820 break;
14821 default:
14822 return -EIO;
14823 break;
14824 }
14825
14826 /* frequency adjustment for primary & secondary audio channel */
14827 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_A_HI__A, &dco_a_hi, 0);
14828 if (rc != 0) {
14829 pr_err("error %d\n", rc);
14830 goto rw_error;
14831 }
14832 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_A_LO__A, &dco_a_lo, 0);
14833 if (rc != 0) {
14834 pr_err("error %d\n", rc);
14835 goto rw_error;
14836 }
14837 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_B_HI__A, &dco_b_hi, 0);
14838 if (rc != 0) {
14839 pr_err("error %d\n", rc);
14840 goto rw_error;
14841 }
14842 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_DCO_B_LO__A, &dco_b_lo, 0);
14843 if (rc != 0) {
14844 pr_err("error %d\n", rc);
14845 goto rw_error;
14846 }
14847
14848 valA = (((u32) dco_a_hi) << 12) | ((u32) dco_a_lo & 0xFFF);
14849 valB = (((u32) dco_b_hi) << 12) | ((u32) dco_b_lo & 0xFFF);
14850
14851 /* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
14852 carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
14853 carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
14854
14855 /* DC level of the incoming FM signal on the primary
14856 & seconday sound channel */
14857 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dc_lvl_a, 0);
14858 if (rc != 0) {
14859 pr_err("error %d\n", rc);
14860 goto rw_error;
14861 }
14862 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dc_lvl_b, 0);
14863 if (rc != 0) {
14864 pr_err("error %d\n", rc);
14865 goto rw_error;
14866 }
14867
14868 /* offset (kHz) = (dcLvl / 322) */
14869 carriers->a.shift = (DRX_U16TODRXFREQ(dc_lvl_a) / 322L);
14870 carriers->b.shift = (DRX_U16TODRXFREQ(dc_lvl_b) / 322L);
14871
14872 /* Carrier detetcion threshold for primary & secondary channel */
14873 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cm_thes_a, 0);
14874 if (rc != 0) {
14875 pr_err("error %d\n", rc);
14876 goto rw_error;
14877 }
14878 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cm_thes_b, 0);
14879 if (rc != 0) {
14880 pr_err("error %d\n", rc);
14881 goto rw_error;
14882 }
14883
14884 carriers->a.thres = cm_thes_a;
14885 carriers->b.thres = cm_thes_b;
14886
14887 return 0;
14888rw_error:
14889 return -EIO;
14890}
14891
14892/*============================================================================*/
14893/**
14894* \brief Set Audio Carrier settings
14895* \param demod instance of demodulator
14896* \param pointer to struct drx_aud_carrier ** \return int.
14897*
14898*/
14899static int
14900aud_ctrl_set_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14901{
14902 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14903 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14904 int rc;
14905 u16 w_modus = 0;
14906 u16 r_modus = 0;
14907 u16 dco_a_hi = 0;
14908 u16 dco_a_lo = 0;
14909 u16 dco_b_hi = 0;
14910 u16 dco_b_lo = 0;
14911 s32 valA = 0;
14912 s32 valB = 0;
14913
14914 if (carriers == NULL)
14915 return -EINVAL;
14916
14917 dev_addr = demod->my_i2c_dev_addr;
14918 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14919
14920 /* power up */
14921 if (ext_attr->aud_data.audio_is_active == false) {
14922 rc = power_up_aud(demod, true);
14923 if (rc != 0) {
14924 pr_err("error %d\n", rc);
14925 goto rw_error;
14926 }
14927 ext_attr->aud_data.audio_is_active = true;
14928 }
14929
14930 rc = aud_get_modus(demod, &r_modus);
14931 if (rc != 0) {
14932 pr_err("error %d\n", rc);
14933 goto rw_error;
14934 }
14935
14936 w_modus = r_modus;
14937 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_A__M;
14938 /* Behaviour of primary audio channel */
14939 switch (carriers->a.opt) {
14940 case DRX_NO_CARRIER_MUTE:
14941 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
14942 break;
14943 case DRX_NO_CARRIER_NOISE:
14944 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
14945 break;
14946 default:
14947 return -EINVAL;
14948 break;
14949 }
14950
14951 /* Behaviour of secondary audio channel */
14952 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_B__M;
14953 switch (carriers->b.opt) {
14954 case DRX_NO_CARRIER_MUTE:
14955 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
14956 break;
14957 case DRX_NO_CARRIER_NOISE:
14958 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
14959 break;
14960 default:
14961 return -EINVAL;
14962 break;
14963 }
14964
14965 /* now update the modus register */
14966 if (w_modus != r_modus) {
14967 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14968 if (rc != 0) {
14969 pr_err("error %d\n", rc);
14970 goto rw_error;
14971 }
14972 }
14973
14974 /* frequency adjustment for primary & secondary audio channel */
14975 valA = (s32) ((carriers->a.dco) * 1657L / 2);
14976 valB = (s32) ((carriers->b.dco) * 1657L / 2);
14977
14978 dco_a_hi = (u16) ((valA >> 12) & 0xFFF);
14979 dco_a_lo = (u16) (valA & 0xFFF);
14980 dco_b_hi = (u16) ((valB >> 12) & 0xFFF);
14981 dco_b_lo = (u16) (valB & 0xFFF);
14982
14983 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_A_HI__A, dco_a_hi, 0);
14984 if (rc != 0) {
14985 pr_err("error %d\n", rc);
14986 goto rw_error;
14987 }
14988 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_A_LO__A, dco_a_lo, 0);
14989 if (rc != 0) {
14990 pr_err("error %d\n", rc);
14991 goto rw_error;
14992 }
14993 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_B_HI__A, dco_b_hi, 0);
14994 if (rc != 0) {
14995 pr_err("error %d\n", rc);
14996 goto rw_error;
14997 }
14998 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_DCO_B_LO__A, dco_b_lo, 0);
14999 if (rc != 0) {
15000 pr_err("error %d\n", rc);
15001 goto rw_error;
15002 }
15003
15004 /* Carrier detetcion threshold for primary & secondary channel */
15005 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres, 0);
15006 if (rc != 0) {
15007 pr_err("error %d\n", rc);
15008 goto rw_error;
15009 }
15010 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres, 0);
15011 if (rc != 0) {
15012 pr_err("error %d\n", rc);
15013 goto rw_error;
15014 }
15015
15016 /* update DRXK data structure */
15017 ext_attr->aud_data.carriers = *carriers;
15018
15019 return 0;
15020rw_error:
15021 return -EIO;
15022}
15023
15024/*============================================================================*/
15025/**
15026* \brief Get I2S Source, I2S matrix and FM matrix
15027* \param demod instance of demodulator
15028* \param pointer to pDRXAudmixer_t
15029* \return int.
15030*
15031*/
15032static int
15033aud_ctrl_get_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
15034{
15035 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15036 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15037 int rc;
15038 u16 src_i2s_matr = 0;
15039 u16 fm_matr = 0;
15040
15041 if (mixer == NULL)
15042 return -EINVAL;
15043
15044 dev_addr = demod->my_i2c_dev_addr;
15045 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15046
15047 /* power up */
15048 if (ext_attr->aud_data.audio_is_active == false) {
15049 rc = power_up_aud(demod, true);
15050 if (rc != 0) {
15051 pr_err("error %d\n", rc);
15052 goto rw_error;
15053 }
15054 ext_attr->aud_data.audio_is_active = true;
15055 }
15056
15057 /* Source Selctor */
15058 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
15059 if (rc != 0) {
15060 pr_err("error %d\n", rc);
15061 goto rw_error;
15062 }
15063
15064 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
15065 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
15066 mixer->source_i2s = DRX_AUD_SRC_MONO;
15067 break;
15068 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
15069 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_AB;
15070 break;
15071 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
15072 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_A;
15073 break;
15074 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
15075 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_B;
15076 break;
15077 default:
15078 return -EIO;
15079 }
15080
15081 /* Matrix */
15082 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
15083 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
15084 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_MONO;
15085 break;
15086 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
15087 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_STEREO;
15088 break;
15089 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
15090 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_A_MONO;
15091 break;
15092 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
15093 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_B_MONO;
15094 break;
15095 default:
15096 return -EIO;
15097 }
15098
15099 /* FM Matrix */
15100 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
15101 if (rc != 0) {
15102 pr_err("error %d\n", rc);
15103 goto rw_error;
15104 }
15105 switch (fm_matr & AUD_DEM_WR_FM_MATRIX__M) {
15106 case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
15107 mixer->matrix_fm = DRX_AUD_FM_MATRIX_NO_MATRIX;
15108 break;
15109 case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
15110 mixer->matrix_fm = DRX_AUD_FM_MATRIX_GERMAN;
15111 break;
15112 case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
15113 mixer->matrix_fm = DRX_AUD_FM_MATRIX_KOREAN;
15114 break;
15115 case AUD_DEM_WR_FM_MATRIX_SOUND_A:
15116 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_A;
15117 break;
15118 case AUD_DEM_WR_FM_MATRIX_SOUND_B:
15119 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_B;
15120 break;
15121 default:
15122 return -EIO;
15123 }
15124
15125 return 0;
15126rw_error:
15127 return -EIO;
15128}
15129
15130/*============================================================================*/
15131/**
15132* \brief Set I2S Source, I2S matrix and FM matrix
15133* \param demod instance of demodulator
15134* \param pointer to DRXAudmixer_t
15135* \return int.
15136*
15137*/
15138static int
15139aud_ctrl_set_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
15140{
15141 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15142 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15143 int rc;
15144 u16 src_i2s_matr = 0;
15145 u16 fm_matr = 0;
15146
15147 if (mixer == NULL)
15148 return -EINVAL;
15149
15150 dev_addr = demod->my_i2c_dev_addr;
15151 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15152
15153 /* power up */
15154 if (ext_attr->aud_data.audio_is_active == false) {
15155 rc = power_up_aud(demod, true);
15156 if (rc != 0) {
15157 pr_err("error %d\n", rc);
15158 goto rw_error;
15159 }
15160 ext_attr->aud_data.audio_is_active = true;
15161 }
15162
15163 /* Source Selctor */
15164 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
15165 if (rc != 0) {
15166 pr_err("error %d\n", rc);
15167 goto rw_error;
15168 }
15169 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
15170
15171 switch (mixer->source_i2s) {
15172 case DRX_AUD_SRC_MONO:
15173 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
15174 break;
15175 case DRX_AUD_SRC_STEREO_OR_AB:
15176 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
15177 break;
15178 case DRX_AUD_SRC_STEREO_OR_A:
15179 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
15180 break;
15181 case DRX_AUD_SRC_STEREO_OR_B:
15182 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
15183 break;
15184 default:
15185 return -EINVAL;
15186 }
15187
15188 /* Matrix */
15189 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
15190 switch (mixer->matrix_i2s) {
15191 case DRX_AUD_I2S_MATRIX_MONO:
15192 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
15193 break;
15194 case DRX_AUD_I2S_MATRIX_STEREO:
15195 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
15196 break;
15197 case DRX_AUD_I2S_MATRIX_A_MONO:
15198 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
15199 break;
15200 case DRX_AUD_I2S_MATRIX_B_MONO:
15201 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
15202 break;
15203 default:
15204 return -EINVAL;
15205 }
15206 /* write the result */
15207 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, src_i2s_matr, 0);
15208 if (rc != 0) {
15209 pr_err("error %d\n", rc);
15210 goto rw_error;
15211 }
15212
15213 /* FM Matrix */
15214 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
15215 if (rc != 0) {
15216 pr_err("error %d\n", rc);
15217 goto rw_error;
15218 }
15219 fm_matr &= (u16) ~AUD_DEM_WR_FM_MATRIX__M;
15220 switch (mixer->matrix_fm) {
15221 case DRX_AUD_FM_MATRIX_NO_MATRIX:
15222 fm_matr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
15223 break;
15224 case DRX_AUD_FM_MATRIX_GERMAN:
15225 fm_matr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
15226 break;
15227 case DRX_AUD_FM_MATRIX_KOREAN:
15228 fm_matr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
15229 break;
15230 case DRX_AUD_FM_MATRIX_SOUND_A:
15231 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
15232 break;
15233 case DRX_AUD_FM_MATRIX_SOUND_B:
15234 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
15235 break;
15236 default:
15237 return -EINVAL;
15238 }
15239
15240 /* Only write if ASS is off */
15241 if (ext_attr->aud_data.auto_sound == DRX_AUD_AUTO_SOUND_OFF) {
15242 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, fm_matr, 0);
15243 if (rc != 0) {
15244 pr_err("error %d\n", rc);
15245 goto rw_error;
15246 }
15247 }
15248
15249 /* update the data structure with hardware state */
15250 ext_attr->aud_data.mixer = *mixer;
15251
15252 return 0;
15253rw_error:
15254 return -EIO;
15255}
15256
15257/*============================================================================*/
15258/**
15259* \brief Set AV Sync settings
15260* \param demod instance of demodulator
15261* \param pointer to DRXICfgAVSync_t
15262* \return int.
15263*
15264*/
15265static int
15266aud_ctrl_set_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15267{
15268 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15269 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15270 int rc;
15271 u16 w_aud_vid_sync = 0;
15272
15273 if (av_sync == NULL)
15274 return -EINVAL;
15275
15276 dev_addr = demod->my_i2c_dev_addr;
15277 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15278
15279 /* power up */
15280 if (ext_attr->aud_data.audio_is_active == false) {
15281 rc = power_up_aud(demod, true);
15282 if (rc != 0) {
15283 pr_err("error %d\n", rc);
15284 goto rw_error;
15285 }
15286 ext_attr->aud_data.audio_is_active = true;
15287 }
15288
15289 /* audio/video synchronisation */
15290 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15291 if (rc != 0) {
15292 pr_err("error %d\n", rc);
15293 goto rw_error;
15294 }
15295
15296 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_ON__M;
15297
15298 if (*av_sync == DRX_AUD_AVSYNC_OFF)
15299 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
15300 else
15301 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
15302
15303 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
15304
15305 switch (*av_sync) {
15306 case DRX_AUD_AVSYNC_NTSC:
15307 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
15308 break;
15309 case DRX_AUD_AVSYNC_MONOCHROME:
15310 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
15311 break;
15312 case DRX_AUD_AVSYNC_PAL_SECAM:
15313 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
15314 break;
15315 case DRX_AUD_AVSYNC_OFF:
15316 /* OK */
15317 break;
15318 default:
15319 return -EINVAL;
15320 }
15321
15322 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_AV_SYNC__A, w_aud_vid_sync, 0);
15323 if (rc != 0) {
15324 pr_err("error %d\n", rc);
15325 goto rw_error;
15326 }
15327 return 0;
15328rw_error:
15329 return -EIO;
15330}
15331
15332/*============================================================================*/
15333/**
15334* \brief Get AV Sync settings
15335* \param demod instance of demodulator
15336* \param pointer to DRXICfgAVSync_t
15337* \return int.
15338*
15339*/
15340static int
15341aud_ctrl_get_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15342{
15343 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15344 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15345 int rc;
15346 u16 w_aud_vid_sync = 0;
15347
15348 if (av_sync == NULL)
15349 return -EINVAL;
15350
15351 dev_addr = demod->my_i2c_dev_addr;
15352 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15353
15354 /* power up */
15355 if (ext_attr->aud_data.audio_is_active == false) {
15356 rc = power_up_aud(demod, true);
15357 if (rc != 0) {
15358 pr_err("error %d\n", rc);
15359 goto rw_error;
15360 }
15361 ext_attr->aud_data.audio_is_active = true;
15362 }
15363
15364 /* audio/video synchronisation */
15365 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15366 if (rc != 0) {
15367 pr_err("error %d\n", rc);
15368 goto rw_error;
15369 }
15370
15371 if ((w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
15372 AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
15373 *av_sync = DRX_AUD_AVSYNC_OFF;
15374 return 0;
15375 }
15376
15377 switch (w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
15378 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
15379 *av_sync = DRX_AUD_AVSYNC_NTSC;
15380 break;
15381 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
15382 *av_sync = DRX_AUD_AVSYNC_MONOCHROME;
15383 break;
15384 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
15385 *av_sync = DRX_AUD_AVSYNC_PAL_SECAM;
15386 break;
15387 default:
15388 return -EIO;
15389 }
15390
15391 return 0;
15392rw_error:
15393 return -EIO;
15394}
15395
15396/*============================================================================*/
15397/**
15398* \brief Get deviation mode
15399* \param demod instance of demodulator
15400* \param pointer to enum drx_cfg_aud_deviation * \return int.
15401*
15402*/
15403static int
15404aud_ctrl_get_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15405{
15406 u16 r_modus = 0;
15407 int rc;
15408
15409 if (dev == NULL)
15410 return -EINVAL;
15411
15412 rc = aud_get_modus(demod, &r_modus);
15413 if (rc != 0) {
15414 pr_err("error %d\n", rc);
15415 goto rw_error;
15416 }
15417
15418 switch (r_modus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
15419 case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
15420 *dev = DRX_AUD_DEVIATION_NORMAL;
15421 break;
15422 case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
15423 *dev = DRX_AUD_DEVIATION_HIGH;
15424 break;
15425 default:
15426 return -EIO;
15427 }
15428
15429 return 0;
15430rw_error:
15431 return -EIO;
15432}
15433
15434/*============================================================================*/
15435/**
15436* \brief Get deviation mode
15437* \param demod instance of demodulator
15438* \param pointer to enum drx_cfg_aud_deviation * \return int.
15439*
15440*/
15441static int
15442aud_ctrl_set_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15443{
15444 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15445 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15446 int rc;
15447 u16 w_modus = 0;
15448 u16 r_modus = 0;
15449
15450 if (dev == NULL)
15451 return -EINVAL;
15452
15453 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15454 dev_addr = demod->my_i2c_dev_addr;
15455
15456 rc = aud_get_modus(demod, &r_modus);
15457 if (rc != 0) {
15458 pr_err("error %d\n", rc);
15459 goto rw_error;
15460 }
15461
15462 w_modus = r_modus;
15463
15464 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
15465
15466 switch (*dev) {
15467 case DRX_AUD_DEVIATION_NORMAL:
15468 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
15469 break;
15470 case DRX_AUD_DEVIATION_HIGH:
15471 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
15472 break;
15473 default:
15474 return -EINVAL;
15475 }
15476
15477 /* now update the modus register */
15478 if (w_modus != r_modus) {
15479 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15480 if (rc != 0) {
15481 pr_err("error %d\n", rc);
15482 goto rw_error;
15483 }
15484 }
15485 /* store in drxk data struct */
15486 ext_attr->aud_data.deviation = *dev;
15487
15488 return 0;
15489rw_error:
15490 return -EIO;
15491}
15492
15493/*============================================================================*/
15494/**
15495* \brief Get Prescaler settings
15496* \param demod instance of demodulator
15497* \param pointer to struct drx_cfg_aud_prescale * \return int.
15498*
15499*/
15500static int
15501aud_ctrl_get_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15502{
15503 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15504 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15505 int rc;
15506 u16 r_max_fm_deviation = 0;
15507 u16 r_nicam_prescaler = 0;
15508
15509 if (presc == NULL)
15510 return -EINVAL;
15511
15512 dev_addr = demod->my_i2c_dev_addr;
15513 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15514
15515 /* power up */
15516 if (ext_attr->aud_data.audio_is_active == false) {
15517 rc = power_up_aud(demod, true);
15518 if (rc != 0) {
15519 pr_err("error %d\n", rc);
15520 goto rw_error;
15521 }
15522 ext_attr->aud_data.audio_is_active = true;
15523 }
15524
15525 /* read register data */
15526 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, &r_nicam_prescaler, 0);
15527 if (rc != 0) {
15528 pr_err("error %d\n", rc);
15529 goto rw_error;
15530 }
15531 rc = drxj_dap_read_reg16(dev_addr, AUD_DSP_WR_FM_PRESC__A, &r_max_fm_deviation, 0);
15532 if (rc != 0) {
15533 pr_err("error %d\n", rc);
15534 goto rw_error;
15535 }
15536
15537 /* calculate max FM deviation */
15538 r_max_fm_deviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15539 if (r_max_fm_deviation > 0) {
15540 presc->fm_deviation = 3600UL + (r_max_fm_deviation >> 1);
15541 presc->fm_deviation /= r_max_fm_deviation;
15542 } else {
15543 presc->fm_deviation = 380; /* kHz */
15544 }
15545
15546 /* calculate NICAM gain from pre-scaler */
15547 /*
15548 nicam_gain = 20 * ( log10( preScaler / 16) )
15549 = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
15550
15551 because log1_times100() cannot return negative numbers
15552 = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
15553
15554 for 0.1dB resolution:
15555
15556 nicam_gain = 200 * ( log10( preScaler / 16) )
15557 = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
15558 = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
15559
15560 */
15561 r_nicam_prescaler >>= 8;
15562 if (r_nicam_prescaler <= 1)
15563 presc->nicam_gain = -241;
15564 else
15565 presc->nicam_gain = (s16)(((s32)(log1_times100(10 * r_nicam_prescaler * r_nicam_prescaler)) - (s32)(log1_times100(10 * 16 * 16))));
15566
15567 return 0;
15568rw_error:
15569 return -EIO;
15570}
15571
15572/*============================================================================*/
15573/**
15574* \brief Set Prescaler settings
15575* \param demod instance of demodulator
15576* \param pointer to struct drx_cfg_aud_prescale * \return int.
15577*
15578*/
15579static int
15580aud_ctrl_set_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15581{
15582 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15583 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15584 int rc;
15585 u16 w_max_fm_deviation = 0;
15586 u16 nicam_prescaler;
15587
15588 if (presc == NULL)
15589 return -EINVAL;
15590
15591 dev_addr = demod->my_i2c_dev_addr;
15592 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15593
15594 /* power up */
15595 if (ext_attr->aud_data.audio_is_active == false) {
15596 rc = power_up_aud(demod, true);
15597 if (rc != 0) {
15598 pr_err("error %d\n", rc);
15599 goto rw_error;
15600 }
15601 ext_attr->aud_data.audio_is_active = true;
15602 }
15603
15604 /* setting of max FM deviation */
15605 w_max_fm_deviation = (u16) (frac(3600UL, presc->fm_deviation, 0));
15606 w_max_fm_deviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15607 if (w_max_fm_deviation >= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION)
15608 w_max_fm_deviation = AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
15609
15610 /* NICAM Prescaler */
15611 if ((presc->nicam_gain >= -241) && (presc->nicam_gain <= 180)) {
15612 /* calculation
15613
15614 prescaler = 16 * 10^( gd_b / 20 )
15615
15616 minval of gd_b = -20*log( 16 ) = -24.1dB
15617
15618 negative numbers not allowed for d_b2lin_times100, so
15619
15620 prescaler = 16 * 10^( gd_b / 20 )
15621 = 10^( (gd_b / 20) + log10(16) )
15622 = 10^( (gd_b + 20log10(16)) / 20 )
15623
15624 in 0.1dB
15625
15626 = 10^( G0.1dB + 200log10(16)) / 200 )
15627
15628 */
15629 nicam_prescaler = (u16)
15630 ((d_b2lin_times100(presc->nicam_gain + 241UL) + 50UL) / 100UL);
15631
15632 /* clip result */
15633 if (nicam_prescaler > 127)
15634 nicam_prescaler = 127;
15635
15636 /* shift before writing to register */
15637 nicam_prescaler <<= 8;
15638 } else {
15639 return -EINVAL;
15640 }
15641 /* end of setting NICAM Prescaler */
15642
15643 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, nicam_prescaler, 0);
15644 if (rc != 0) {
15645 pr_err("error %d\n", rc);
15646 goto rw_error;
15647 }
15648 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_FM_PRESC__A, w_max_fm_deviation, 0);
15649 if (rc != 0) {
15650 pr_err("error %d\n", rc);
15651 goto rw_error;
15652 }
15653
15654 ext_attr->aud_data.prescale = *presc;
15655
15656 return 0;
15657rw_error:
15658 return -EIO;
15659}
15660
15661/*============================================================================*/
15662/**
15663* \brief Beep
15664* \param demod instance of demodulator
15665* \param pointer to struct drx_aud_beep * \return int.
15666*
15667*/
15668static int aud_ctrl_beep(struct drx_demod_instance *demod, struct drx_aud_beep *beep)
15669{
15670 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15671 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15672 int rc;
15673 u16 the_beep = 0;
15674 u16 volume = 0;
15675 u32 frequency = 0;
15676
15677 if (beep == NULL)
15678 return -EINVAL;
15679
15680 dev_addr = demod->my_i2c_dev_addr;
15681 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15682
15683 /* power up */
15684 if (ext_attr->aud_data.audio_is_active == false) {
15685 rc = power_up_aud(demod, true);
15686 if (rc != 0) {
15687 pr_err("error %d\n", rc);
15688 goto rw_error;
15689 }
15690 ext_attr->aud_data.audio_is_active = true;
15691 }
15692
15693 if ((beep->volume > 0) || (beep->volume < -127))
15694 return -EINVAL;
15695
15696 if (beep->frequency > 3000)
15697 return -EINVAL;
15698
15699 volume = (u16) beep->volume + 127;
15700 the_beep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
15701
15702 frequency = ((u32) beep->frequency) * 23 / 500;
15703 if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M)
15704 frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
15705 the_beep |= (u16) frequency;
15706
15707 if (beep->mute == true)
15708 the_beep = 0;
15709
15710 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_BEEPER__A, the_beep, 0);
15711 if (rc != 0) {
15712 pr_err("error %d\n", rc);
15713 goto rw_error;
15714 }
15715
15716 return 0;
15717rw_error:
15718 return -EIO;
15719}
15720
15721/*============================================================================*/
15722/**
15723* \brief Set an audio standard
15724* \param demod instance of demodulator
15725* \param pointer to enum drx_aud_standard * \return int.
15726*
15727*/
15728static int
15729aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15730{
15731 struct i2c_device_addr *dev_addr = NULL;
15732 struct drxj_data *ext_attr = NULL;
15733 enum drx_standard current_standard = DRX_STANDARD_UNKNOWN;
15734 int rc;
15735 u16 w_standard = 0;
15736 u16 w_modus = 0;
15737 u16 r_modus = 0;
15738
15739 bool mute_buffer = false;
15740 s16 volume_buffer = 0;
15741 u16 w_volume = 0;
15742
15743 if (standard == NULL)
15744 return -EINVAL;
15745
15746 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15747 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15748
15749 /* power up */
15750 if (ext_attr->aud_data.audio_is_active == false) {
15751 rc = power_up_aud(demod, false);
15752 if (rc != 0) {
15753 pr_err("error %d\n", rc);
15754 goto rw_error;
15755 }
15756 ext_attr->aud_data.audio_is_active = true;
15757 }
15758
15759 /* reset RDS data availability flag */
15760 ext_attr->aud_data.rds_data_present = false;
15761
15762 /* we need to mute from here to avoid noise during standard switching */
15763 mute_buffer = ext_attr->aud_data.volume.mute;
15764 volume_buffer = ext_attr->aud_data.volume.volume;
15765
15766 ext_attr->aud_data.volume.mute = true;
15767 /* restore data structure from DRX ExtAttr, call volume first to mute */
15768 rc = aud_ctrl_set_cfg_volume(demod, &ext_attr->aud_data.volume);
15769 if (rc != 0) {
15770 pr_err("error %d\n", rc);
15771 goto rw_error;
15772 }
15773 rc = aud_ctrl_set_cfg_carrier(demod, &ext_attr->aud_data.carriers);
15774 if (rc != 0) {
15775 pr_err("error %d\n", rc);
15776 goto rw_error;
15777 }
15778 rc = aud_ctrl_set_cfg_ass_thres(demod, &ext_attr->aud_data.ass_thresholds);
15779 if (rc != 0) {
15780 pr_err("error %d\n", rc);
15781 goto rw_error;
15782 }
15783 rc = aud_ctr_setl_cfg_auto_sound(demod, &ext_attr->aud_data.auto_sound);
15784 if (rc != 0) {
15785 pr_err("error %d\n", rc);
15786 goto rw_error;
15787 }
15788 rc = aud_ctrl_set_cfg_mixer(demod, &ext_attr->aud_data.mixer);
15789 if (rc != 0) {
15790 pr_err("error %d\n", rc);
15791 goto rw_error;
15792 }
15793 rc = aud_ctrl_set_cfg_av_sync(demod, &ext_attr->aud_data.av_sync);
15794 if (rc != 0) {
15795 pr_err("error %d\n", rc);
15796 goto rw_error;
15797 }
15798 rc = aud_ctrl_set_cfg_output_i2s(demod, &ext_attr->aud_data.i2sdata);
15799 if (rc != 0) {
15800 pr_err("error %d\n", rc);
15801 goto rw_error;
15802 }
15803
15804 /* get prescaler from presets */
15805 rc = aud_ctrl_set_cfg_prescale(demod, &ext_attr->aud_data.prescale);
15806 if (rc != 0) {
15807 pr_err("error %d\n", rc);
15808 goto rw_error;
15809 }
15810
15811 rc = aud_get_modus(demod, &r_modus);
15812 if (rc != 0) {
15813 pr_err("error %d\n", rc);
15814 goto rw_error;
15815 }
15816
15817 w_modus = r_modus;
15818
15819 switch (*standard) {
15820 case DRX_AUD_STANDARD_AUTO:
15821 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15822 break;
15823 case DRX_AUD_STANDARD_BTSC:
15824 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
15825 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_MONO_AND_SAP)
15826 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
15827 break;
15828 case DRX_AUD_STANDARD_A2:
15829 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
15830 break;
15831 case DRX_AUD_STANDARD_EIAJ:
15832 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
15833 break;
15834 case DRX_AUD_STANDARD_FM_STEREO:
15835 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
15836 break;
15837 case DRX_AUD_STANDARD_BG_FM:
15838 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
15839 break;
15840 case DRX_AUD_STANDARD_D_K1:
15841 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
15842 break;
15843 case DRX_AUD_STANDARD_D_K2:
15844 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
15845 break;
15846 case DRX_AUD_STANDARD_D_K3:
15847 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
15848 break;
15849 case DRX_AUD_STANDARD_BG_NICAM_FM:
15850 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
15851 break;
15852 case DRX_AUD_STANDARD_L_NICAM_AM:
15853 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
15854 break;
15855 case DRX_AUD_STANDARD_I_NICAM_FM:
15856 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
15857 break;
15858 case DRX_AUD_STANDARD_D_K_NICAM_FM:
15859 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
15860 break;
15861 case DRX_AUD_STANDARD_UNKNOWN:
15862 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15863 break;
15864 default:
15865 return -EIO;
15866 }
15867
15868 if (*standard == DRX_AUD_STANDARD_AUTO) {
15869 /* we need the current standard here */
15870 current_standard = ext_attr->standard;
15871
15872 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
15873
15874 if ((current_standard == DRX_STANDARD_PAL_SECAM_L) || (current_standard == DRX_STANDARD_PAL_SECAM_LP))
15875 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
15876 else
15877 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
15878
15879 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
15880 if (current_standard == DRX_STANDARD_NTSC)
15881 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
15882 else
15883 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
15884
15885 }
15886
15887 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
15888
15889 /* just get hardcoded deemphasis and activate here */
15890 if (ext_attr->aud_data.deemph == DRX_AUD_FM_DEEMPH_50US)
15891 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
15892 else
15893 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
15894
15895 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_BTSC__M;
15896 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_STEREO)
15897 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
15898 else
15899 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
15900
15901 if (w_modus != r_modus) {
15902 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15903 if (rc != 0) {
15904 pr_err("error %d\n", rc);
15905 goto rw_error;
15906 }
15907 }
15908
15909 rc = drxj_dap_write_reg16(dev_addr, AUD_DEM_WR_STANDARD_SEL__A, w_standard, 0);
15910 if (rc != 0) {
15911 pr_err("error %d\n", rc);
15912 goto rw_error;
15913 }
15914
15915 /**************************************************************************/
15916 /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard */
15917 /* detection, need to keep things very minimal here, but keep audio */
15918 /* buffers intact */
15919 /**************************************************************************/
15920 ext_attr->aud_data.volume.mute = mute_buffer;
15921 if (ext_attr->aud_data.volume.mute == false) {
15922 w_volume |= (u16) ((volume_buffer + AUD_VOLUME_ZERO_DB) <<
15923 AUD_DSP_WR_VOLUME_VOL_MAIN__B);
15924 rc = drxj_dap_write_reg16(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
15925 if (rc != 0) {
15926 pr_err("error %d\n", rc);
15927 goto rw_error;
15928 }
15929 }
15930
15931 /* write standard selected */
15932 ext_attr->aud_data.audio_standard = *standard;
15933
15934 return 0;
15935rw_error:
15936 return -EIO;
15937}
15938
15939/*============================================================================*/
15940/**
15941* \brief Get the current audio standard
15942* \param demod instance of demodulator
15943* \param pointer to enum drx_aud_standard * \return int.
15944*
15945*/
15946static int
15947aud_ctrl_get_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15948{
15949 struct i2c_device_addr *dev_addr = NULL;
15950 struct drxj_data *ext_attr = NULL;
15951 int rc;
15952 u16 r_data = 0;
15953
15954 if (standard == NULL)
15955 return -EINVAL;
15956
15957 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15958 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15959
15960 /* power up */
15961 if (ext_attr->aud_data.audio_is_active == false) {
15962 rc = power_up_aud(demod, true);
15963 if (rc != 0) {
15964 pr_err("error %d\n", rc);
15965 goto rw_error;
15966 }
15967 ext_attr->aud_data.audio_is_active = true;
15968 }
15969
15970 *standard = DRX_AUD_STANDARD_UNKNOWN;
15971
15972 rc = drxj_dap_read_reg16(dev_addr, AUD_DEM_RD_STANDARD_RES__A, &r_data, 0);
15973 if (rc != 0) {
15974 pr_err("error %d\n", rc);
15975 goto rw_error;
15976 }
15977
15978 /* return OK if the detection is not ready yet */
15979 if (r_data >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
15980 *standard = DRX_AUD_STANDARD_NOT_READY;
15981 return 0;
15982 }
15983
15984 /* detection done, return correct standard */
15985 switch (r_data) {
15986 /* no standard detected */
15987 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
15988 *standard = DRX_AUD_STANDARD_UNKNOWN;
15989 break;
15990 /* standard is KOREA(A2) */
15991 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
15992 *standard = DRX_AUD_STANDARD_A2;
15993 break;
15994 /* standard is EIA-J (Japan) */
15995 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
15996 *standard = DRX_AUD_STANDARD_EIAJ;
15997 break;
15998 /* standard is BTSC-stereo */
15999 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
16000 *standard = DRX_AUD_STANDARD_BTSC;
16001 break;
16002 /* standard is BTSC-mono (SAP) */
16003 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
16004 *standard = DRX_AUD_STANDARD_BTSC;
16005 break;
16006 /* standard is FM radio */
16007 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
16008 *standard = DRX_AUD_STANDARD_FM_STEREO;
16009 break;
16010 /* standard is BG FM */
16011 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
16012 *standard = DRX_AUD_STANDARD_BG_FM;
16013 break;
16014 /* standard is DK-1 FM */
16015 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
16016 *standard = DRX_AUD_STANDARD_D_K1;
16017 break;
16018 /* standard is DK-2 FM */
16019 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
16020 *standard = DRX_AUD_STANDARD_D_K2;
16021 break;
16022 /* standard is DK-3 FM */
16023 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
16024 *standard = DRX_AUD_STANDARD_D_K3;
16025 break;
16026 /* standard is BG-NICAM FM */
16027 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
16028 *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
16029 break;
16030 /* standard is L-NICAM AM */
16031 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
16032 *standard = DRX_AUD_STANDARD_L_NICAM_AM;
16033 break;
16034 /* standard is I-NICAM FM */
16035 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
16036 *standard = DRX_AUD_STANDARD_I_NICAM_FM;
16037 break;
16038 /* standard is DK-NICAM FM */
16039 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
16040 *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
16041 break;
16042 default:
16043 *standard = DRX_AUD_STANDARD_UNKNOWN;
16044 }
16045
16046 return 0;
16047rw_error:
16048 return -EIO;
16049
16050}
16051
16052/*============================================================================*/
16053/**
16054* \brief Retreive lock status in case of FM standard
16055* \param demod instance of demodulator
16056* \param pointer to lock status
16057* \return int.
16058*
16059*/
16060static int
16061fm_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
16062{
16063 struct drx_aud_status status;
16064 int rc;
16065
16066 /* Check detection of audio carriers */
16067 rc = aud_ctrl_get_carrier_detect_status(demod, &status);
16068 if (rc != 0) {
16069 pr_err("error %d\n", rc);
16070 goto rw_error;
16071 }
16072
16073 /* locked if either primary or secondary carrier is detected */
16074 if ((status.carrier_a == true) || (status.carrier_b == true))
16075 *lock_stat = DRX_LOCKED;
16076 else
16077 *lock_stat = DRX_NOT_LOCKED;
16078
16079 return 0;
16080
16081rw_error:
16082 return -EIO;
16083}
16084
16085/*============================================================================*/
16086/**
16087* \brief retreive signal quality in case of FM standard
16088* \param demod instance of demodulator
16089* \param pointer to signal quality
16090* \return int.
16091*
16092* Only the quality indicator field is will be supplied.
16093* This will either be 0% or 100%, nothing in between.
16094*
16095*/
16096static int
16097fm_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
16098{
16099 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
16100 int rc;
16101
16102 rc = fm_lock_status(demod, &lock_status);
16103 if (rc != 0) {
16104 pr_err("error %d\n", rc);
16105 goto rw_error;
16106 }
16107 if (lock_status == DRX_LOCKED)
16108 sig_quality->indicator = 100;
16109 else
16110 sig_quality->indicator = 0;
16111
16112 return 0;
16113
16114rw_error:
16115 return -EIO;
16116}
16117
16118/*===========================================================================*/
16119/*== END AUDIO DATAPATH FUNCTIONS ==*/
16120/*===========================================================================*/
16121
16122/*============================================================================*/
16123/*============================================================================*/
16124/*== OOB DATAPATH FUNCTIONS ==*/
16125/*============================================================================*/
16126/*============================================================================*/
16127/**
16128* \fn int get_oob_lock_status ()
16129* \brief Get OOB lock status.
16130* \param dev_addr I2C address
16131 \ oob_lock OOB lock status.
16132* \return int.
16133*
16134* Gets OOB lock status
16135*
16136*/
16137static int
16138get_oob_lock_status(struct drx_demod_instance *demod,
16139 struct i2c_device_addr *dev_addr, enum drx_lock_status *oob_lock)
16140{
16141 struct drxjscu_cmd scu_cmd;
16142 int rc;
16143 u16 cmd_result[2];
16144 u16 oob_lock_state;
16145
16146 *oob_lock = DRX_NOT_LOCKED;
16147
16148 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
16149 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
16150 scu_cmd.result_len = 2;
16151 scu_cmd.result = cmd_result;
16152 scu_cmd.parameter_len = 0;
16153
16154 rc = scu_command(dev_addr, &scu_cmd);
16155 if (rc != 0) {
16156 pr_err("error %d\n", rc);
16157 goto rw_error;
16158 }
16159
16160 if (scu_cmd.result[1] < 0x4000) {
16161 /* 0x00 NOT LOCKED */
16162 *oob_lock = DRX_NOT_LOCKED;
16163 } else if (scu_cmd.result[1] < 0x8000) {
16164 /* 0x40 DEMOD LOCKED */
16165 *oob_lock = DRXJ_OOB_SYNC_LOCK;
16166 } else if (scu_cmd.result[1] < 0xC000) {
16167 /* 0x80 DEMOD + OOB LOCKED (system lock) */
16168 oob_lock_state = scu_cmd.result[1] & 0x00FF;
16169
16170 if (oob_lock_state & 0x0008)
16171 *oob_lock = DRXJ_OOB_SYNC_LOCK;
16172 else if ((oob_lock_state & 0x0002) && (oob_lock_state & 0x0001))
16173 *oob_lock = DRXJ_OOB_AGC_LOCK;
16174 } else {
16175 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
16176 *oob_lock = DRX_NEVER_LOCK;
16177 }
16178
16179 /* *oob_lock = scu_cmd.result[1]; */
16180
16181 return 0;
16182rw_error:
16183 return -EIO;
16184}
16185
16186/**
16187* \fn int get_oob_symbol_rate_offset ()
16188* \brief Get OOB Symbol rate offset. Unit is [ppm]
16189* \param dev_addr I2C address
16190* \ Symbol Rate Offset OOB parameter.
16191* \return int.
16192*
16193* Gets OOB frequency offset
16194*
16195*/
16196static int
16197get_oob_symbol_rate_offset(struct i2c_device_addr *dev_addr, s32 *symbol_rate_offset)
16198{
16199/* offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm] */
16200/* offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm] */
16201/* after reconfiguration: */
16202/* offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm] */
16203/* shift symbol rate left by 5 without lossing information */
16204/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
16205/* shift 10^6 left by 6 without loosing information */
16206/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
16207/* trim 12656250/15625 = 810 */
16208/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm] */
16209/* offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm] */
16210 int rc;
16211 s32 timing_offset = 0;
16212 u32 unsigned_timing_offset = 0;
16213 s32 division_factor = 810;
16214 u16 data = 0;
16215 u32 symbol_rate = 0;
16216 bool negative = false;
16217
16218 *symbol_rate_offset = 0;
16219 /* read data rate */
16220 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data, 0);
16221 if (rc != 0) {
16222 pr_err("error %d\n", rc);
16223 goto rw_error;
16224 }
16225 switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16226 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16227 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16228 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16229 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16230 symbol_rate = 1024000; /* bps */
16231 break;
16232 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16233 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16234 symbol_rate = 772000; /* bps */
16235 break;
16236 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16237 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16238 symbol_rate = 1544000; /* bps */
16239 break;
16240 default:
16241 return -EIO;
16242 }
16243
16244 rc = drxj_dap_read_reg16(dev_addr, ORX_CON_CTI_DTI_R__A, &data, 0);
16245 if (rc != 0) {
16246 pr_err("error %d\n", rc);
16247 goto rw_error;
16248 }
16249 /* convert data to positive and keep information about sign */
16250 if ((data & 0x8000) == 0x8000) {
16251 if (data == 0x8000)
16252 unsigned_timing_offset = 32768;
16253 else
16254 unsigned_timing_offset = 0x00007FFF & (u32) (-data);
16255 negative = true;
16256 } else
16257 unsigned_timing_offset = (u32) data;
16258
16259 symbol_rate = symbol_rate >> 5;
16260 unsigned_timing_offset = (unsigned_timing_offset * symbol_rate);
16261 unsigned_timing_offset = frac(unsigned_timing_offset, 256, FRAC_ROUND);
16262 unsigned_timing_offset = frac(unsigned_timing_offset,
16263 division_factor, FRAC_ROUND);
16264 if (negative)
16265 timing_offset = (s32) unsigned_timing_offset;
16266 else
16267 timing_offset = -(s32) unsigned_timing_offset;
16268
16269 *symbol_rate_offset = timing_offset;
16270
16271 return 0;
16272rw_error:
16273 return -EIO;
16274}
16275
16276/**
16277* \fn int get_oob_freq_offset ()
16278* \brief Get OOB lock status.
16279* \param dev_addr I2C address
16280* \ freq_offset OOB frequency offset.
16281* \return int.
16282*
16283* Gets OOB frequency offset
16284*
16285*/
16286static int
16287get_oob_freq_offset(struct drx_demod_instance *demod, s32 *freq_offset)
16288{
16289 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
16290 struct i2c_device_addr *dev_addr = NULL;
16291 int rc;
16292 u16 data = 0;
16293 u16 rot = 0;
16294 u16 symbol_rate_reg = 0;
16295 u32 symbol_rate = 0;
16296 s32 coarse_freq_offset = 0;
16297 s32 fine_freq_offset = 0;
16298 s32 fine_sign = 1;
16299 s32 coarse_sign = 1;
16300 u32 data64hi = 0;
16301 u32 data64lo = 0;
16302 u32 temp_freq_offset = 0;
16303
16304 /* check arguments */
16305 if ((demod == NULL) || (freq_offset == NULL))
16306 return -EINVAL;
16307
16308 dev_addr = demod->my_i2c_dev_addr;
16309 common_attr = (struct drx_common_attr *) demod->my_common_attr;
16310
16311 *freq_offset = 0;
16312
16313 /* read sign (spectrum inversion) */
16314 rc = drxj_dap_read_reg16(dev_addr, ORX_FWP_IQM_FRQ_W__A, &rot, 0);
16315 if (rc != 0) {
16316 pr_err("error %d\n", rc);
16317 goto rw_error;
16318 }
16319
16320 /* read frequency offset */
16321 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_FRQ_OFFSET__A, &data, 0);
16322 if (rc != 0) {
16323 pr_err("error %d\n", rc);
16324 goto rw_error;
16325 }
16326 /* find COARSE frequency offset */
16327 /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
16328 if (data & 0x8000) {
16329 data = (0xffff - data + 1);
16330 coarse_sign = -1;
16331 }
16332 mult32(data, (common_attr->sys_clock_freq * 1000) / 6, &data64hi,
16333 &data64lo);
16334 temp_freq_offset = (((data64lo >> 21) & 0x7ff) | (data64hi << 11));
16335
16336 /* get value in KHz */
16337 coarse_freq_offset = coarse_sign * frac(temp_freq_offset, 1000, FRAC_ROUND); /* KHz */
16338 /* read data rate */
16339 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbol_rate_reg, 0);
16340 if (rc != 0) {
16341 pr_err("error %d\n", rc);
16342 goto rw_error;
16343 }
16344 switch (symbol_rate_reg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16345 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16346 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16347 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16348 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16349 symbol_rate = 1024000;
16350 break;
16351 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16352 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16353 symbol_rate = 772000;
16354 break;
16355 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16356 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16357 symbol_rate = 1544000;
16358 break;
16359 default:
16360 return -EIO;
16361 }
16362
16363 /* find FINE frequency offset */
16364 /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
16365 rc = drxj_dap_read_reg16(dev_addr, ORX_CON_CPH_FRQ_R__A, &data, 0);
16366 if (rc != 0) {
16367 pr_err("error %d\n", rc);
16368 goto rw_error;
16369 }
16370 /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
16371 fine_freq_offset = (symbol_rate >> 5);
16372 if (data & 0x8000) {
16373 fine_freq_offset *= 0xffff - data + 1; /* Hz */
16374 fine_sign = -1;
16375 } else {
16376 fine_freq_offset *= data; /* Hz */
16377 }
16378 /* Left to divide with 8192 (2^13) */
16379 fine_freq_offset = frac(fine_freq_offset, 8192, FRAC_ROUND);
16380 /* and to divide with 1000 to get KHz */
16381 fine_freq_offset = fine_sign * frac(fine_freq_offset, 1000, FRAC_ROUND); /* KHz */
16382
16383 if ((rot & 0x8000) == 0x8000)
16384 *freq_offset = -(coarse_freq_offset + fine_freq_offset);
16385 else
16386 *freq_offset = (coarse_freq_offset + fine_freq_offset);
16387
16388 return 0;
16389rw_error:
16390 return -EIO;
16391}
16392
16393/**
16394* \fn int get_oob_frequency ()
16395* \brief Get OOB frequency (Unit:KHz).
16396* \param dev_addr I2C address
16397* \ frequency OOB frequency parameters.
16398* \return int.
16399*
16400* Gets OOB frequency
16401*
16402*/
16403static int
16404get_oob_frequency(struct drx_demod_instance *demod, s32 *frequency)
16405{
16406 struct i2c_device_addr *dev_addr = NULL;
16407 int rc;
16408 u16 data = 0;
16409 s32 freq_offset = 0;
16410 s32 freq = 0;
16411
16412 dev_addr = demod->my_i2c_dev_addr;
16413
16414 *frequency = 0; /* KHz */
16415
16416 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data, 0);
16417 if (rc != 0) {
16418 pr_err("error %d\n", rc);
16419 goto rw_error;
16420 }
16421
16422 freq = (s32) ((s32) data * 50 + 50000L);
16423
16424 rc = get_oob_freq_offset(demod, &freq_offset);
16425 if (rc != 0) {
16426 pr_err("error %d\n", rc);
16427 goto rw_error;
16428 }
16429
16430 *frequency = freq + freq_offset;
16431
16432 return 0;
16433rw_error:
16434 return -EIO;
16435}
16436
16437/**
16438* \fn int get_oobmer ()
16439* \brief Get OOB MER.
16440* \param dev_addr I2C address
16441 \ MER OOB parameter in dB.
16442* \return int.
16443*
16444* Gets OOB MER. Table for MER is in Programming guide.
16445*
16446*/
16447static int get_oobmer(struct i2c_device_addr *dev_addr, u32 *mer)
16448{
16449 int rc;
16450 u16 data = 0;
16451
16452 *mer = 0;
16453 /* READ MER */
16454 rc = drxj_dap_read_reg16(dev_addr, ORX_EQU_MER_MER_R__A, &data, 0);
16455 if (rc != 0) {
16456 pr_err("error %d\n", rc);
16457 goto rw_error;
16458 }
16459 switch (data) {
16460 case 0: /* fall through */
16461 case 1:
16462 *mer = 39;
16463 break;
16464 case 2:
16465 *mer = 33;
16466 break;
16467 case 3:
16468 *mer = 29;
16469 break;
16470 case 4:
16471 *mer = 27;
16472 break;
16473 case 5:
16474 *mer = 25;
16475 break;
16476 case 6:
16477 *mer = 23;
16478 break;
16479 case 7:
16480 *mer = 22;
16481 break;
16482 case 8:
16483 *mer = 21;
16484 break;
16485 case 9:
16486 *mer = 20;
16487 break;
16488 case 10:
16489 *mer = 19;
16490 break;
16491 case 11:
16492 *mer = 18;
16493 break;
16494 case 12:
16495 *mer = 17;
16496 break;
16497 case 13: /* fall through */
16498 case 14:
16499 *mer = 16;
16500 break;
16501 case 15: /* fall through */
16502 case 16:
16503 *mer = 15;
16504 break;
16505 case 17: /* fall through */
16506 case 18:
16507 *mer = 14;
16508 break;
16509 case 19: /* fall through */
16510 case 20:
16511 *mer = 13;
16512 break;
16513 case 21: /* fall through */
16514 case 22:
16515 *mer = 12;
16516 break;
16517 case 23: /* fall through */
16518 case 24: /* fall through */
16519 case 25:
16520 *mer = 11;
16521 break;
16522 case 26: /* fall through */
16523 case 27: /* fall through */
16524 case 28:
16525 *mer = 10;
16526 break;
16527 case 29: /* fall through */
16528 case 30: /* fall through */
16529 case 31: /* fall through */
16530 case 32:
16531 *mer = 9;
16532 break;
16533 case 33: /* fall through */
16534 case 34: /* fall through */
16535 case 35: /* fall through */
16536 case 36:
16537 *mer = 8;
16538 break;
16539 case 37: /* fall through */
16540 case 38: /* fall through */
16541 case 39: /* fall through */
16542 case 40:
16543 *mer = 7;
16544 break;
16545 case 41: /* fall through */
16546 case 42: /* fall through */
16547 case 43: /* fall through */
16548 case 44: /* fall through */
16549 case 45:
16550 *mer = 6;
16551 break;
16552 case 46: /* fall through */
16553 case 47: /* fall through */
16554 case 48: /* fall through */
16555 case 49: /* fall through */
16556 case 50: /* fall through */
16557 *mer = 5;
16558 break;
16559 case 51: /* fall through */
16560 case 52: /* fall through */
16561 case 53: /* fall through */
16562 case 54: /* fall through */
16563 case 55: /* fall through */
16564 case 56: /* fall through */
16565 case 57:
16566 *mer = 4;
16567 break;
16568 case 58: /* fall through */
16569 case 59: /* fall through */
16570 case 60: /* fall through */
16571 case 61: /* fall through */
16572 case 62: /* fall through */
16573 case 63:
16574 *mer = 0;
16575 break;
16576 default:
16577 *mer = 0;
16578 break;
16579 }
16580 return 0;
16581rw_error:
16582 return -EIO;
16583}
16584#endif
16585
16586/** 9751/**
16587* \fn int set_orx_nsu_aox() 9752* \fn int set_orx_nsu_aox()
16588* \brief Configure OrxNsuAox for OOB 9753* \brief Configure OrxNsuAox for OOB
@@ -17141,185 +10306,6 @@ rw_error:
17141 return -EIO; 10306 return -EIO;
17142} 10307}
17143 10308
17144#if 0
17145
17146/**
17147* \fn int ctrl_get_oob()
17148* \brief Set modulation standard to be used.
17149* \param demod instance of demodulator
17150* \param oob_status OOB status parameters.
17151* \return int.
17152*/
17153static int
17154ctrl_get_oob(struct drx_demod_instance *demod, struct drxoob_status *oob_status)
17155{
17156 int rc;
17157 struct i2c_device_addr *dev_addr = NULL;
17158 struct drxj_data *ext_attr = NULL;
17159 u16 data = 0;
17160
17161 dev_addr = demod->my_i2c_dev_addr;
17162 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17163
17164 /* check arguments */
17165 if (oob_status == NULL)
17166 return -EINVAL;
17167
17168 if (!ext_attr->oob_power_on)
17169 return -EIO;
17170
17171 rc = drxj_dap_read_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, &data, 0);
17172 if (rc != 0) {
17173 pr_err("error %d\n", rc);
17174 goto rw_error;
17175 }
17176 rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &data, 0);
17177 if (rc != 0) {
17178 pr_err("error %d\n", rc);
17179 goto rw_error;
17180 }
17181 rc = drxj_dap_read_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, &data, 0);
17182 if (rc != 0) {
17183 pr_err("error %d\n", rc);
17184 goto rw_error;
17185 }
17186 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_DGN_KI__A, &data, 0);
17187 if (rc != 0) {
17188 pr_err("error %d\n", rc);
17189 goto rw_error;
17190 }
17191 rc = drxj_dap_read_reg16(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
17192 if (rc != 0) {
17193 pr_err("error %d\n", rc);
17194 goto rw_error;
17195 }
17196
17197 rc = get_oob_lock_status(demod, dev_addr, &oob_status->lock);
17198 if (rc != 0) {
17199 pr_err("error %d\n", rc);
17200 goto rw_error;
17201 }
17202 rc = get_oob_frequency(demod, &oob_status->frequency);
17203 if (rc != 0) {
17204 pr_err("error %d\n", rc);
17205 goto rw_error;
17206 }
17207 rc = get_oobmer(dev_addr, &oob_status->mer);
17208 if (rc != 0) {
17209 pr_err("error %d\n", rc);
17210 goto rw_error;
17211 }
17212 rc = get_oob_symbol_rate_offset(dev_addr, &oob_status->symbol_rate_offset);
17213 if (rc != 0) {
17214 pr_err("error %d\n", rc);
17215 goto rw_error;
17216 }
17217
17218 return 0;
17219rw_error:
17220 return -EIO;
17221}
17222
17223/**
17224* \fn int ctrl_set_cfg_oob_pre_saw()
17225* \brief Configure PreSAW treshold value
17226* \param cfg_data Pointer to configuration parameter
17227* \return Error code
17228*/
17229static int
17230ctrl_set_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17231{
17232 struct i2c_device_addr *dev_addr = NULL;
17233 struct drxj_data *ext_attr = NULL;
17234 int rc;
17235
17236 if (cfg_data == NULL)
17237 return -EINVAL;
17238
17239 dev_addr = demod->my_i2c_dev_addr;
17240 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17241
17242 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, *cfg_data, 0);
17243 if (rc != 0) {
17244 pr_err("error %d\n", rc);
17245 goto rw_error;
17246 }
17247 ext_attr->oob_pre_saw = *cfg_data;
17248 return 0;
17249rw_error:
17250 return -EIO;
17251}
17252
17253/**
17254* \fn int ctrl_get_cfg_oob_pre_saw()
17255* \brief Configure PreSAW treshold value
17256* \param cfg_data Pointer to configuration parameter
17257* \return Error code
17258*/
17259static int
17260ctrl_get_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17261{
17262 struct drxj_data *ext_attr = NULL;
17263
17264 if (cfg_data == NULL)
17265 return -EINVAL;
17266
17267 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17268
17269 *cfg_data = ext_attr->oob_pre_saw;
17270
17271 return 0;
17272}
17273
17274/**
17275* \fn int ctrl_set_cfg_oob_lo_power()
17276* \brief Configure LO Power value
17277* \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17278*/
17279static int
17280ctrl_set_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17281{
17282 struct i2c_device_addr *dev_addr = NULL;
17283 struct drxj_data *ext_attr = NULL;
17284 int rc;
17285
17286 if (cfg_data == NULL)
17287 return -EINVAL;
17288
17289 dev_addr = demod->my_i2c_dev_addr;
17290 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17291
17292 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, *cfg_data, 0);
17293 if (rc != 0) {
17294 pr_err("error %d\n", rc);
17295 goto rw_error;
17296 }
17297 ext_attr->oob_lo_pow = *cfg_data;
17298 return 0;
17299rw_error:
17300 return -EIO;
17301}
17302
17303/**
17304* \fn int ctrl_get_cfg_oob_lo_power()
17305* \brief Configure LO Power value
17306* \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17307*/
17308static int
17309ctrl_get_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17310{
17311 struct drxj_data *ext_attr = NULL;
17312
17313 if (cfg_data == NULL)
17314 return -EINVAL;
17315
17316 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17317
17318 *cfg_data = ext_attr->oob_lo_pow;
17319
17320 return 0;
17321}
17322#endif
17323/*============================================================================*/ 10309/*============================================================================*/
17324/*== END OOB DATAPATH FUNCTIONS ==*/ 10310/*== END OOB DATAPATH FUNCTIONS ==*/
17325/*============================================================================*/ 10311/*============================================================================*/
@@ -17375,15 +10361,6 @@ ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17375 case DRX_STANDARD_ITU_B: 10361 case DRX_STANDARD_ITU_B:
17376 case DRX_STANDARD_ITU_C: 10362 case DRX_STANDARD_ITU_C:
17377#endif /* DRXJ_VSB_ONLY */ 10363#endif /* DRXJ_VSB_ONLY */
17378#if 0
17379 case DRX_STANDARD_NTSC:
17380 case DRX_STANDARD_FM:
17381 case DRX_STANDARD_PAL_SECAM_BG:
17382 case DRX_STANDARD_PAL_SECAM_DK:
17383 case DRX_STANDARD_PAL_SECAM_I:
17384 case DRX_STANDARD_PAL_SECAM_L:
17385 case DRX_STANDARD_PAL_SECAM_LP:
17386#endif
17387 break; 10364 break;
17388 case DRX_STANDARD_UNKNOWN: 10365 case DRX_STANDARD_UNKNOWN:
17389 default: 10366 default:
@@ -17405,37 +10382,6 @@ ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17405 return -EINVAL; 10382 return -EINVAL;
17406 } 10383 }
17407 } 10384 }
17408#if 0
17409 if (standard == DRX_STANDARD_PAL_SECAM_BG) {
17410 switch (channel->bandwidth) {
17411 case DRX_BANDWIDTH_7MHZ: /* fall through */
17412 case DRX_BANDWIDTH_8MHZ:
17413 /* ok */
17414 break;
17415 case DRX_BANDWIDTH_6MHZ: /* fall through */
17416 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17417 default:
17418 return -EINVAL;
17419 }
17420 }
17421 /* check bandwidth PAL/SECAM */
17422 if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
17423 (standard == DRX_STANDARD_PAL_SECAM_DK) ||
17424 (standard == DRX_STANDARD_PAL_SECAM_I) ||
17425 (standard == DRX_STANDARD_PAL_SECAM_L) ||
17426 (standard == DRX_STANDARD_PAL_SECAM_LP)) {
17427 switch (channel->bandwidth) {
17428 case DRX_BANDWIDTH_8MHZ:
17429 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17430 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17431 break;
17432 case DRX_BANDWIDTH_6MHZ: /* fall through */
17433 case DRX_BANDWIDTH_7MHZ: /* fall through */
17434 default:
17435 return -EINVAL;
17436 }
17437 }
17438#endif
17439 10385
17440 /* For QAM annex A and annex C: 10386 /* For QAM annex A and annex C:
17441 -check symbolrate and constellation 10387 -check symbolrate and constellation
@@ -17580,25 +10526,6 @@ ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17580 goto rw_error; 10526 goto rw_error;
17581 } 10527 }
17582 break; 10528 break;
17583#if 0
17584 case DRX_STANDARD_NTSC: /* fallthrough */
17585 case DRX_STANDARD_FM: /* fallthrough */
17586 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17587 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17588 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
17589 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
17590 case DRX_STANDARD_PAL_SECAM_LP:
17591 if (channel->mirror == DRX_MIRROR_AUTO)
17592 ext_attr->mirror = DRX_MIRROR_NO;
17593 else
17594 ext_attr->mirror = channel->mirror;
17595 rc = set_atv_channel(demod, tuner_freq_offset, channel, standard);
17596 if (rc != 0) {
17597 pr_err("error %d\n", rc);
17598 goto rw_error;
17599 }
17600 break;
17601#endif
17602#ifndef DRXJ_VSB_ONLY 10529#ifndef DRXJ_VSB_ONLY
17603 case DRX_STANDARD_ITU_A: /* fallthrough */ 10530 case DRX_STANDARD_ITU_A: /* fallthrough */
17604 case DRX_STANDARD_ITU_B: /* fallthrough */ 10531 case DRX_STANDARD_ITU_B: /* fallthrough */
@@ -17623,215 +10550,6 @@ rw_error:
17623 return -EIO; 10550 return -EIO;
17624} 10551}
17625 10552
17626#if 0
17627/*=============================================================================
17628 ===== ctrl_get_channel() ==========================================================
17629 ===========================================================================*/
17630/**
17631* \fn int ctrl_get_channel()
17632* \brief Retreive parameters of current transmission channel.
17633* \param demod Pointer to demod instance.
17634* \param channel Pointer to channel data.
17635* \return int.
17636*/
17637static int
17638ctrl_get_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17639{
17640 struct i2c_device_addr *dev_addr = NULL;
17641 struct drxj_data *ext_attr = NULL;
17642 int rc;
17643 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17644 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17645 struct drx_common_attr *common_attr = NULL;
17646 s32 intermediate_freq = 0;
17647 s32 ctl_freq_offset = 0;
17648 u32 iqm_rc_rate_lo = 0;
17649 u32 adc_frequency = 0;
17650#ifndef DRXJ_VSB_ONLY
17651 int bandwidth_temp = 0;
17652 int bandwidth = 0;
17653#endif
17654
17655 /* check arguments */
17656 if ((demod == NULL) || (channel == NULL))
17657 return -EINVAL;
17658
17659 dev_addr = demod->my_i2c_dev_addr;
17660 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17661 standard = ext_attr->standard;
17662 common_attr = (struct drx_common_attr *) demod->my_common_attr;
17663
17664 /* initialize channel fields */
17665 channel->mirror = DRX_MIRROR_UNKNOWN;
17666 channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
17667 channel->priority = DRX_PRIORITY_UNKNOWN;
17668 channel->coderate = DRX_CODERATE_UNKNOWN;
17669 channel->guard = DRX_GUARD_UNKNOWN;
17670 channel->fftmode = DRX_FFTMODE_UNKNOWN;
17671 channel->classification = DRX_CLASSIFICATION_UNKNOWN;
17672 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
17673 channel->constellation = DRX_CONSTELLATION_UNKNOWN;
17674 channel->symbolrate = 0;
17675 channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
17676 channel->carrier = DRX_CARRIER_UNKNOWN;
17677 channel->framemode = DRX_FRAMEMODE_UNKNOWN;
17678/* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
17679 channel->ldpc = DRX_LDPC_UNKNOWN;
17680
17681 intermediate_freq = common_attr->intermediate_freq;
17682
17683 /* check lock status */
17684 rc = ctrl_lock_status(demod, &lock_status);
17685 if (rc != 0) {
17686 pr_err("error %d\n", rc);
17687 goto rw_error;
17688 }
17689 if ((lock_status == DRX_LOCKED) || (lock_status == DRXJ_DEMOD_LOCK)) {
17690 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &iqm_rc_rate_lo, 0);
17691 if (rc != 0) {
17692 pr_err("error %d\n", rc);
17693 goto rw_error;
17694 }
17695 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
17696
17697 channel->symbolrate =
17698 frac28(adc_frequency, (iqm_rc_rate_lo + (1 << 23))) >> 7;
17699
17700 switch (standard) {
17701 case DRX_STANDARD_8VSB:
17702 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17703 /* get the channel frequency */
17704 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17705 if (rc != 0) {
17706 pr_err("error %d\n", rc);
17707 goto rw_error;
17708 }
17709 channel->frequency -= ctl_freq_offset;
17710 /* get the channel constellation */
17711 channel->constellation = DRX_CONSTELLATION_AUTO;
17712 break;
17713#ifndef DRXJ_VSB_ONLY
17714 case DRX_STANDARD_ITU_A:
17715 case DRX_STANDARD_ITU_B:
17716 case DRX_STANDARD_ITU_C:
17717 {
17718 /* get the channel frequency */
17719 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17720 if (rc != 0) {
17721 pr_err("error %d\n", rc);
17722 goto rw_error;
17723 }
17724 channel->frequency -= ctl_freq_offset;
17725
17726 if (standard == DRX_STANDARD_ITU_B) {
17727 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17728 } else {
17729 /* annex A & C */
17730
17731 u32 roll_off = 113; /* default annex C */
17732
17733 if (standard == DRX_STANDARD_ITU_A)
17734 roll_off = 115;
17735
17736 bandwidth_temp =
17737 channel->symbolrate * roll_off;
17738 bandwidth = bandwidth_temp / 100;
17739
17740 if ((bandwidth_temp % 100) >= 50)
17741 bandwidth++;
17742
17743 if (bandwidth <= 6000000) {
17744 channel->bandwidth =
17745 DRX_BANDWIDTH_6MHZ;
17746 } else if ((bandwidth > 6000000)
17747 && (bandwidth <= 7000000)) {
17748 channel->bandwidth =
17749 DRX_BANDWIDTH_7MHZ;
17750 } else if (bandwidth > 7000000) {
17751 channel->bandwidth =
17752 DRX_BANDWIDTH_8MHZ;
17753 }
17754 } /* if (standard == DRX_STANDARD_ITU_B) */
17755
17756 {
17757 struct drxjscu_cmd cmd_scu = { 0, 0, 0, NULL, NULL };
17758 u16 cmd_result[3] = { 0, 0, 0 };
17759
17760 cmd_scu.command =
17761 SCU_RAM_COMMAND_STANDARD_QAM |
17762 SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
17763 cmd_scu.parameter_len = 0;
17764 cmd_scu.result_len = 3;
17765 cmd_scu.parameter = NULL;
17766 cmd_scu.result = cmd_result;
17767 rc = scu_command(dev_addr, &cmd_scu);
17768 if (rc != 0) {
17769 pr_err("error %d\n", rc);
17770 goto rw_error;
17771 }
17772
17773 channel->interleavemode =
17774 (enum drx_interleave_mode) (cmd_scu.
17775 result[2]);
17776 }
17777
17778 switch (ext_attr->constellation) {
17779 case DRX_CONSTELLATION_QAM256:
17780 channel->constellation =
17781 DRX_CONSTELLATION_QAM256;
17782 break;
17783 case DRX_CONSTELLATION_QAM128:
17784 channel->constellation =
17785 DRX_CONSTELLATION_QAM128;
17786 break;
17787 case DRX_CONSTELLATION_QAM64:
17788 channel->constellation =
17789 DRX_CONSTELLATION_QAM64;
17790 break;
17791 case DRX_CONSTELLATION_QAM32:
17792 channel->constellation =
17793 DRX_CONSTELLATION_QAM32;
17794 break;
17795 case DRX_CONSTELLATION_QAM16:
17796 channel->constellation =
17797 DRX_CONSTELLATION_QAM16;
17798 break;
17799 default:
17800 channel->constellation =
17801 DRX_CONSTELLATION_UNKNOWN;
17802 return -EIO;
17803 }
17804 }
17805 break;
17806#endif
17807 case DRX_STANDARD_NTSC: /* fall trough */
17808 case DRX_STANDARD_PAL_SECAM_BG:
17809 case DRX_STANDARD_PAL_SECAM_DK:
17810 case DRX_STANDARD_PAL_SECAM_I:
17811 case DRX_STANDARD_PAL_SECAM_L:
17812 case DRX_STANDARD_PAL_SECAM_LP:
17813 case DRX_STANDARD_FM:
17814 rc = get_atv_channel(demod, channel, standard);
17815 if (rc != 0) {
17816 pr_err("error %d\n", rc);
17817 goto rw_error;
17818 }
17819 break;
17820 case DRX_STANDARD_UNKNOWN: /* fall trough */
17821 default:
17822 return -EIO;
17823 } /* switch ( standard ) */
17824
17825 if (lock_status == DRX_LOCKED)
17826 channel->mirror = ext_attr->mirror;
17827 }
17828 /* if ( lock_status == DRX_LOCKED ) */
17829 return 0;
17830rw_error:
17831 return -EIO;
17832}
17833#endif
17834
17835/*============================================================================= 10553/*=============================================================================
17836 ===== SigQuality() ========================================================== 10554 ===== SigQuality() ==========================================================
17837 ===========================================================================*/ 10555 ===========================================================================*/
@@ -17996,27 +10714,6 @@ ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_q
17996 max_mer); 10714 max_mer);
17997 break; 10715 break;
17998#endif 10716#endif
17999#if 0
18000 case DRX_STANDARD_PAL_SECAM_BG:
18001 case DRX_STANDARD_PAL_SECAM_DK:
18002 case DRX_STANDARD_PAL_SECAM_I:
18003 case DRX_STANDARD_PAL_SECAM_L:
18004 case DRX_STANDARD_PAL_SECAM_LP:
18005 case DRX_STANDARD_NTSC:
18006 rc = atv_sig_quality(demod, sig_quality);
18007 if (rc != 0) {
18008 pr_err("error %d\n", rc);
18009 goto rw_error;
18010 }
18011 break;
18012 case DRX_STANDARD_FM:
18013 rc = fm_sig_quality(demod, sig_quality);
18014 if (rc != 0) {
18015 pr_err("error %d\n", rc);
18016 goto rw_error;
18017 }
18018 break;
18019#endif
18020 default: 10717 default:
18021 return -EIO; 10718 return -EIO;
18022 } 10719 }
@@ -18077,19 +10774,6 @@ ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_st
18077 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK; 10774 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18078 break; 10775 break;
18079#endif 10776#endif
18080#if 0
18081 case DRX_STANDARD_NTSC:
18082 case DRX_STANDARD_PAL_SECAM_BG:
18083 case DRX_STANDARD_PAL_SECAM_DK:
18084 case DRX_STANDARD_PAL_SECAM_I:
18085 case DRX_STANDARD_PAL_SECAM_L:
18086 case DRX_STANDARD_PAL_SECAM_LP:
18087 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
18088 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18089 break;
18090 case DRX_STANDARD_FM:
18091 return fm_lock_status(demod, lock_stat);
18092#endif
18093 case DRX_STANDARD_UNKNOWN: /* fallthrough */ 10777 case DRX_STANDARD_UNKNOWN: /* fallthrough */
18094 default: 10778 default:
18095 return -EIO; 10779 return -EIO;
@@ -18129,62 +10813,6 @@ rw_error:
18129 10813
18130/*============================================================================*/ 10814/*============================================================================*/
18131 10815
18132#if 0
18133/**
18134* \fn int ctrl_constel()
18135* \brief Retreive a constellation point via I2C.
18136* \param demod Pointer to demodulator instance.
18137* \param complex_nr Pointer to the structure in which to store the
18138 constellation point.
18139* \return int.
18140*/
18141static int
18142ctrl_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
18143{
18144 int rc;
18145 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18146 /**< active standard */
18147
18148 /* check arguments */
18149 if ((demod == NULL) || (complex_nr == NULL))
18150 return -EINVAL;
18151
18152 /* read device info */
18153 standard = ((struct drxj_data *) demod->my_ext_attr)->standard;
18154
18155 /* Read constellation point */
18156 switch (standard) {
18157 case DRX_STANDARD_8VSB:
18158 rc = ctrl_get_vsb_constel(demod, complex_nr);
18159 if (rc != 0) {
18160 pr_err("error %d\n", rc);
18161 goto rw_error;
18162 }
18163 break;
18164#ifndef DRXJ_VSB_ONLY
18165 case DRX_STANDARD_ITU_A: /* fallthrough */
18166 case DRX_STANDARD_ITU_B: /* fallthrough */
18167 case DRX_STANDARD_ITU_C:
18168 rc = ctrl_get_qam_constel(demod, complex_nr);
18169 if (rc != 0) {
18170 pr_err("error %d\n", rc);
18171 goto rw_error;
18172 }
18173 break;
18174#endif
18175 case DRX_STANDARD_UNKNOWN:
18176 default:
18177 return -EIO;
18178 }
18179
18180 return 0;
18181rw_error:
18182 return -EIO;
18183}
18184#endif
18185
18186/*============================================================================*/
18187
18188/** 10816/**
18189* \fn int ctrl_set_standard() 10817* \fn int ctrl_set_standard()
18190* \brief Set modulation standard to be used. 10818* \brief Set modulation standard to be used.
@@ -18231,21 +10859,6 @@ ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18231 goto rw_error; 10859 goto rw_error;
18232 } 10860 }
18233 break; 10861 break;
18234#if 0
18235 case DRX_STANDARD_NTSC: /* fallthrough */
18236 case DRX_STANDARD_FM: /* fallthrough */
18237 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18238 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18239 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18240 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18241 case DRX_STANDARD_PAL_SECAM_LP:
18242 rc = power_down_atv(demod, prev_standard, false);
18243 if (rc != 0) {
18244 pr_err("error %d\n", rc);
18245 goto rw_error;
18246 }
18247 break;
18248#endif
18249 case DRX_STANDARD_UNKNOWN: 10862 case DRX_STANDARD_UNKNOWN:
18250 /* Do nothing */ 10863 /* Do nothing */
18251 break; 10864 break;
@@ -18282,26 +10895,6 @@ ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18282 goto rw_error; 10895 goto rw_error;
18283 } 10896 }
18284 break; 10897 break;
18285#if 0
18286 case DRX_STANDARD_NTSC: /* fallthrough */
18287 case DRX_STANDARD_FM: /* fallthrough */
18288 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18289 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18290 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18291 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18292 case DRX_STANDARD_PAL_SECAM_LP:
18293 rc = set_atv_standard(demod, standard);
18294 if (rc != 0) {
18295 pr_err("error %d\n", rc);
18296 goto rw_error;
18297 }
18298 rc = power_up_atv(demod, *standard);
18299 if (rc != 0) {
18300 pr_err("error %d\n", rc);
18301 goto rw_error;
18302 }
18303 break;
18304#endif
18305 default: 10898 default:
18306 ext_attr->standard = DRX_STANDARD_UNKNOWN; 10899 ext_attr->standard = DRX_STANDARD_UNKNOWN;
18307 return -EINVAL; 10900 return -EINVAL;
@@ -18315,92 +10908,6 @@ rw_error:
18315 return -EIO; 10908 return -EIO;
18316} 10909}
18317 10910
18318#if 0
18319/*============================================================================*/
18320
18321/**
18322* \fn int ctrl_get_standard()
18323* \brief Get modulation standard currently used to demodulate.
18324* \param standard Modulation standard.
18325* \return int.
18326*
18327* Returns 8VSB, NTSC, QAM only.
18328*
18329*/
18330static int
18331ctrl_get_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18332{
18333 struct drxj_data *ext_attr = NULL;
18334 int rc;
18335 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18336
18337 /* check arguments */
18338 if (standard == NULL)
18339 return -EINVAL;
18340
18341 *standard = ext_attr->standard;
18342 do {
18343 u16 dummy;
18344 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18345 if (rc != 0) {
18346 pr_err("error %d\n", rc);
18347 goto rw_error;
18348 }
18349 } while (0);
18350
18351 return 0;
18352rw_error:
18353 return -EIO;
18354}
18355
18356/*============================================================================*/
18357
18358/**
18359* \fn int ctrl_get_cfg_symbol_clock_offset()
18360* \brief Get frequency offsets of STR.
18361* \param pointer to s32.
18362* \return int.
18363*
18364*/
18365static int
18366ctrl_get_cfg_symbol_clock_offset(struct drx_demod_instance *demod, s32 *rate_offset)
18367{
18368 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18369 int rc;
18370 struct drxj_data *ext_attr = NULL;
18371
18372 /* check arguments */
18373 if (rate_offset == NULL)
18374 return -EINVAL;
18375
18376 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18377 standard = ext_attr->standard;
18378
18379 switch (standard) {
18380 case DRX_STANDARD_8VSB: /* fallthrough */
18381#ifndef DRXJ_VSB_ONLY
18382 case DRX_STANDARD_ITU_A: /* fallthrough */
18383 case DRX_STANDARD_ITU_B: /* fallthrough */
18384 case DRX_STANDARD_ITU_C:
18385#endif
18386 rc = get_str_freq_offset(demod, rate_offset);
18387 if (rc != 0) {
18388 pr_err("error %d\n", rc);
18389 goto rw_error;
18390 }
18391 break;
18392 case DRX_STANDARD_NTSC:
18393 case DRX_STANDARD_UNKNOWN:
18394 default:
18395 return -EINVAL;
18396 }
18397
18398 return 0;
18399rw_error:
18400 return -EIO;
18401}
18402#endif
18403
18404/*============================================================================*/ 10911/*============================================================================*/
18405 10912
18406static void drxj_reset_mode(struct drxj_data *ext_attr) 10913static void drxj_reset_mode(struct drxj_data *ext_attr)
@@ -18460,22 +10967,6 @@ static void drxj_reset_mode(struct drxj_data *ext_attr)
18460 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB; 10967 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
18461 ext_attr->vsb_pre_saw_cfg.reference = 0x07; 10968 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
18462 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true; 10969 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
18463
18464#if 0
18465 /* Initialize default AFE configuartion for ATV */
18466 ext_attr->atv_rf_agc_cfg.standard = DRX_STANDARD_NTSC;
18467 ext_attr->atv_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18468 ext_attr->atv_rf_agc_cfg.top = 9500;
18469 ext_attr->atv_rf_agc_cfg.cut_off_current = 4000;
18470 ext_attr->atv_rf_agc_cfg.speed = 3;
18471 ext_attr->atv_if_agc_cfg.standard = DRX_STANDARD_NTSC;
18472 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18473 ext_attr->atv_if_agc_cfg.speed = 3;
18474 ext_attr->atv_if_agc_cfg.top = 2400;
18475 ext_attr->atv_pre_saw_cfg.reference = 0x0007;
18476 ext_attr->atv_pre_saw_cfg.use_pre_saw = true;
18477 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
18478#endif
18479} 10970}
18480 10971
18481/** 10972/**
@@ -18633,590 +11124,10 @@ rw_error:
18633 return rc; 11124 return rc;
18634} 11125}
18635 11126
18636#if 0
18637/*============================================================================*/
18638
18639/**
18640* \fn int ctrl_probe_device()
18641* \brief Probe device, check if it is present
18642* \param demod Pointer to demodulator instance.
18643* \return int.
18644* \retval 0 a drx39xxj device has been detected.
18645* \retval -EIO no drx39xxj device detected.
18646*
18647* This funtion can be caled before open() and after close().
18648*
18649*/
18650
18651static int ctrl_probe_device(struct drx_demod_instance *demod)
18652{
18653 enum drx_power_mode org_power_mode = DRX_POWER_UP;
18654 int ret_status = 0;
18655 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18656 int rc;
18657
18658 common_attr = (struct drx_common_attr *) demod->my_common_attr;
18659
18660 if (common_attr->is_opened == false
18661 || common_attr->current_power_mode != DRX_POWER_UP) {
18662 struct i2c_device_addr *dev_addr = NULL;
18663 enum drx_power_mode power_mode = DRX_POWER_UP;
18664 u32 jtag = 0;
18665
18666 dev_addr = demod->my_i2c_dev_addr;
18667
18668 /* Remeber original power mode */
18669 org_power_mode = common_attr->current_power_mode;
18670
18671 if (demod->my_common_attr->is_opened == false) {
18672 rc = power_up_device(demod);
18673 if (rc != 0) {
18674 pr_err("error %d\n", rc);
18675 goto rw_error;
18676 }
18677 common_attr->current_power_mode = DRX_POWER_UP;
18678 } else {
18679 /* Wake-up device, feedback from device */
18680 rc = ctrl_power_mode(demod, &power_mode);
18681 if (rc != 0) {
18682 pr_err("error %d\n", rc);
18683 goto rw_error;
18684 }
18685 }
18686 /* Initialize HI, wakeup key especially */
18687 rc = init_hi(demod);
18688 if (rc != 0) {
18689 pr_err("error %d\n", rc);
18690 goto rw_error;
18691 }
18692
18693 /* Check device id */
18694 rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18695 if (rc != 0) {
18696 pr_err("error %d\n", rc);
18697 goto rw_error;
18698 }
18699 jtag = (jtag >> 12) & 0xFFFF;
18700 switch (jtag) {
18701 case 0x3931: /* fallthrough */
18702 case 0x3932: /* fallthrough */
18703 case 0x3933: /* fallthrough */
18704 case 0x3934: /* fallthrough */
18705 case 0x3941: /* fallthrough */
18706 case 0x3942: /* fallthrough */
18707 case 0x3943: /* fallthrough */
18708 case 0x3944: /* fallthrough */
18709 case 0x3945: /* fallthrough */
18710 case 0x3946:
18711 /* ok , do nothing */
18712 break;
18713 default:
18714 ret_status = -EIO;
18715 break;
18716 }
18717
18718 /* Device was not opened, return to orginal powermode,
18719 feedback from device */
18720 rc = ctrl_power_mode(demod, &org_power_mode);
18721 if (rc != 0) {
18722 pr_err("error %d\n", rc);
18723 goto rw_error;
18724 }
18725 } else {
18726 /* dummy read to make this function fail in case device
18727 suddenly disappears after a succesful drx_open */
18728 do {
18729 u16 dummy;
18730 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18731 if (rc != 0) {
18732 pr_err("error %d\n", rc);
18733 goto rw_error;
18734 }
18735 } while (0);
18736 }
18737
18738 return ret_status;
18739
18740rw_error:
18741 common_attr->current_power_mode = org_power_mode;
18742 return -EIO;
18743}
18744#endif
18745
18746/*============================================================================*/ 11127/*============================================================================*/
18747/*== CTRL Set/Get Config related functions ===================================*/ 11128/*== CTRL Set/Get Config related functions ===================================*/
18748/*============================================================================*/ 11129/*============================================================================*/
18749 11130
18750#if 0
18751/*===== SigStrength() =========================================================*/
18752/**
18753* \fn int ctrl_sig_strength()
18754* \brief Retrieve signal strength.
18755* \param devmod Pointer to demodulator instance.
18756* \param sig_quality Pointer to signal strength data; range 0, .. , 100.
18757* \return int.
18758* \retval 0 sig_strength contains valid data.
18759* \retval -EINVAL sig_strength is NULL.
18760* \retval -EIO Erroneous data, sig_strength contains invalid data.
18761
18762*/
18763static int
18764ctrl_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
18765{
18766 struct drxj_data *ext_attr = NULL;
18767 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18768 int rc;
18769
18770 /* Check arguments */
18771 if ((sig_strength == NULL) || (demod == NULL))
18772 return -EINVAL;
18773
18774 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18775 standard = ext_attr->standard;
18776 *sig_strength = 0;
18777
18778 /* Signal strength indication for each standard */
18779 switch (standard) {
18780 case DRX_STANDARD_8VSB: /* fallthrough */
18781#ifndef DRXJ_VSB_ONLY
18782 case DRX_STANDARD_ITU_A: /* fallthrough */
18783 case DRX_STANDARD_ITU_B: /* fallthrough */
18784 case DRX_STANDARD_ITU_C:
18785#endif
18786 rc = get_sig_strength(demod, sig_strength);
18787 if (rc != 0) {
18788 pr_err("error %d\n", rc);
18789 goto rw_error;
18790 }
18791 break;
18792 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18793 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18794 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18795 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18796 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
18797 case DRX_STANDARD_NTSC: /* fallthrough */
18798 case DRX_STANDARD_FM:
18799 rc = get_atv_sig_strength(demod, sig_strength);
18800 if (rc != 0) {
18801 pr_err("error %d\n", rc);
18802 goto rw_error;
18803 }
18804 break;
18805 case DRX_STANDARD_UNKNOWN: /* fallthrough */
18806 default:
18807 return -EINVAL;
18808 }
18809
18810 /* TODO */
18811 /* find out if signal strength is calculated in the same way for all standards */
18812 return 0;
18813rw_error:
18814 return -EIO;
18815}
18816
18817/*============================================================================*/
18818/**
18819* \fn int ctrl_get_cfg_oob_misc()
18820* \brief Get current state information of OOB.
18821* \param pointer to struct drxj_cfg_oob_misc.
18822* \return int.
18823*
18824*/
18825static int
18826ctrl_get_cfg_oob_misc(struct drx_demod_instance *demod, struct drxj_cfg_oob_misc *misc)
18827{
18828 struct i2c_device_addr *dev_addr = NULL;
18829 int rc;
18830 u16 lock = 0U;
18831 u16 state = 0U;
18832 u16 data = 0U;
18833 u16 digital_agc_mant = 0U;
18834 u16 digital_agc_exp = 0U;
18835
18836 /* check arguments */
18837 if (misc == NULL)
18838 return -EINVAL;
18839
18840 dev_addr = demod->my_i2c_dev_addr;
18841
18842 /* TODO */
18843 /* check if the same registers are used for all standards (QAM/VSB/ATV) */
18844 rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC, 0);
18845 if (rc != 0) {
18846 pr_err("error %d\n", rc);
18847 goto rw_error;
18848 }
18849 rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC, 0);
18850 if (rc != 0) {
18851 pr_err("error %d\n", rc);
18852 goto rw_error;
18853 }
18854 rc = drxj_dap_read_reg16(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
18855 if (rc != 0) {
18856 pr_err("error %d\n", rc);
18857 goto rw_error;
18858 }
18859
18860 digital_agc_mant = data & ORX_FWP_SRC_DGN_W_MANT__M;
18861 digital_agc_exp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
18862 >> ORX_FWP_SRC_DGN_W_EXP__B;
18863 misc->agc.digital_agc = digital_agc_mant << digital_agc_exp;
18864
18865 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_LOCK__A, &lock, 0);
18866 if (rc != 0) {
18867 pr_err("error %d\n", rc);
18868 goto rw_error;
18869 }
18870
18871 misc->ana_gain_lock = ((lock & 0x0001) ? true : false);
18872 misc->dig_gain_lock = ((lock & 0x0002) ? true : false);
18873 misc->freq_lock = ((lock & 0x0004) ? true : false);
18874 misc->phase_lock = ((lock & 0x0008) ? true : false);
18875 misc->sym_timing_lock = ((lock & 0x0010) ? true : false);
18876 misc->eq_lock = ((lock & 0x0020) ? true : false);
18877
18878 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_STATE__A, &state, 0);
18879 if (rc != 0) {
18880 pr_err("error %d\n", rc);
18881 goto rw_error;
18882 }
18883 misc->state = (state >> 8) & 0xff;
18884
18885 return 0;
18886rw_error:
18887 return -EIO;
18888}
18889
18890/**
18891* \fn int ctrl_get_cfg_vsb_misc()
18892* \brief Get current state information of OOB.
18893* \param pointer to struct drxj_cfg_oob_misc.
18894* \return int.
18895*
18896*/
18897static int
18898ctrl_get_cfg_vsb_misc(struct drx_demod_instance *demod, struct drxj_cfg_vsb_misc *misc)
18899{
18900 struct i2c_device_addr *dev_addr = NULL;
18901 int rc;
18902
18903 /* check arguments */
18904 if (misc == NULL)
18905 return -EINVAL;
18906
18907 dev_addr = demod->my_i2c_dev_addr;
18908
18909 rc = get_vsb_symb_err(dev_addr, &misc->symb_error);
18910 if (rc != 0) {
18911 pr_err("error %d\n", rc);
18912 goto rw_error;
18913 }
18914
18915 return 0;
18916rw_error:
18917 return -EIO;
18918}
18919
18920/*============================================================================*/
18921
18922/**
18923* \fn int ctrl_set_cfg_agc_if()
18924* \brief Set IF AGC.
18925* \param demod demod instance
18926* \param agc_settings If agc configuration
18927* \return int.
18928*
18929* Check arguments
18930* Dispatch handling to standard specific function.
18931*
18932*/
18933static int
18934ctrl_set_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
18935{
18936 /* check arguments */
18937 if (agc_settings == NULL)
18938 return -EINVAL;
18939
18940 switch (agc_settings->ctrl_mode) {
18941 case DRX_AGC_CTRL_AUTO: /* fallthrough */
18942 case DRX_AGC_CTRL_USER: /* fallthrough */
18943 case DRX_AGC_CTRL_OFF: /* fallthrough */
18944 break;
18945 default:
18946 return -EINVAL;
18947 }
18948
18949 /* Distpatch */
18950 switch (agc_settings->standard) {
18951 case DRX_STANDARD_8VSB: /* fallthrough */
18952#ifndef DRXJ_VSB_ONLY
18953 case DRX_STANDARD_ITU_A: /* fallthrough */
18954 case DRX_STANDARD_ITU_B: /* fallthrough */
18955 case DRX_STANDARD_ITU_C:
18956#endif
18957#if 0
18958 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18959 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18960 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18961 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18962 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
18963 case DRX_STANDARD_NTSC: /* fallthrough */
18964 case DRX_STANDARD_FM:
18965#endif
18966 return set_agc_if(demod, agc_settings, true);
18967 case DRX_STANDARD_UNKNOWN:
18968 default:
18969 return -EINVAL;
18970 }
18971
18972 return 0;
18973}
18974
18975/*============================================================================*/
18976
18977/**
18978* \fn int ctrl_get_cfg_agc_if()
18979* \brief Retrieve IF AGC settings.
18980* \param demod demod instance
18981* \param agc_settings If agc configuration
18982* \return int.
18983*
18984* Check arguments
18985* Dispatch handling to standard specific function.
18986*
18987*/
18988static int
18989ctrl_get_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
18990{
18991 /* check arguments */
18992 if (agc_settings == NULL)
18993 return -EINVAL;
18994
18995 /* Distpatch */
18996 switch (agc_settings->standard) {
18997 case DRX_STANDARD_8VSB: /* fallthrough */
18998#ifndef DRXJ_VSB_ONLY
18999 case DRX_STANDARD_ITU_A: /* fallthrough */
19000 case DRX_STANDARD_ITU_B: /* fallthrough */
19001 case DRX_STANDARD_ITU_C:
19002#endif
19003#if 0
19004 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19005 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19006 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19007 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19008 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19009 case DRX_STANDARD_NTSC: /* fallthrough */
19010 case DRX_STANDARD_FM:
19011#endif
19012 return get_agc_if(demod, agc_settings);
19013 case DRX_STANDARD_UNKNOWN:
19014 default:
19015 return -EINVAL;
19016 }
19017
19018 return 0;
19019}
19020
19021/*============================================================================*/
19022
19023/**
19024* \fn int ctrl_set_cfg_agc_rf()
19025* \brief Set RF AGC.
19026* \param demod demod instance
19027* \param agc_settings rf agc configuration
19028* \return int.
19029*
19030* Check arguments
19031* Dispatch handling to standard specific function.
19032*
19033*/
19034static int
19035ctrl_set_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19036{
19037 /* check arguments */
19038 if (agc_settings == NULL)
19039 return -EINVAL;
19040
19041 switch (agc_settings->ctrl_mode) {
19042 case DRX_AGC_CTRL_AUTO: /* fallthrough */
19043 case DRX_AGC_CTRL_USER: /* fallthrough */
19044 case DRX_AGC_CTRL_OFF:
19045 break;
19046 default:
19047 return -EINVAL;
19048 }
19049
19050 /* Distpatch */
19051 switch (agc_settings->standard) {
19052 case DRX_STANDARD_8VSB: /* fallthrough */
19053#ifndef DRXJ_VSB_ONLY
19054 case DRX_STANDARD_ITU_A: /* fallthrough */
19055 case DRX_STANDARD_ITU_B: /* fallthrough */
19056 case DRX_STANDARD_ITU_C:
19057#endif
19058 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19059 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19060 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19061 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19062 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19063 case DRX_STANDARD_NTSC: /* fallthrough */
19064 case DRX_STANDARD_FM:
19065 return set_agc_rf(demod, agc_settings, true);
19066 case DRX_STANDARD_UNKNOWN:
19067 default:
19068 return -EINVAL;
19069 }
19070
19071 return 0;
19072}
19073
19074/*============================================================================*/
19075
19076/**
19077* \fn int ctrl_get_cfg_agc_rf()
19078* \brief Retrieve RF AGC settings.
19079* \param demod demod instance
19080* \param agc_settings Rf agc configuration
19081* \return int.
19082*
19083* Check arguments
19084* Dispatch handling to standard specific function.
19085*
19086*/
19087static int
19088ctrl_get_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19089{
19090 /* check arguments */
19091 if (agc_settings == NULL)
19092 return -EINVAL;
19093
19094 /* Distpatch */
19095 switch (agc_settings->standard) {
19096 case DRX_STANDARD_8VSB: /* fallthrough */
19097#ifndef DRXJ_VSB_ONLY
19098 case DRX_STANDARD_ITU_A: /* fallthrough */
19099 case DRX_STANDARD_ITU_B: /* fallthrough */
19100 case DRX_STANDARD_ITU_C:
19101#endif
19102 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19103 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19104 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19105 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19106 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19107 case DRX_STANDARD_NTSC: /* fallthrough */
19108 case DRX_STANDARD_FM:
19109 return get_agc_rf(demod, agc_settings);
19110 case DRX_STANDARD_UNKNOWN:
19111 default:
19112 return -EINVAL;
19113 }
19114
19115 return 0;
19116}
19117
19118/*============================================================================*/
19119
19120/**
19121* \fn int ctrl_get_cfg_agc_internal()
19122* \brief Retrieve internal AGC value.
19123* \param demod demod instance
19124* \param u16
19125* \return int.
19126*
19127* Check arguments
19128* Dispatch handling to standard specific function.
19129*
19130*/
19131static int
19132ctrl_get_cfg_agc_internal(struct drx_demod_instance *demod, u16 *agc_internal)
19133{
19134 struct i2c_device_addr *dev_addr = NULL;
19135 int rc;
19136 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
19137 struct drxj_data *ext_attr = NULL;
19138 u16 iqm_cf_scale_sh = 0;
19139 u16 iqm_cf_power = 0;
19140 u16 iqm_cf_amp = 0;
19141 u16 iqm_cf_gain = 0;
19142
19143 /* check arguments */
19144 if (agc_internal == NULL)
19145 return -EINVAL;
19146 dev_addr = demod->my_i2c_dev_addr;
19147 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19148
19149 rc = ctrl_lock_status(demod, &lock_status);
19150 if (rc != 0) {
19151 pr_err("error %d\n", rc);
19152 goto rw_error;
19153 }
19154 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
19155 *agc_internal = 0;
19156 return 0;
19157 }
19158
19159 /* Distpatch */
19160 switch (ext_attr->standard) {
19161 case DRX_STANDARD_8VSB:
19162 iqm_cf_gain = 57;
19163 break;
19164#ifndef DRXJ_VSB_ONLY
19165 case DRX_STANDARD_ITU_A:
19166 case DRX_STANDARD_ITU_B:
19167 case DRX_STANDARD_ITU_C:
19168 switch (ext_attr->constellation) {
19169 case DRX_CONSTELLATION_QAM256:
19170 case DRX_CONSTELLATION_QAM128:
19171 case DRX_CONSTELLATION_QAM32:
19172 case DRX_CONSTELLATION_QAM16:
19173 iqm_cf_gain = 57;
19174 break;
19175 case DRX_CONSTELLATION_QAM64:
19176 iqm_cf_gain = 56;
19177 break;
19178 default:
19179 return -EIO;
19180 }
19181 break;
19182#endif
19183 default:
19184 return -EINVAL;
19185 }
19186
19187 rc = drxj_dap_read_reg16(dev_addr, IQM_CF_POW__A, &iqm_cf_power, 0);
19188 if (rc != 0) {
19189 pr_err("error %d\n", rc);
19190 goto rw_error;
19191 }
19192 rc = drxj_dap_read_reg16(dev_addr, IQM_CF_SCALE_SH__A, &iqm_cf_scale_sh, 0);
19193 if (rc != 0) {
19194 pr_err("error %d\n", rc);
19195 goto rw_error;
19196 }
19197 rc = drxj_dap_read_reg16(dev_addr, IQM_CF_AMP__A, &iqm_cf_amp, 0);
19198 if (rc != 0) {
19199 pr_err("error %d\n", rc);
19200 goto rw_error;
19201 }
19202 /* IQM_CF_PWR_CORRECTION_dB = 3;
19203 P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
19204 /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
19205 -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
19206 +6*7+10*log10(1+0.115/4); */
19207 /* PadcdB = P4dB +3 -6 +60; dBmV */
19208 *agc_internal = (u16) (log1_times100(iqm_cf_power)
19209 - 2 * log1_times100(iqm_cf_amp)
19210 - iqm_cf_gain - 120 * iqm_cf_scale_sh + 781);
19211
19212 return 0;
19213rw_error:
19214 return -EIO;
19215}
19216
19217/*============================================================================*/
19218#endif
19219
19220/** 11131/**
19221* \fn int ctrl_set_cfg_pre_saw() 11132* \fn int ctrl_set_cfg_pre_saw()
19222* \brief Set Pre-saw reference. 11133* \brief Set Pre-saw reference.
@@ -19269,17 +11180,6 @@ ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *
19269 ext_attr->qam_pre_saw_cfg = *pre_saw; 11180 ext_attr->qam_pre_saw_cfg = *pre_saw;
19270 break; 11181 break;
19271#endif 11182#endif
19272#if 0
19273 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19274 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19275 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19276 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19277 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19278 case DRX_STANDARD_NTSC: /* fallthrough */
19279 case DRX_STANDARD_FM:
19280 ext_attr->atv_pre_saw_cfg = *pre_saw;
19281 break;
19282#endif
19283 default: 11183 default:
19284 return -EINVAL; 11184 return -EINVAL;
19285 } 11185 }
@@ -19372,419 +11272,6 @@ rw_error:
19372 11272
19373/*============================================================================*/ 11273/*============================================================================*/
19374 11274
19375#if 0
19376/**
19377* \fn int ctrl_get_cfg_pre_saw()
19378* \brief Get Pre-saw reference setting.
19379* \param demod demod instance
19380* \param u16 *
19381* \return int.
19382*
19383* Check arguments
19384* Dispatch handling to standard specific function.
19385*
19386*/
19387static int
19388ctrl_get_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19389{
19390 struct drxj_data *ext_attr = NULL;
19391
19392 /* check arguments */
19393 if (pre_saw == NULL)
19394 return -EINVAL;
19395
19396 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19397
19398 switch (pre_saw->standard) {
19399 case DRX_STANDARD_8VSB:
19400 *pre_saw = ext_attr->vsb_pre_saw_cfg;
19401 break;
19402#ifndef DRXJ_VSB_ONLY
19403 case DRX_STANDARD_ITU_A: /* fallthrough */
19404 case DRX_STANDARD_ITU_B: /* fallthrough */
19405 case DRX_STANDARD_ITU_C:
19406 *pre_saw = ext_attr->qam_pre_saw_cfg;
19407 break;
19408#endif
19409 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19410 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19411 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19412 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19413 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19414 case DRX_STANDARD_NTSC:
19415 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
19416 *pre_saw = ext_attr->atv_pre_saw_cfg;
19417 break;
19418 case DRX_STANDARD_FM:
19419 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_FM;
19420 *pre_saw = ext_attr->atv_pre_saw_cfg;
19421 break;
19422
19423 default:
19424 return -EINVAL;
19425 }
19426
19427 return 0;
19428}
19429
19430/*============================================================================*/
19431
19432/**
19433* \fn int ctrl_get_cfg_afe_gain()
19434* \brief Get AFE Gain.
19435* \param demod demod instance
19436* \param u16 *
19437* \return int.
19438*
19439* Check arguments
19440* Dispatch handling to standard specific function.
19441*
19442*/
19443static int
19444ctrl_get_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19445{
19446 struct drxj_data *ext_attr = NULL;
19447
19448 /* check arguments */
19449 if (afe_gain == NULL)
19450 return -EINVAL;
19451
19452 ext_attr = demod->my_ext_attr;
19453
19454 switch (afe_gain->standard) {
19455 case DRX_STANDARD_8VSB:
19456 afe_gain->gain = ext_attr->vsb_pga_cfg;
19457 break;
19458#ifndef DRXJ_VSB_ONLY
19459 case DRX_STANDARD_ITU_A: /* fallthrough */
19460 case DRX_STANDARD_ITU_B: /* fallthrough */
19461 case DRX_STANDARD_ITU_C:
19462 afe_gain->gain = ext_attr->qam_pga_cfg;
19463 break;
19464#endif
19465 default:
19466 return -EINVAL;
19467 }
19468
19469 return 0;
19470}
19471
19472/*============================================================================*/
19473
19474/**
19475* \fn int ctrl_get_fec_meas_seq_count()
19476* \brief Get FEC measurement sequnce number.
19477* \param demod demod instance
19478* \param u16 *
19479* \return int.
19480*
19481* Check arguments
19482* Dispatch handling to standard specific function.
19483*
19484*/
19485static int
19486ctrl_get_fec_meas_seq_count(struct drx_demod_instance *demod, u16 *fec_meas_seq_count)
19487{
19488 int rc;
19489 /* check arguments */
19490 if (fec_meas_seq_count == NULL)
19491 return -EINVAL;
19492
19493 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, fec_meas_seq_count, 0);
19494 if (rc != 0) {
19495 pr_err("error %d\n", rc);
19496 goto rw_error;
19497 }
19498
19499 return 0;
19500rw_error:
19501 return -EIO;
19502}
19503
19504/*============================================================================*/
19505
19506/**
19507* \fn int ctrl_get_accum_cr_rs_cw_err()
19508* \brief Get accumulative corrected RS codeword number.
19509* \param demod demod instance
19510* \param u32 *
19511* \return int.
19512*
19513* Check arguments
19514* Dispatch handling to standard specific function.
19515*
19516*/
19517static int
19518ctrl_get_accum_cr_rs_cw_err(struct drx_demod_instance *demod, u32 *accum_cr_rs_cw_err)
19519{
19520 int rc;
19521 if (accum_cr_rs_cw_err == NULL)
19522 return -EINVAL;
19523
19524 rc = drxdap_fasi_read_reg32(demod->my_i2c_dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, accum_cr_rs_cw_err, 0);
19525 if (rc != 0) {
19526 pr_err("error %d\n", rc);
19527 goto rw_error;
19528 }
19529
19530 return 0;
19531rw_error:
19532 return -EIO;
19533}
19534
19535/**
19536* \fn int ctrl_set_cfg()
19537* \brief Set 'some' configuration of the device.
19538* \param devmod Pointer to demodulator instance.
19539* \param config Pointer to configuration parameters (type and data).
19540* \return int.
19541
19542*/
19543static int ctrl_set_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19544{
19545 int rc;
19546
19547 if (config == NULL)
19548 return -EINVAL;
19549
19550 do {
19551 u16 dummy;
19552 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19553 if (rc != 0) {
19554 pr_err("error %d\n", rc);
19555 goto rw_error;
19556 }
19557 } while (0);
19558 switch (config->cfg_type) {
19559 case DRX_CFG_MPEG_OUTPUT:
19560 return ctrl_set_cfg_mpeg_output(demod,
19561 (struct drx_cfg_mpeg_output *) config->
19562 cfg_data);
19563 case DRX_CFG_PINS_SAFE_MODE:
19564 return ctrl_set_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19565 case DRXJ_CFG_AGC_RF:
19566 return ctrl_set_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19567 case DRXJ_CFG_AGC_IF:
19568 return ctrl_set_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19569 case DRXJ_CFG_PRE_SAW:
19570 return ctrl_set_cfg_pre_saw(demod,
19571 (struct drxj_cfg_pre_saw *) config->cfg_data);
19572 case DRXJ_CFG_AFE_GAIN:
19573 return ctrl_set_cfg_afe_gain(demod,
19574 (struct drxj_cfg_afe_gain *) config->cfg_data);
19575 case DRXJ_CFG_SMART_ANT:
19576 return ctrl_set_cfg_smart_ant(demod,
19577 (struct drxj_cfg_smart_ant *) (config->
19578 cfg_data));
19579 case DRXJ_CFG_RESET_PACKET_ERR:
19580 return ctrl_set_cfg_reset_pkt_err(demod);
19581#if 0
19582 case DRXJ_CFG_OOB_PRE_SAW:
19583 return ctrl_set_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19584 case DRXJ_CFG_OOB_LO_POW:
19585 return ctrl_set_cfg_oob_lo_power(demod,
19586 (enum drxj_cfg_oob_lo_power *) (config->
19587 cfg_data));
19588 case DRXJ_CFG_ATV_MISC:
19589 return ctrl_set_cfg_atv_misc(demod,
19590 (struct drxj_cfg_atv_misc *) config->cfg_data);
19591 case DRXJ_CFG_ATV_EQU_COEF:
19592 return ctrl_set_cfg_atv_equ_coef(demod,
19593 (struct drxj_cfg_atv_equ_coef *) config->
19594 cfg_data);
19595 case DRXJ_CFG_ATV_OUTPUT:
19596 return ctrl_set_cfg_atv_output(demod,
19597 (struct drxj_cfg_atv_output *) config->
19598 cfg_data);
19599#endif
19600 case DRXJ_CFG_MPEG_OUTPUT_MISC:
19601 return ctrl_set_cfg_mpeg_output_misc(demod,
19602 (struct drxj_cfg_mpeg_output_misc *)
19603 config->cfg_data);
19604#ifndef DRXJ_EXCLUDE_AUDIO
19605 case DRX_CFG_AUD_VOLUME:
19606 return aud_ctrl_set_cfg_volume(demod,
19607 (struct drx_cfg_aud_volume *) config->
19608 cfg_data);
19609 case DRX_CFG_I2S_OUTPUT:
19610 return aud_ctrl_set_cfg_output_i2s(demod,
19611 (struct drx_cfg_i2s_output *) config->
19612 cfg_data);
19613 case DRX_CFG_AUD_AUTOSOUND:
19614 return aud_ctr_setl_cfg_auto_sound(demod, (enum drx_cfg_aud_auto_sound *)
19615 config->cfg_data);
19616 case DRX_CFG_AUD_ASS_THRES:
19617 return aud_ctrl_set_cfg_ass_thres(demod, (struct drx_cfg_aud_ass_thres *)
19618 config->cfg_data);
19619 case DRX_CFG_AUD_CARRIER:
19620 return aud_ctrl_set_cfg_carrier(demod,
19621 (struct drx_cfg_aud_carriers *) config->
19622 cfg_data);
19623 case DRX_CFG_AUD_DEVIATION:
19624 return aud_ctrl_set_cfg_dev(demod,
19625 (enum drx_cfg_aud_deviation *) config->
19626 cfg_data);
19627 case DRX_CFG_AUD_PRESCALE:
19628 return aud_ctrl_set_cfg_prescale(demod,
19629 (struct drx_cfg_aud_prescale *) config->
19630 cfg_data);
19631 case DRX_CFG_AUD_MIXER:
19632 return aud_ctrl_set_cfg_mixer(demod,
19633 (struct drx_cfg_aud_mixer *) config->cfg_data);
19634 case DRX_CFG_AUD_AVSYNC:
19635 return aud_ctrl_set_cfg_av_sync(demod,
19636 (enum drx_cfg_aud_av_sync *) config->
19637 cfg_data);
19638
19639#endif
19640 default:
19641 return -EINVAL;
19642 }
19643
19644 return 0;
19645rw_error:
19646 return -EIO;
19647}
19648
19649/*============================================================================*/
19650
19651/**
19652* \fn int ctrl_get_cfg()
19653* \brief Get 'some' configuration of the device.
19654* \param devmod Pointer to demodulator instance.
19655* \param config Pointer to configuration parameters (type and data).
19656* \return int.
19657*/
19658
19659static int ctrl_get_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19660{
19661 int rc;
19662
19663 if (config == NULL)
19664 return -EINVAL;
19665
19666 do {
19667 u16 dummy;
19668 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19669 if (rc != 0) {
19670 pr_err("error %d\n", rc);
19671 goto rw_error;
19672 }
19673 } while (0);
19674
19675 switch (config->cfg_type) {
19676 case DRX_CFG_MPEG_OUTPUT:
19677 return ctrl_get_cfg_mpeg_output(demod,
19678 (struct drx_cfg_mpeg_output *) config->
19679 cfg_data);
19680 case DRX_CFG_PINS_SAFE_MODE:
19681 return ctrl_get_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19682 case DRXJ_CFG_AGC_RF:
19683 return ctrl_get_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19684 case DRXJ_CFG_AGC_IF:
19685 return ctrl_get_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19686 case DRXJ_CFG_AGC_INTERNAL:
19687 return ctrl_get_cfg_agc_internal(demod, (u16 *)config->cfg_data);
19688 case DRXJ_CFG_PRE_SAW:
19689 return ctrl_get_cfg_pre_saw(demod,
19690 (struct drxj_cfg_pre_saw *) config->cfg_data);
19691 case DRXJ_CFG_AFE_GAIN:
19692 return ctrl_get_cfg_afe_gain(demod,
19693 (struct drxj_cfg_afe_gain *) config->cfg_data);
19694 case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
19695 return ctrl_get_accum_cr_rs_cw_err(demod, (u32 *)config->cfg_data);
19696 case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
19697 return ctrl_get_fec_meas_seq_count(demod, (u16 *)config->cfg_data);
19698 case DRXJ_CFG_VSB_MISC:
19699 return ctrl_get_cfg_vsb_misc(demod,
19700 (struct drxj_cfg_vsb_misc *) config->cfg_data);
19701 case DRXJ_CFG_SYMBOL_CLK_OFFSET:
19702 return ctrl_get_cfg_symbol_clock_offset(demod,
19703 (s32 *)config->cfg_data);
19704#if 0
19705 case DRXJ_CFG_OOB_MISC:
19706 return ctrl_get_cfg_oob_misc(demod,
19707 (struct drxj_cfg_oob_misc *) config->cfg_data);
19708 case DRXJ_CFG_OOB_PRE_SAW:
19709 return ctrl_get_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19710 case DRXJ_CFG_OOB_LO_POW:
19711 return ctrl_get_cfg_oob_lo_power(demod,
19712 (enum drxj_cfg_oob_lo_power *) (config->
19713 cfg_data));
19714 case DRXJ_CFG_ATV_EQU_COEF:
19715 return ctrl_get_cfg_atv_equ_coef(demod,
19716 (struct drxj_cfg_atv_equ_coef *) config->
19717 cfg_data);
19718 case DRXJ_CFG_ATV_MISC:
19719 return ctrl_get_cfg_atv_misc(demod,
19720 (struct drxj_cfg_atv_misc *) config->cfg_data);
19721 case DRXJ_CFG_ATV_OUTPUT:
19722 return ctrl_get_cfg_atv_output(demod,
19723 (struct drxj_cfg_atv_output *) config->
19724 cfg_data);
19725 case DRXJ_CFG_ATV_AGC_STATUS:
19726 return ctrl_get_cfg_atv_agc_status(demod,
19727 (struct drxj_cfg_atv_agc_status *) config->
19728 cfg_data);
19729#endif
19730 case DRXJ_CFG_MPEG_OUTPUT_MISC:
19731 return ctrl_get_cfg_mpeg_output_misc(demod,
19732 (struct drxj_cfg_mpeg_output_misc *)
19733 config->cfg_data);
19734 case DRXJ_CFG_HW_CFG:
19735 return ctrl_get_cfg_hw_cfg(demod,
19736 (struct drxj_cfg_hw_cfg *) config->cfg_data);
19737#ifndef DRXJ_EXCLUDE_AUDIO
19738 case DRX_CFG_AUD_VOLUME:
19739 return aud_ctrl_get_cfg_volume(demod,
19740 (struct drx_cfg_aud_volume *) config->
19741 cfg_data);
19742 case DRX_CFG_I2S_OUTPUT:
19743 return aud_ctrl_get_cfg_output_i2s(demod,
19744 (struct drx_cfg_i2s_output *) config->
19745 cfg_data);
19746
19747 case DRX_CFG_AUD_RDS:
19748 return aud_ctrl_get_cfg_rds(demod,
19749 (struct drx_cfg_aud_rds *) config->cfg_data);
19750 case DRX_CFG_AUD_AUTOSOUND:
19751 return aud_ctrl_get_cfg_auto_sound(demod,
19752 (enum drx_cfg_aud_auto_sound *) config->
19753 cfg_data);
19754 case DRX_CFG_AUD_ASS_THRES:
19755 return aud_ctrl_get_cfg_ass_thres(demod,
19756 (struct drx_cfg_aud_ass_thres *) config->
19757 cfg_data);
19758 case DRX_CFG_AUD_CARRIER:
19759 return aud_ctrl_get_cfg_carrier(demod,
19760 (struct drx_cfg_aud_carriers *) config->
19761 cfg_data);
19762 case DRX_CFG_AUD_DEVIATION:
19763 return aud_ctrl_get_cfg_dev(demod,
19764 (enum drx_cfg_aud_deviation *) config->
19765 cfg_data);
19766 case DRX_CFG_AUD_PRESCALE:
19767 return aud_ctrl_get_cfg_prescale(demod,
19768 (struct drx_cfg_aud_prescale *) config->
19769 cfg_data);
19770 case DRX_CFG_AUD_MIXER:
19771 return aud_ctrl_get_cfg_mixer(demod,
19772 (struct drx_cfg_aud_mixer *) config->cfg_data);
19773 case DRX_CFG_AUD_AVSYNC:
19774 return aud_ctrl_get_cfg_av_sync(demod,
19775 (enum drx_cfg_aud_av_sync *) config->
19776 cfg_data);
19777#endif
19778
19779 default:
19780 return -EINVAL;
19781 }
19782
19783 return 0;
19784rw_error:
19785 return -EIO;
19786}
19787#endif
19788 11275
19789/*============================================================================= 11276/*=============================================================================
19790===== EXPORTED FUNCTIONS ====================================================*/ 11277===== EXPORTED FUNCTIONS ====================================================*/