Back to home page

OSCL-LXR

 
 

    


0001 /*
0002   Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
0003   All rights reserved.
0004 
0005   Redistribution and use in source and binary forms, with or without
0006   modification, are permitted provided that the following conditions are met:
0007 
0008   * Redistributions of source code must retain the above copyright notice,
0009     this list of conditions and the following disclaimer.
0010   * Redistributions in binary form must reproduce the above copyright notice,
0011     this list of conditions and the following disclaimer in the documentation
0012     and/or other materials provided with the distribution.
0013   * Neither the name of Trident Microsystems nor Hauppauge Computer Works
0014     nor the names of its contributors may be used to endorse or promote
0015     products derived from this software without specific prior written
0016     permission.
0017 
0018   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
0022   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028   POSSIBILITY OF SUCH DAMAGE.
0029 
0030   DRXJ specific implementation of DRX driver
0031   authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
0032 
0033   The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
0034   written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
0035 
0036   This program is free software; you can redistribute it and/or modify
0037   it under the terms of the GNU General Public License as published by
0038   the Free Software Foundation; either version 2 of the License, or
0039   (at your option) any later version.
0040 
0041   This program is distributed in the hope that it will be useful,
0042   but WITHOUT ANY WARRANTY; without even the implied warranty of
0043   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0044 
0045   GNU General Public License for more details.
0046 
0047   You should have received a copy of the GNU General Public License
0048   along with this program; if not, write to the Free Software
0049   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
0050 */
0051 
0052 /*-----------------------------------------------------------------------------
0053 INCLUDE FILES
0054 ----------------------------------------------------------------------------*/
0055 
0056 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
0057 
0058 #include <linux/module.h>
0059 #include <linux/init.h>
0060 #include <linux/string.h>
0061 #include <linux/slab.h>
0062 #include <asm/div64.h>
0063 
0064 #include <media/dvb_frontend.h>
0065 #include "drx39xxj.h"
0066 
0067 #include "drxj.h"
0068 #include "drxj_map.h"
0069 
0070 /*============================================================================*/
0071 /*=== DEFINES ================================================================*/
0072 /*============================================================================*/
0073 
0074 #define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
0075 
0076 /*
0077 * \brief Maximum u32 value.
0078 */
0079 #ifndef MAX_U32
0080 #define MAX_U32  ((u32) (0xFFFFFFFFL))
0081 #endif
0082 
0083 /* Customer configurable hardware settings, etc */
0084 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
0085 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
0086 #endif
0087 
0088 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
0089 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
0090 #endif
0091 
0092 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
0093 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
0094 #endif
0095 
0096 #ifndef OOB_CRX_DRIVE_STRENGTH
0097 #define OOB_CRX_DRIVE_STRENGTH 0x02
0098 #endif
0099 
0100 #ifndef OOB_DRX_DRIVE_STRENGTH
0101 #define OOB_DRX_DRIVE_STRENGTH 0x02
0102 #endif
0103 /*** START DJCOMBO patches to DRXJ registermap constants *********************/
0104 /*** registermap 200706071303 from drxj **************************************/
0105 #define   ATV_TOP_CR_AMP_TH_FM                                              0x0
0106 #define   ATV_TOP_CR_AMP_TH_L                                               0xA
0107 #define   ATV_TOP_CR_AMP_TH_LP                                              0xA
0108 #define   ATV_TOP_CR_AMP_TH_BG                                              0x8
0109 #define   ATV_TOP_CR_AMP_TH_DK                                              0x8
0110 #define   ATV_TOP_CR_AMP_TH_I                                               0x8
0111 #define     ATV_TOP_CR_CONT_CR_D_MN                                         0x18
0112 #define     ATV_TOP_CR_CONT_CR_D_FM                                         0x0
0113 #define     ATV_TOP_CR_CONT_CR_D_L                                          0x20
0114 #define     ATV_TOP_CR_CONT_CR_D_LP                                         0x20
0115 #define     ATV_TOP_CR_CONT_CR_D_BG                                         0x18
0116 #define     ATV_TOP_CR_CONT_CR_D_DK                                         0x18
0117 #define     ATV_TOP_CR_CONT_CR_D_I                                          0x18
0118 #define     ATV_TOP_CR_CONT_CR_I_MN                                         0x80
0119 #define     ATV_TOP_CR_CONT_CR_I_FM                                         0x0
0120 #define     ATV_TOP_CR_CONT_CR_I_L                                          0x80
0121 #define     ATV_TOP_CR_CONT_CR_I_LP                                         0x80
0122 #define     ATV_TOP_CR_CONT_CR_I_BG                                         0x80
0123 #define     ATV_TOP_CR_CONT_CR_I_DK                                         0x80
0124 #define     ATV_TOP_CR_CONT_CR_I_I                                          0x80
0125 #define     ATV_TOP_CR_CONT_CR_P_MN                                         0x4
0126 #define     ATV_TOP_CR_CONT_CR_P_FM                                         0x0
0127 #define     ATV_TOP_CR_CONT_CR_P_L                                          0x4
0128 #define     ATV_TOP_CR_CONT_CR_P_LP                                         0x4
0129 #define     ATV_TOP_CR_CONT_CR_P_BG                                         0x4
0130 #define     ATV_TOP_CR_CONT_CR_P_DK                                         0x4
0131 #define     ATV_TOP_CR_CONT_CR_P_I                                          0x4
0132 #define   ATV_TOP_CR_OVM_TH_MN                                              0xA0
0133 #define   ATV_TOP_CR_OVM_TH_FM                                              0x0
0134 #define   ATV_TOP_CR_OVM_TH_L                                               0xA0
0135 #define   ATV_TOP_CR_OVM_TH_LP                                              0xA0
0136 #define   ATV_TOP_CR_OVM_TH_BG                                              0xA0
0137 #define   ATV_TOP_CR_OVM_TH_DK                                              0xA0
0138 #define   ATV_TOP_CR_OVM_TH_I                                               0xA0
0139 #define     ATV_TOP_EQU0_EQU_C0_FM                                          0x0
0140 #define     ATV_TOP_EQU0_EQU_C0_L                                           0x3
0141 #define     ATV_TOP_EQU0_EQU_C0_LP                                          0x3
0142 #define     ATV_TOP_EQU0_EQU_C0_BG                                          0x7
0143 #define     ATV_TOP_EQU0_EQU_C0_DK                                          0x0
0144 #define     ATV_TOP_EQU0_EQU_C0_I                                           0x3
0145 #define     ATV_TOP_EQU1_EQU_C1_FM                                          0x0
0146 #define     ATV_TOP_EQU1_EQU_C1_L                                           0x1F6
0147 #define     ATV_TOP_EQU1_EQU_C1_LP                                          0x1F6
0148 #define     ATV_TOP_EQU1_EQU_C1_BG                                          0x197
0149 #define     ATV_TOP_EQU1_EQU_C1_DK                                          0x198
0150 #define     ATV_TOP_EQU1_EQU_C1_I                                           0x1F6
0151 #define     ATV_TOP_EQU2_EQU_C2_FM                                          0x0
0152 #define     ATV_TOP_EQU2_EQU_C2_L                                           0x28
0153 #define     ATV_TOP_EQU2_EQU_C2_LP                                          0x28
0154 #define     ATV_TOP_EQU2_EQU_C2_BG                                          0xC5
0155 #define     ATV_TOP_EQU2_EQU_C2_DK                                          0xB0
0156 #define     ATV_TOP_EQU2_EQU_C2_I                                           0x28
0157 #define     ATV_TOP_EQU3_EQU_C3_FM                                          0x0
0158 #define     ATV_TOP_EQU3_EQU_C3_L                                           0x192
0159 #define     ATV_TOP_EQU3_EQU_C3_LP                                          0x192
0160 #define     ATV_TOP_EQU3_EQU_C3_BG                                          0x12E
0161 #define     ATV_TOP_EQU3_EQU_C3_DK                                          0x18E
0162 #define     ATV_TOP_EQU3_EQU_C3_I                                           0x192
0163 #define     ATV_TOP_STD_MODE_MN                                             0x0
0164 #define     ATV_TOP_STD_MODE_FM                                             0x1
0165 #define     ATV_TOP_STD_MODE_L                                              0x0
0166 #define     ATV_TOP_STD_MODE_LP                                             0x0
0167 #define     ATV_TOP_STD_MODE_BG                                             0x0
0168 #define     ATV_TOP_STD_MODE_DK                                             0x0
0169 #define     ATV_TOP_STD_MODE_I                                              0x0
0170 #define     ATV_TOP_STD_VID_POL_MN                                          0x0
0171 #define     ATV_TOP_STD_VID_POL_FM                                          0x0
0172 #define     ATV_TOP_STD_VID_POL_L                                           0x2
0173 #define     ATV_TOP_STD_VID_POL_LP                                          0x2
0174 #define     ATV_TOP_STD_VID_POL_BG                                          0x0
0175 #define     ATV_TOP_STD_VID_POL_DK                                          0x0
0176 #define     ATV_TOP_STD_VID_POL_I                                           0x0
0177 #define   ATV_TOP_VID_AMP_MN                                                0x380
0178 #define   ATV_TOP_VID_AMP_FM                                                0x0
0179 #define   ATV_TOP_VID_AMP_L                                                 0xF50
0180 #define   ATV_TOP_VID_AMP_LP                                                0xF50
0181 #define   ATV_TOP_VID_AMP_BG                                                0x380
0182 #define   ATV_TOP_VID_AMP_DK                                                0x394
0183 #define   ATV_TOP_VID_AMP_I                                                 0x3D8
0184 #define   IQM_CF_OUT_ENA_OFDM__M                                            0x4
0185 #define     IQM_FS_ADJ_SEL_B_QAM                                            0x1
0186 #define     IQM_FS_ADJ_SEL_B_OFF                                            0x0
0187 #define     IQM_FS_ADJ_SEL_B_VSB                                            0x2
0188 #define     IQM_RC_ADJ_SEL_B_OFF                                            0x0
0189 #define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
0190 #define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
0191 /*** END DJCOMBO patches to DRXJ registermap *********************************/
0192 
0193 #include "drx_driver_version.h"
0194 
0195 /* #define DRX_DEBUG */
0196 #ifdef DRX_DEBUG
0197 #include <stdio.h>
0198 #endif
0199 
0200 /*-----------------------------------------------------------------------------
0201 ENUMS
0202 ----------------------------------------------------------------------------*/
0203 
0204 /*-----------------------------------------------------------------------------
0205 DEFINES
0206 ----------------------------------------------------------------------------*/
0207 #ifndef DRXJ_WAKE_UP_KEY
0208 #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
0209 #endif
0210 
0211 /*
0212 * \def DRXJ_DEF_I2C_ADDR
0213 * \brief Default I2C address of a demodulator instance.
0214 */
0215 #define DRXJ_DEF_I2C_ADDR (0x52)
0216 
0217 /*
0218 * \def DRXJ_DEF_DEMOD_DEV_ID
0219 * \brief Default device identifier of a demodultor instance.
0220 */
0221 #define DRXJ_DEF_DEMOD_DEV_ID      (1)
0222 
0223 /*
0224 * \def DRXJ_SCAN_TIMEOUT
0225 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
0226 */
0227 #define DRXJ_SCAN_TIMEOUT    1000
0228 
0229 /*
0230 * \def HI_I2C_DELAY
0231 * \brief HI timing delay for I2C timing (in nano seconds)
0232 *
0233 *  Used to compute HI_CFG_DIV
0234 */
0235 #define HI_I2C_DELAY    42
0236 
0237 /*
0238 * \def HI_I2C_BRIDGE_DELAY
0239 * \brief HI timing delay for I2C timing (in nano seconds)
0240 *
0241 *  Used to compute HI_CFG_BDL
0242 */
0243 #define HI_I2C_BRIDGE_DELAY   750
0244 
0245 /*
0246 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
0247 */
0248 #define VSB_TOP_MEASUREMENT_PERIOD  64
0249 #define SYMBOLS_PER_SEGMENT         832
0250 
0251 /*
0252 * \brief bit rate and segment rate constants used for SER and BER.
0253 */
0254 /* values taken from the QAM microcode */
0255 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
0256 #define DRXJ_QAM_SL_SIG_POWER_QPSK        32768
0257 #define DRXJ_QAM_SL_SIG_POWER_QAM8        24576
0258 #define DRXJ_QAM_SL_SIG_POWER_QAM16       40960
0259 #define DRXJ_QAM_SL_SIG_POWER_QAM32       20480
0260 #define DRXJ_QAM_SL_SIG_POWER_QAM64       43008
0261 #define DRXJ_QAM_SL_SIG_POWER_QAM128      20992
0262 #define DRXJ_QAM_SL_SIG_POWER_QAM256      43520
0263 /*
0264 * \brief Min supported symbolrates.
0265 */
0266 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
0267 #define DRXJ_QAM_SYMBOLRATE_MIN          (520000)
0268 #endif
0269 
0270 /*
0271 * \brief Max supported symbolrates.
0272 */
0273 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
0274 #define DRXJ_QAM_SYMBOLRATE_MAX         (7233000)
0275 #endif
0276 
0277 /*
0278 * \def DRXJ_QAM_MAX_WAITTIME
0279 * \brief Maximal wait time for QAM auto constellation in ms
0280 */
0281 #ifndef DRXJ_QAM_MAX_WAITTIME
0282 #define DRXJ_QAM_MAX_WAITTIME 900
0283 #endif
0284 
0285 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
0286 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
0287 #endif
0288 
0289 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
0290 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
0291 #endif
0292 
0293 /*
0294 * \def SCU status and results
0295 * \brief SCU
0296 */
0297 #define DRX_SCU_READY               0
0298 #define DRXJ_MAX_WAITTIME           100 /* ms */
0299 #define FEC_RS_MEASUREMENT_PERIOD   12894   /* 1 sec */
0300 #define FEC_RS_MEASUREMENT_PRESCALE 1   /* n sec */
0301 
0302 /*
0303 * \def DRX_AUD_MAX_DEVIATION
0304 * \brief Needed for calculation of prescale feature in AUD
0305 */
0306 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
0307 #define DRXJ_AUD_MAX_FM_DEVIATION  100  /* kHz */
0308 #endif
0309 
0310 /*
0311 * \brief Needed for calculation of NICAM prescale feature in AUD
0312 */
0313 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
0314 #define DRXJ_AUD_MAX_NICAM_PRESCALE  (9)    /* dB */
0315 #endif
0316 
0317 /*
0318 * \brief Needed for calculation of NICAM prescale feature in AUD
0319 */
0320 #ifndef DRXJ_AUD_MAX_WAITTIME
0321 #define DRXJ_AUD_MAX_WAITTIME  250  /* ms */
0322 #endif
0323 
0324 /* ATV config changed flags */
0325 #define DRXJ_ATV_CHANGED_COEF          (0x00000001UL)
0326 #define DRXJ_ATV_CHANGED_PEAK_FLT      (0x00000008UL)
0327 #define DRXJ_ATV_CHANGED_NOISE_FLT     (0x00000010UL)
0328 #define DRXJ_ATV_CHANGED_OUTPUT        (0x00000020UL)
0329 #define DRXJ_ATV_CHANGED_SIF_ATT       (0x00000040UL)
0330 
0331 /* UIO define */
0332 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
0333 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
0334 
0335 /*
0336  * MICROCODE RELATED DEFINES
0337  */
0338 
0339 /* Magic word for checking correct Endianness of microcode data */
0340 #define DRX_UCODE_MAGIC_WORD         ((((u16)'H')<<8)+((u16)'L'))
0341 
0342 /* CRC flag in ucode header, flags field. */
0343 #define DRX_UCODE_CRC_FLAG           (0x0001)
0344 
0345 /*
0346  * Maximum size of buffer used to verify the microcode.
0347  * Must be an even number
0348  */
0349 #define DRX_UCODE_MAX_BUF_SIZE       (DRXDAP_MAX_RCHUNKSIZE)
0350 
0351 #if DRX_UCODE_MAX_BUF_SIZE & 1
0352 #error DRX_UCODE_MAX_BUF_SIZE must be an even number
0353 #endif
0354 
0355 /*
0356  * Power mode macros
0357  */
0358 
0359 #define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
0360                        (mode == DRX_POWER_MODE_10) || \
0361                        (mode == DRX_POWER_MODE_11) || \
0362                        (mode == DRX_POWER_MODE_12) || \
0363                        (mode == DRX_POWER_MODE_13) || \
0364                        (mode == DRX_POWER_MODE_14) || \
0365                        (mode == DRX_POWER_MODE_15) || \
0366                        (mode == DRX_POWER_MODE_16) || \
0367                        (mode == DRX_POWER_DOWN))
0368 
0369 /* Pin safe mode macro */
0370 #define DRXJ_PIN_SAFE_MODE 0x0000
0371 /*============================================================================*/
0372 /*=== GLOBAL VARIABLEs =======================================================*/
0373 /*============================================================================*/
0374 /*
0375 */
0376 
0377 /*
0378 * \brief Temporary register definitions.
0379 *        (register definitions that are not yet available in register master)
0380 */
0381 
0382 /*****************************************************************************/
0383 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing   */
0384 /* RAM addresses directly. This must be READ ONLY to avoid problems.         */
0385 /* Writing to the interface addresses are more than only writing the RAM     */
0386 /* locations                                                                 */
0387 /*****************************************************************************/
0388 /*
0389 * \brief RAM location of MODUS registers
0390 */
0391 #define AUD_DEM_RAM_MODUS_HI__A              0x10204A3
0392 #define AUD_DEM_RAM_MODUS_HI__M              0xF000
0393 
0394 #define AUD_DEM_RAM_MODUS_LO__A              0x10204A4
0395 #define AUD_DEM_RAM_MODUS_LO__M              0x0FFF
0396 
0397 /*
0398 * \brief RAM location of I2S config registers
0399 */
0400 #define AUD_DEM_RAM_I2S_CONFIG1__A           0x10204B1
0401 #define AUD_DEM_RAM_I2S_CONFIG2__A           0x10204B2
0402 
0403 /*
0404 * \brief RAM location of DCO config registers
0405 */
0406 #define AUD_DEM_RAM_DCO_B_HI__A              0x1020461
0407 #define AUD_DEM_RAM_DCO_B_LO__A              0x1020462
0408 #define AUD_DEM_RAM_DCO_A_HI__A              0x1020463
0409 #define AUD_DEM_RAM_DCO_A_LO__A              0x1020464
0410 
0411 /*
0412 * \brief RAM location of Threshold registers
0413 */
0414 #define AUD_DEM_RAM_NICAM_THRSHLD__A         0x102045A
0415 #define AUD_DEM_RAM_A2_THRSHLD__A            0x10204BB
0416 #define AUD_DEM_RAM_BTSC_THRSHLD__A          0x10204A6
0417 
0418 /*
0419 * \brief RAM location of Carrier Threshold registers
0420 */
0421 #define AUD_DEM_RAM_CM_A_THRSHLD__A          0x10204AF
0422 #define AUD_DEM_RAM_CM_B_THRSHLD__A          0x10204B0
0423 
0424 /*
0425 * \brief FM Matrix register fix
0426 */
0427 #ifdef AUD_DEM_WR_FM_MATRIX__A
0428 #undef  AUD_DEM_WR_FM_MATRIX__A
0429 #endif
0430 #define AUD_DEM_WR_FM_MATRIX__A              0x105006F
0431 
0432 /*============================================================================*/
0433 /*
0434 * \brief Defines required for audio
0435 */
0436 #define AUD_VOLUME_ZERO_DB                      115
0437 #define AUD_VOLUME_DB_MIN                       -60
0438 #define AUD_VOLUME_DB_MAX                       12
0439 #define AUD_CARRIER_STRENGTH_QP_0DB             0x4000
0440 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100   421
0441 #define AUD_MAX_AVC_REF_LEVEL                   15
0442 #define AUD_I2S_FREQUENCY_MAX                   48000UL
0443 #define AUD_I2S_FREQUENCY_MIN                   12000UL
0444 #define AUD_RDS_ARRAY_SIZE                      18
0445 
0446 /*
0447 * \brief Needed for calculation of prescale feature in AUD
0448 */
0449 #ifndef DRX_AUD_MAX_FM_DEVIATION
0450 #define DRX_AUD_MAX_FM_DEVIATION  (100) /* kHz */
0451 #endif
0452 
0453 /*
0454 * \brief Needed for calculation of NICAM prescale feature in AUD
0455 */
0456 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
0457 #define DRX_AUD_MAX_NICAM_PRESCALE  (9) /* dB */
0458 #endif
0459 
0460 /*============================================================================*/
0461 /* Values for I2S Master/Slave pin configurations */
0462 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER      0x0004
0463 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER     0x0008
0464 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE       0x0004
0465 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE      0x0000
0466 
0467 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER      0x0003
0468 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER     0x0008
0469 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE       0x0003
0470 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE      0x0008
0471 
0472 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER      0x0004
0473 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER     0x0008
0474 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE       0x0004
0475 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE      0x0000
0476 
0477 /*============================================================================*/
0478 /*=== REGISTER ACCESS MACROS =================================================*/
0479 /*============================================================================*/
0480 
0481 /*
0482 * This macro is used to create byte arrays for block writes.
0483 * Block writes speed up I2C traffic between host and demod.
0484 * The macro takes care of the required byte order in a 16 bits word.
0485 * x -> lowbyte(x), highbyte(x)
0486 */
0487 #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
0488                ((u8)((((u16)x)>>8)&0xFF))
0489 /*
0490 * This macro is used to convert byte array to 16 bit register value for block read.
0491 * Block read speed up I2C traffic between host and demod.
0492 * The macro takes care of the required byte order in a 16 bits word.
0493 */
0494 #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
0495 
0496 /*============================================================================*/
0497 /*=== MISC DEFINES ===========================================================*/
0498 /*============================================================================*/
0499 
0500 /*============================================================================*/
0501 /*=== HI COMMAND RELATED DEFINES =============================================*/
0502 /*============================================================================*/
0503 
0504 /*
0505 * \brief General maximum number of retries for ucode command interfaces
0506 */
0507 #define DRXJ_MAX_RETRIES (100)
0508 
0509 /*============================================================================*/
0510 /*=== STANDARD RELATED MACROS ================================================*/
0511 /*============================================================================*/
0512 
0513 #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
0514                    (std == DRX_STANDARD_PAL_SECAM_DK) || \
0515                    (std == DRX_STANDARD_PAL_SECAM_I) || \
0516                    (std == DRX_STANDARD_PAL_SECAM_L) || \
0517                    (std == DRX_STANDARD_PAL_SECAM_LP) || \
0518                    (std == DRX_STANDARD_NTSC) || \
0519                    (std == DRX_STANDARD_FM))
0520 
0521 #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
0522                    (std == DRX_STANDARD_ITU_B) || \
0523                    (std == DRX_STANDARD_ITU_C) || \
0524                    (std == DRX_STANDARD_ITU_D))
0525 
0526 /*-----------------------------------------------------------------------------
0527 GLOBAL VARIABLES
0528 ----------------------------------------------------------------------------*/
0529 /*
0530  * DRXJ DAP structures
0531  */
0532 
0533 static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
0534                       u32 addr,
0535                       u16 datasize,
0536                       u8 *data, u32 flags);
0537 
0538 
0539 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
0540                          u32 waddr,
0541                          u32 raddr,
0542                          u16 wdata, u16 *rdata);
0543 
0544 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
0545                       u32 addr,
0546                       u16 *data, u32 flags);
0547 
0548 static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
0549                       u32 addr,
0550                       u32 *data, u32 flags);
0551 
0552 static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
0553                        u32 addr,
0554                        u16 datasize,
0555                        u8 *data, u32 flags);
0556 
0557 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
0558                        u32 addr,
0559                        u16 data, u32 flags);
0560 
0561 static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
0562                        u32 addr,
0563                        u32 data, u32 flags);
0564 
0565 static struct drxj_data drxj_data_g = {
0566     false,          /* has_lna : true if LNA (aka PGA) present      */
0567     false,          /* has_oob : true if OOB supported              */
0568     false,          /* has_ntsc: true if NTSC supported             */
0569     false,          /* has_btsc: true if BTSC supported             */
0570     false,          /* has_smatx: true if SMA_TX pin is available   */
0571     false,          /* has_smarx: true if SMA_RX pin is available   */
0572     false,          /* has_gpio : true if GPIO pin is available     */
0573     false,          /* has_irqn : true if IRQN pin is available     */
0574     0,          /* mfx A1/A2/A... */
0575 
0576     /* tuner settings */
0577     false,          /* tuner mirrors RF signal    */
0578     /* standard/channel settings */
0579     DRX_STANDARD_UNKNOWN,   /* current standard           */
0580     DRX_CONSTELLATION_AUTO, /* constellation              */
0581     0,          /* frequency in KHz           */
0582     DRX_BANDWIDTH_UNKNOWN,  /* curr_bandwidth              */
0583     DRX_MIRROR_NO,      /* mirror                     */
0584 
0585     /* signal quality information: */
0586     /* default values taken from the QAM Programming guide */
0587     /*   fec_bits_desired should not be less than 4000000    */
0588     4000000,        /* fec_bits_desired    */
0589     5,          /* fec_vd_plen         */
0590     4,          /* qam_vd_prescale     */
0591     0xFFFF,         /* qamVDPeriod       */
0592     204 * 8,        /* fec_rs_plen annex A */
0593     1,          /* fec_rs_prescale     */
0594     FEC_RS_MEASUREMENT_PERIOD,  /* fec_rs_period     */
0595     true,           /* reset_pkt_err_acc    */
0596     0,          /* pkt_err_acc_start    */
0597 
0598     /* HI configuration */
0599     0,          /* hi_cfg_timing_div    */
0600     0,          /* hi_cfg_bridge_delay  */
0601     0,          /* hi_cfg_wake_up_key    */
0602     0,          /* hi_cfg_ctrl         */
0603     0,          /* HICfgTimeout      */
0604     /* UIO configuration */
0605     DRX_UIO_MODE_DISABLE,   /* uio_sma_rx_mode      */
0606     DRX_UIO_MODE_DISABLE,   /* uio_sma_tx_mode      */
0607     DRX_UIO_MODE_DISABLE,   /* uioASELMode       */
0608     DRX_UIO_MODE_DISABLE,   /* uio_irqn_mode       */
0609     /* FS setting */
0610     0UL,            /* iqm_fs_rate_ofs      */
0611     false,          /* pos_image          */
0612     /* RC setting */
0613     0UL,            /* iqm_rc_rate_ofs      */
0614     /* AUD information */
0615 /*   false,                  * flagSetAUDdone    */
0616 /*   false,                  * detectedRDS       */
0617 /*   true,                   * flagASDRequest    */
0618 /*   false,                  * flagHDevClear     */
0619 /*   false,                  * flagHDevSet       */
0620 /*   (u16) 0xFFF,          * rdsLastCount      */
0621 
0622     /* ATV configuration */
0623     0UL,            /* flags cfg changes */
0624     /* shadow of ATV_TOP_EQU0__A */
0625     {-5,
0626      ATV_TOP_EQU0_EQU_C0_FM,
0627      ATV_TOP_EQU0_EQU_C0_L,
0628      ATV_TOP_EQU0_EQU_C0_LP,
0629      ATV_TOP_EQU0_EQU_C0_BG,
0630      ATV_TOP_EQU0_EQU_C0_DK,
0631      ATV_TOP_EQU0_EQU_C0_I},
0632     /* shadow of ATV_TOP_EQU1__A */
0633     {-50,
0634      ATV_TOP_EQU1_EQU_C1_FM,
0635      ATV_TOP_EQU1_EQU_C1_L,
0636      ATV_TOP_EQU1_EQU_C1_LP,
0637      ATV_TOP_EQU1_EQU_C1_BG,
0638      ATV_TOP_EQU1_EQU_C1_DK,
0639      ATV_TOP_EQU1_EQU_C1_I},
0640     /* shadow of ATV_TOP_EQU2__A */
0641     {210,
0642      ATV_TOP_EQU2_EQU_C2_FM,
0643      ATV_TOP_EQU2_EQU_C2_L,
0644      ATV_TOP_EQU2_EQU_C2_LP,
0645      ATV_TOP_EQU2_EQU_C2_BG,
0646      ATV_TOP_EQU2_EQU_C2_DK,
0647      ATV_TOP_EQU2_EQU_C2_I},
0648     /* shadow of ATV_TOP_EQU3__A */
0649     {-160,
0650      ATV_TOP_EQU3_EQU_C3_FM,
0651      ATV_TOP_EQU3_EQU_C3_L,
0652      ATV_TOP_EQU3_EQU_C3_LP,
0653      ATV_TOP_EQU3_EQU_C3_BG,
0654      ATV_TOP_EQU3_EQU_C3_DK,
0655      ATV_TOP_EQU3_EQU_C3_I},
0656     false,          /* flag: true=bypass             */
0657     ATV_TOP_VID_PEAK__PRE,  /* shadow of ATV_TOP_VID_PEAK__A */
0658     ATV_TOP_NOISE_TH__PRE,  /* shadow of ATV_TOP_NOISE_TH__A */
0659     true,           /* flag CVBS output enable       */
0660     false,          /* flag SIF output enable        */
0661     DRXJ_SIF_ATTENUATION_0DB,   /* current SIF att setting       */
0662     {           /* qam_rf_agc_cfg */
0663      DRX_STANDARD_ITU_B,    /* standard            */
0664      DRX_AGC_CTRL_AUTO, /* ctrl_mode            */
0665      0,         /* output_level         */
0666      0,         /* min_output_level      */
0667      0xFFFF,        /* max_output_level      */
0668      0x0000,        /* speed               */
0669      0x0000,        /* top                 */
0670      0x0000         /* c.o.c.              */
0671      },
0672     {           /* qam_if_agc_cfg */
0673      DRX_STANDARD_ITU_B,    /* standard            */
0674      DRX_AGC_CTRL_AUTO, /* ctrl_mode            */
0675      0,         /* output_level         */
0676      0,         /* min_output_level      */
0677      0xFFFF,        /* max_output_level      */
0678      0x0000,        /* speed               */
0679      0x0000,        /* top    (don't care) */
0680      0x0000         /* c.o.c. (don't care) */
0681      },
0682     {           /* vsb_rf_agc_cfg */
0683      DRX_STANDARD_8VSB, /* standard       */
0684      DRX_AGC_CTRL_AUTO, /* ctrl_mode       */
0685      0,         /* output_level    */
0686      0,         /* min_output_level */
0687      0xFFFF,        /* max_output_level */
0688      0x0000,        /* speed          */
0689      0x0000,        /* top    (don't care) */
0690      0x0000         /* c.o.c. (don't care) */
0691      },
0692     {           /* vsb_if_agc_cfg */
0693      DRX_STANDARD_8VSB, /* standard       */
0694      DRX_AGC_CTRL_AUTO, /* ctrl_mode       */
0695      0,         /* output_level    */
0696      0,         /* min_output_level */
0697      0xFFFF,        /* max_output_level */
0698      0x0000,        /* speed          */
0699      0x0000,        /* top    (don't care) */
0700      0x0000         /* c.o.c. (don't care) */
0701      },
0702     0,          /* qam_pga_cfg */
0703     0,          /* vsb_pga_cfg */
0704     {           /* qam_pre_saw_cfg */
0705      DRX_STANDARD_ITU_B,    /* standard  */
0706      0,         /* reference */
0707      false          /* use_pre_saw */
0708      },
0709     {           /* vsb_pre_saw_cfg */
0710      DRX_STANDARD_8VSB, /* standard  */
0711      0,         /* reference */
0712      false          /* use_pre_saw */
0713      },
0714 
0715     /* Version information */
0716 #ifndef _CH_
0717     {
0718      "01234567890",     /* human readable version microcode             */
0719      "01234567890"      /* human readable version device specific code  */
0720      },
0721     {
0722      {          /* struct drx_version for microcode                   */
0723       DRX_MODULE_UNKNOWN,
0724       (char *)(NULL),
0725       0,
0726       0,
0727       0,
0728       (char *)(NULL)
0729       },
0730      {          /* struct drx_version for device specific code */
0731       DRX_MODULE_UNKNOWN,
0732       (char *)(NULL),
0733       0,
0734       0,
0735       0,
0736       (char *)(NULL)
0737       }
0738      },
0739     {
0740      {          /* struct drx_version_list for microcode */
0741       (struct drx_version *) (NULL),
0742       (struct drx_version_list *) (NULL)
0743       },
0744      {          /* struct drx_version_list for device specific code */
0745       (struct drx_version *) (NULL),
0746       (struct drx_version_list *) (NULL)
0747       }
0748      },
0749 #endif
0750     false,          /* smart_ant_inverted */
0751     /* Tracking filter setting for OOB  */
0752     {
0753      12000,
0754      9300,
0755      6600,
0756      5280,
0757      3700,
0758      3000,
0759      2000,
0760      0},
0761     false,          /* oob_power_on           */
0762     0,          /* mpeg_ts_static_bitrate  */
0763     false,          /* disable_te_ihandling   */
0764     false,          /* bit_reverse_mpeg_outout */
0765     DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,    /* mpeg_output_clock_rate */
0766     DRXJ_MPEG_START_WIDTH_1CLKCYC,  /* mpeg_start_width */
0767 
0768     /* Pre SAW & Agc configuration for ATV */
0769     {
0770      DRX_STANDARD_NTSC, /* standard     */
0771      7,         /* reference    */
0772      true           /* use_pre_saw    */
0773      },
0774     {           /* ATV RF-AGC */
0775      DRX_STANDARD_NTSC, /* standard              */
0776      DRX_AGC_CTRL_AUTO, /* ctrl_mode              */
0777      0,         /* output_level           */
0778      0,         /* min_output_level (d.c.) */
0779      0,         /* max_output_level (d.c.) */
0780      3,         /* speed                 */
0781      9500,          /* top                   */
0782      4000           /* cut-off current       */
0783      },
0784     {           /* ATV IF-AGC */
0785      DRX_STANDARD_NTSC, /* standard              */
0786      DRX_AGC_CTRL_AUTO, /* ctrl_mode              */
0787      0,         /* output_level           */
0788      0,         /* min_output_level (d.c.) */
0789      0,         /* max_output_level (d.c.) */
0790      3,         /* speed                 */
0791      2400,          /* top                   */
0792      0          /* c.o.c.         (d.c.) */
0793      },
0794     140,            /* ATV PGA config */
0795     0,          /* curr_symbol_rate */
0796 
0797     false,          /* pdr_safe_mode     */
0798     SIO_PDR_GPIO_CFG__PRE,  /* pdr_safe_restore_val_gpio  */
0799     SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
0800     SIO_PDR_SMA_RX_CFG__PRE,    /* pdr_safe_restore_val_sma_rx */
0801     SIO_PDR_SMA_TX_CFG__PRE,    /* pdr_safe_restore_val_sma_tx */
0802 
0803     4,          /* oob_pre_saw            */
0804     DRXJ_OOB_LO_POW_MINUS10DB,  /* oob_lo_pow             */
0805     {
0806      false          /* aud_data, only first member */
0807      },
0808 };
0809 
0810 /*
0811 * \var drxj_default_addr_g
0812 * \brief Default I2C address and device identifier.
0813 */
0814 static struct i2c_device_addr drxj_default_addr_g = {
0815     DRXJ_DEF_I2C_ADDR,  /* i2c address */
0816     DRXJ_DEF_DEMOD_DEV_ID   /* device id */
0817 };
0818 
0819 /*
0820 * \var drxj_default_comm_attr_g
0821 * \brief Default common attributes of a drxj demodulator instance.
0822 */
0823 static struct drx_common_attr drxj_default_comm_attr_g = {
0824     NULL,           /* ucode file           */
0825     true,           /* ucode verify switch  */
0826     {0},            /* version record       */
0827 
0828     44000,          /* IF in kHz in case no tuner instance is used  */
0829     (151875 - 0),       /* system clock frequency in kHz                */
0830     0,          /* oscillator frequency kHz                     */
0831     0,          /* oscillator deviation in ppm, signed          */
0832     false,          /* If true mirror frequency spectrum            */
0833     {
0834      /* MPEG output configuration */
0835      true,          /* If true, enable MPEG output   */
0836      false,         /* If true, insert RS byte       */
0837      false,         /* If true, parallel out otherwise serial */
0838      false,         /* If true, invert DATA signals  */
0839      false,         /* If true, invert ERR signal    */
0840      false,         /* If true, invert STR signals   */
0841      false,         /* If true, invert VAL signals   */
0842      false,         /* If true, invert CLK signals   */
0843      true,          /* If true, static MPEG clockrate will
0844                    be used, otherwise clockrate will
0845                    adapt to the bitrate of the TS */
0846      19392658UL,        /* Maximum bitrate in b/s in case
0847                    static clockrate is selected */
0848      DRX_MPEG_STR_WIDTH_1   /* MPEG Start width in clock cycles */
0849      },
0850     /* Initilisations below can be omitted, they require no user input and
0851        are initially 0, NULL or false. The compiler will initialize them to these
0852        values when omitted.  */
0853     false,          /* is_opened */
0854 
0855     /* SCAN */
0856     NULL,           /* no scan params yet               */
0857     0,          /* current scan index               */
0858     0,          /* next scan frequency              */
0859     false,          /* scan ready flag                  */
0860     0,          /* max channels to scan             */
0861     0,          /* nr of channels scanned           */
0862     NULL,           /* default scan function            */
0863     NULL,           /* default context pointer          */
0864     0,          /* millisec to wait for demod lock  */
0865     DRXJ_DEMOD_LOCK,    /* desired lock               */
0866     false,
0867 
0868     /* Power management */
0869     DRX_POWER_UP,
0870 
0871     /* Tuner */
0872     1,          /* nr of I2C port to which tuner is    */
0873     0L,         /* minimum RF input frequency, in kHz  */
0874     0L,         /* maximum RF input frequency, in kHz  */
0875     false,          /* Rf Agc Polarity                     */
0876     false,          /* If Agc Polarity                     */
0877     false,          /* tuner slow mode                     */
0878 
0879     {           /* current channel (all 0)             */
0880      0UL            /* channel.frequency */
0881      },
0882     DRX_STANDARD_UNKNOWN,   /* current standard */
0883     DRX_STANDARD_UNKNOWN,   /* previous standard */
0884     DRX_STANDARD_UNKNOWN,   /* di_cache_standard   */
0885     false,          /* use_bootloader */
0886     0UL,            /* capabilities */
0887     0           /* mfx */
0888 };
0889 
0890 /*
0891 * \var drxj_default_demod_g
0892 * \brief Default drxj demodulator instance.
0893 */
0894 static struct drx_demod_instance drxj_default_demod_g = {
0895     &drxj_default_addr_g,   /* i2c address & device id */
0896     &drxj_default_comm_attr_g,  /* demod common attributes */
0897     &drxj_data_g        /* demod device specific attributes */
0898 };
0899 
0900 /*
0901 * \brief Default audio data structure for DRK demodulator instance.
0902 *
0903 * This structure is DRXK specific.
0904 *
0905 */
0906 static struct drx_aud_data drxj_default_aud_data_g = {
0907     false,          /* audio_is_active */
0908     DRX_AUD_STANDARD_AUTO,  /* audio_standard  */
0909 
0910     /* i2sdata */
0911     {
0912      false,         /* output_enable   */
0913      48000,         /* frequency      */
0914      DRX_I2S_MODE_MASTER,   /* mode           */
0915      DRX_I2S_WORDLENGTH_32, /* word_length     */
0916      DRX_I2S_POLARITY_RIGHT,    /* polarity       */
0917      DRX_I2S_FORMAT_WS_WITH_DATA    /* format         */
0918      },
0919     /* volume            */
0920     {
0921      true,          /* mute;          */
0922      0,         /* volume         */
0923      DRX_AUD_AVC_OFF,   /* avc_mode        */
0924      0,         /* avc_ref_level    */
0925      DRX_AUD_AVC_MAX_GAIN_12DB, /* avc_max_gain     */
0926      DRX_AUD_AVC_MAX_ATTEN_24DB,    /* avc_max_atten    */
0927      0,         /* strength_left   */
0928      0          /* strength_right  */
0929      },
0930     DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
0931     /*  ass_thresholds */
0932     {
0933      440,           /* A2    */
0934      12,            /* BTSC  */
0935      700,           /* NICAM */
0936      },
0937     /* carrier */
0938     {
0939      /* a */
0940      {
0941       42,           /* thres */
0942       DRX_NO_CARRIER_NOISE, /* opt   */
0943       0,            /* shift */
0944       0         /* dco   */
0945       },
0946      /* b */
0947      {
0948       42,           /* thres */
0949       DRX_NO_CARRIER_MUTE,  /* opt   */
0950       0,            /* shift */
0951       0         /* dco   */
0952       },
0953 
0954      },
0955     /* mixer */
0956     {
0957      DRX_AUD_SRC_STEREO_OR_A,   /* source_i2s */
0958      DRX_AUD_I2S_MATRIX_STEREO, /* matrix_i2s */
0959      DRX_AUD_FM_MATRIX_SOUND_A  /* matrix_fm  */
0960      },
0961     DRX_AUD_DEVIATION_NORMAL,   /* deviation */
0962     DRX_AUD_AVSYNC_OFF, /* av_sync */
0963 
0964     /* prescale */
0965     {
0966      DRX_AUD_MAX_FM_DEVIATION,  /* fm_deviation */
0967      DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
0968      },
0969     DRX_AUD_FM_DEEMPH_75US, /* deemph */
0970     DRX_BTSC_STEREO,    /* btsc_detect */
0971     0,          /* rds_data_counter */
0972     false           /* rds_data_present */
0973 };
0974 
0975 /*-----------------------------------------------------------------------------
0976 STRUCTURES
0977 ----------------------------------------------------------------------------*/
0978 struct drxjeq_stat {
0979     u16 eq_mse;
0980     u8 eq_mode;
0981     u8 eq_ctrl;
0982     u8 eq_stat;
0983 };
0984 
0985 /* HI command */
0986 struct drxj_hi_cmd {
0987     u16 cmd;
0988     u16 param1;
0989     u16 param2;
0990     u16 param3;
0991     u16 param4;
0992     u16 param5;
0993     u16 param6;
0994 };
0995 
0996 /*============================================================================*/
0997 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
0998 /*============================================================================*/
0999 
1000 /*
1001  * struct drxu_code_block_hdr - Structure of the microcode block headers
1002  *
1003  * @addr:   Destination address of the data in this block
1004  * @size:   Size of the block data following this header counted in
1005  *      16 bits words
1006  * @CRC:    CRC value of the data block, only valid if CRC flag is
1007  *      set.
1008  */
1009 struct drxu_code_block_hdr {
1010     u32 addr;
1011     u16 size;
1012     u16 flags;
1013     u16 CRC;
1014 };
1015 
1016 /*-----------------------------------------------------------------------------
1017 FUNCTIONS
1018 ----------------------------------------------------------------------------*/
1019 /* Some prototypes */
1020 static int
1021 hi_command(struct i2c_device_addr *dev_addr,
1022        const struct drxj_hi_cmd *cmd, u16 *result);
1023 
1024 static int
1025 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1026 
1027 static int
1028 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1029 
1030 static int power_down_aud(struct drx_demod_instance *demod);
1031 
1032 static int
1033 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1034 
1035 static int
1036 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1037 
1038 /*============================================================================*/
1039 /*============================================================================*/
1040 /*==                          HELPER FUNCTIONS                              ==*/
1041 /*============================================================================*/
1042 /*============================================================================*/
1043 
1044 
1045 /*============================================================================*/
1046 
1047 /*
1048 * \fn u32 frac28(u32 N, u32 D)
1049 * \brief Compute: (1<<28)*N/D
1050 * \param N 32 bits
1051 * \param D 32 bits
1052 * \return (1<<28)*N/D
1053 * This function is used to avoid floating-point calculations as they may
1054 * not be present on the target platform.
1055 
1056 * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1057 * fraction used for setting the Frequency Shifter registers.
1058 * N and D can hold numbers up to width: 28-bits.
1059 * The 4 bits integer part and the 28 bits fractional part are calculated.
1060 
1061 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1062 
1063 * N: 0...(1<<28)-1 = 268435454
1064 * D: 0...(1<<28)-1
1065 * Q: 0...(1<<32)-1
1066 */
1067 static u32 frac28(u32 N, u32 D)
1068 {
1069     int i = 0;
1070     u32 Q1 = 0;
1071     u32 R0 = 0;
1072 
1073     R0 = (N % D) << 4;  /* 32-28 == 4 shifts possible at max */
1074     Q1 = N / D;     /* integer part, only the 4 least significant bits
1075                    will be visible in the result */
1076 
1077     /* division using radix 16, 7 nibbles in the result */
1078     for (i = 0; i < 7; i++) {
1079         Q1 = (Q1 << 4) | R0 / D;
1080         R0 = (R0 % D) << 4;
1081     }
1082     /* rounding */
1083     if ((R0 >> 3) >= D)
1084         Q1++;
1085 
1086     return Q1;
1087 }
1088 
1089 /*
1090 * \fn u32 log1_times100( u32 x)
1091 * \brief Compute: 100*log10(x)
1092 * \param x 32 bits
1093 * \return 100*log10(x)
1094 *
1095 * 100*log10(x)
1096 * = 100*(log2(x)/log2(10)))
1097 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1098 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1099 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1100 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1101 *
1102 * where y = 2^k and 1<= (x/y) < 2
1103 */
1104 
1105 static u32 log1_times100(u32 x)
1106 {
1107     static const u8 scale = 15;
1108     static const u8 index_width = 5;
1109     /*
1110        log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1111        0 <= n < ((1<<INDEXWIDTH)+1)
1112      */
1113 
1114     static const u32 log2lut[] = {
1115         0,      /* 0.000000 */
1116         290941,     /* 290941.300628 */
1117         573196,     /* 573196.476418 */
1118         847269,     /* 847269.179851 */
1119         1113620,    /* 1113620.489452 */
1120         1372674,    /* 1372673.576986 */
1121         1624818,    /* 1624817.752104 */
1122         1870412,    /* 1870411.981536 */
1123         2109788,    /* 2109787.962654 */
1124         2343253,    /* 2343252.817465 */
1125         2571091,    /* 2571091.461923 */
1126         2793569,    /* 2793568.696416 */
1127         3010931,    /* 3010931.055901 */
1128         3223408,    /* 3223408.452106 */
1129         3431216,    /* 3431215.635215 */
1130         3634553,    /* 3634553.498355 */
1131         3833610,    /* 3833610.244726 */
1132         4028562,    /* 4028562.434393 */
1133         4219576,    /* 4219575.925308 */
1134         4406807,    /* 4406806.721144 */
1135         4590402,    /* 4590401.736809 */
1136         4770499,    /* 4770499.491025 */
1137         4947231,    /* 4947230.734179 */
1138         5120719,    /* 5120719.018555 */
1139         5291081,    /* 5291081.217197 */
1140         5458428,    /* 5458427.996830 */
1141         5622864,    /* 5622864.249668 */
1142         5784489,    /* 5784489.488298 */
1143         5943398,    /* 5943398.207380 */
1144         6099680,    /* 6099680.215452 */
1145         6253421,    /* 6253420.939751 */
1146         6404702,    /* 6404701.706649 */
1147         6553600,    /* 6553600.000000 */
1148     };
1149 
1150     u8 i = 0;
1151     u32 y = 0;
1152     u32 d = 0;
1153     u32 k = 0;
1154     u32 r = 0;
1155 
1156     if (x == 0)
1157         return 0;
1158 
1159     /* Scale x (normalize) */
1160     /* computing y in log(x/y) = log(x) - log(y) */
1161     if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1162         for (k = scale; k > 0; k--) {
1163             if (x & (((u32) 1) << scale))
1164                 break;
1165             x <<= 1;
1166         }
1167     } else {
1168         for (k = scale; k < 31; k++) {
1169             if ((x & (((u32) (-1)) << (scale + 1))) == 0)
1170                 break;
1171             x >>= 1;
1172         }
1173     }
1174     /*
1175        Now x has binary point between bit[scale] and bit[scale-1]
1176        and 1.0 <= x < 2.0 */
1177 
1178     /* correction for division: log(x) = log(x/y)+log(y) */
1179     y = k * ((((u32) 1) << scale) * 200);
1180 
1181     /* remove integer part */
1182     x &= ((((u32) 1) << scale) - 1);
1183     /* get index */
1184     i = (u8) (x >> (scale - index_width));
1185     /* compute delta (x-a) */
1186     d = x & ((((u32) 1) << (scale - index_width)) - 1);
1187     /* compute log, multiplication ( d* (.. )) must be within range ! */
1188     y += log2lut[i] +
1189         ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1190     /* Conver to log10() */
1191     y /= 108853;        /* (log2(10) << scale) */
1192     r = (y >> 1);
1193     /* rounding */
1194     if (y & ((u32)1))
1195         r++;
1196 
1197     return r;
1198 
1199 }
1200 
1201 /*
1202 * \fn u32 frac_times1e6( u16 N, u32 D)
1203 * \brief Compute: (N/D) * 1000000.
1204 * \param N nominator 16-bits.
1205 * \param D denominator 32-bits.
1206 * \return u32
1207 * \retval ((N/D) * 1000000), 32 bits
1208 *
1209 * No check on D=0!
1210 */
1211 static u32 frac_times1e6(u32 N, u32 D)
1212 {
1213     u32 remainder = 0;
1214     u32 frac = 0;
1215 
1216     /*
1217        frac = (N * 1000000) / D
1218        To let it fit in a 32 bits computation:
1219        frac = (N * (1000000 >> 4)) / (D >> 4)
1220        This would result in a problem in case D < 16 (div by 0).
1221        So we do it more elaborate as shown below.
1222      */
1223     frac = (((u32) N) * (1000000 >> 4)) / D;
1224     frac <<= 4;
1225     remainder = (((u32) N) * (1000000 >> 4)) % D;
1226     remainder <<= 4;
1227     frac += remainder / D;
1228     remainder = remainder % D;
1229     if ((remainder * 2) > D)
1230         frac++;
1231 
1232     return frac;
1233 }
1234 
1235 /*============================================================================*/
1236 
1237 
1238 /*
1239 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1240 *        and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1241 *
1242 */
1243 #if 0
1244 /* Currently, unused as we lack support for analog TV */
1245 static const u16 nicam_presc_table_val[43] = {
1246     1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1247     5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1248     18, 20, 23, 25, 28, 32, 36, 40, 45,
1249     51, 57, 64, 71, 80, 90, 101, 113, 127
1250 };
1251 #endif
1252 
1253 /*============================================================================*/
1254 /*==                        END HELPER FUNCTIONS                            ==*/
1255 /*============================================================================*/
1256 
1257 /*============================================================================*/
1258 /*============================================================================*/
1259 /*==                      DRXJ DAP FUNCTIONS                                ==*/
1260 /*============================================================================*/
1261 /*============================================================================*/
1262 
1263 /*
1264    This layer takes care of some device specific register access protocols:
1265    -conversion to short address format
1266    -access to audio block
1267    This layer is placed between the drx_dap_fasi and the rest of the drxj
1268    specific implementation. This layer can use address map knowledge whereas
1269    dap_fasi may not use memory map knowledge.
1270 
1271    * For audio currently only 16 bits read and write register access is
1272      supported. More is not needed. RMW and 32 or 8 bit access on audio
1273      registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1274      single/multi master) will be ignored.
1275 
1276    TODO: check ignoring single/multimaster is ok for AUD access ?
1277 */
1278 
1279 #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1280 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1281 /*============================================================================*/
1282 
1283 /*
1284 * \fn bool is_handled_by_aud_tr_if( u32 addr )
1285 * \brief Check if this address is handled by the audio token ring interface.
1286 * \param addr
1287 * \return bool
1288 * \retval true  Yes, handled by audio token ring interface
1289 * \retval false No, not handled by audio token ring interface
1290 *
1291 */
1292 static
1293 bool is_handled_by_aud_tr_if(u32 addr)
1294 {
1295     bool retval = false;
1296 
1297     if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1298         (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1299         (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1300         retval = true;
1301     }
1302 
1303     return retval;
1304 }
1305 
1306 /*============================================================================*/
1307 
1308 int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
1309                  u16 w_count,
1310                  u8 *wData,
1311                  struct i2c_device_addr *r_dev_addr,
1312                  u16 r_count, u8 *r_data)
1313 {
1314     struct drx39xxj_state *state;
1315     struct i2c_msg msg[2];
1316     unsigned int num_msgs;
1317 
1318     if (w_dev_addr == NULL) {
1319         /* Read only */
1320         state = r_dev_addr->user_data;
1321         msg[0].addr = r_dev_addr->i2c_addr >> 1;
1322         msg[0].flags = I2C_M_RD;
1323         msg[0].buf = r_data;
1324         msg[0].len = r_count;
1325         num_msgs = 1;
1326     } else if (r_dev_addr == NULL) {
1327         /* Write only */
1328         state = w_dev_addr->user_data;
1329         msg[0].addr = w_dev_addr->i2c_addr >> 1;
1330         msg[0].flags = 0;
1331         msg[0].buf = wData;
1332         msg[0].len = w_count;
1333         num_msgs = 1;
1334     } else {
1335         /* Both write and read */
1336         state = w_dev_addr->user_data;
1337         msg[0].addr = w_dev_addr->i2c_addr >> 1;
1338         msg[0].flags = 0;
1339         msg[0].buf = wData;
1340         msg[0].len = w_count;
1341         msg[1].addr = r_dev_addr->i2c_addr >> 1;
1342         msg[1].flags = I2C_M_RD;
1343         msg[1].buf = r_data;
1344         msg[1].len = r_count;
1345         num_msgs = 2;
1346     }
1347 
1348     if (state->i2c == NULL) {
1349         pr_err("i2c was zero, aborting\n");
1350         return 0;
1351     }
1352     if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
1353         pr_warn("drx3933: I2C write/read failed\n");
1354         return -EREMOTEIO;
1355     }
1356 
1357 #ifdef DJH_DEBUG
1358     if (w_dev_addr == NULL || r_dev_addr == NULL)
1359         return 0;
1360 
1361     state = w_dev_addr->user_data;
1362 
1363     if (state->i2c == NULL)
1364         return 0;
1365 
1366     msg[0].addr = w_dev_addr->i2c_addr;
1367     msg[0].flags = 0;
1368     msg[0].buf = wData;
1369     msg[0].len = w_count;
1370     msg[1].addr = r_dev_addr->i2c_addr;
1371     msg[1].flags = I2C_M_RD;
1372     msg[1].buf = r_data;
1373     msg[1].len = r_count;
1374     num_msgs = 2;
1375 
1376     pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
1377            w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
1378 
1379     if (i2c_transfer(state->i2c, msg, 2) != 2) {
1380         pr_warn("drx3933: I2C write/read failed\n");
1381         return -EREMOTEIO;
1382     }
1383 #endif
1384     return 0;
1385 }
1386 
1387 /*============================================================================*/
1388 
1389 /*****************************
1390 *
1391 * int drxdap_fasi_read_block (
1392 *      struct i2c_device_addr *dev_addr,      -- address of I2C device
1393 *      u32 addr,         -- address of chip register/memory
1394 *      u16            datasize,     -- number of bytes to read
1395 *      u8 *data,         -- data to receive
1396 *      u32 flags)        -- special device flags
1397 *
1398 * Read block data from chip address. Because the chip is word oriented,
1399 * the number of bytes to read must be even.
1400 *
1401 * Make sure that the buffer to receive the data is large enough.
1402 *
1403 * Although this function expects an even number of bytes, it is still byte
1404 * oriented, and the data read back is NOT translated to the endianness of
1405 * the target platform.
1406 *
1407 * Output:
1408 * - 0     if reading was successful
1409 *                  in that case: data read is in *data.
1410 * - -EIO  if anything went wrong
1411 *
1412 ******************************/
1413 
1414 static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
1415                      u32 addr,
1416                      u16 datasize,
1417                      u8 *data, u32 flags)
1418 {
1419     u8 buf[4];
1420     u16 bufx;
1421     int rc;
1422     u16 overhead_size = 0;
1423 
1424     /* Check parameters ******************************************************* */
1425     if (dev_addr == NULL)
1426         return -EINVAL;
1427 
1428     overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1429         (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1430 
1431     if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1432         ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1433          DRXDAP_FASI_LONG_FORMAT(addr)) ||
1434         (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1435         ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
1436         return -EINVAL;
1437     }
1438 
1439     /* ReadModifyWrite & mode flag bits are not allowed */
1440     flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
1441 #if DRXDAP_SINGLE_MASTER
1442     flags |= DRXDAP_FASI_SINGLE_MASTER;
1443 #endif
1444 
1445     /* Read block from I2C **************************************************** */
1446     do {
1447         u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
1448                   datasize : DRXDAP_MAX_RCHUNKSIZE);
1449 
1450         bufx = 0;
1451 
1452         addr &= ~DRXDAP_FASI_FLAGS;
1453         addr |= flags;
1454 
1455 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1456         /* short format address preferred but long format otherwise */
1457         if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1458 #endif
1459 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1460             buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1461             buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1462             buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1463             buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1464 #endif
1465 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1466         } else {
1467 #endif
1468 #if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
1469             buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1470             buf[bufx++] =
1471                 (u8) (((addr >> 16) & 0x0F) |
1472                     ((addr >> 18) & 0xF0));
1473 #endif
1474 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1475         }
1476 #endif
1477 
1478 #if DRXDAP_SINGLE_MASTER
1479         /*
1480          * In single master mode, split the read and write actions.
1481          * No special action is needed for write chunks here.
1482          */
1483         rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,
1484                        NULL, 0, NULL);
1485         if (rc == 0)
1486             rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data);
1487 #else
1488         /* In multi master mode, do everything in one RW action */
1489         rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
1490                       data);
1491 #endif
1492         data += todo;
1493         addr += (todo >> 1);
1494         datasize -= todo;
1495     } while (datasize && rc == 0);
1496 
1497     return rc;
1498 }
1499 
1500 
1501 /*****************************
1502 *
1503 * int drxdap_fasi_read_reg16 (
1504 *     struct i2c_device_addr *dev_addr, -- address of I2C device
1505 *     u32 addr,    -- address of chip register/memory
1506 *     u16 *data,    -- data to receive
1507 *     u32 flags)   -- special device flags
1508 *
1509 * Read one 16-bit register or memory location. The data received back is
1510 * converted back to the target platform's endianness.
1511 *
1512 * Output:
1513 * - 0     if reading was successful
1514 *                  in that case: read data is at *data
1515 * - -EIO  if anything went wrong
1516 *
1517 ******************************/
1518 
1519 static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
1520                      u32 addr,
1521                      u16 *data, u32 flags)
1522 {
1523     u8 buf[sizeof(*data)];
1524     int rc;
1525 
1526     if (!data)
1527         return -EINVAL;
1528 
1529     rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1530     *data = buf[0] + (((u16) buf[1]) << 8);
1531     return rc;
1532 }
1533 
1534 /*****************************
1535 *
1536 * int drxdap_fasi_read_reg32 (
1537 *     struct i2c_device_addr *dev_addr, -- address of I2C device
1538 *     u32 addr,    -- address of chip register/memory
1539 *     u32 *data,    -- data to receive
1540 *     u32 flags)   -- special device flags
1541 *
1542 * Read one 32-bit register or memory location. The data received back is
1543 * converted back to the target platform's endianness.
1544 *
1545 * Output:
1546 * - 0     if reading was successful
1547 *                  in that case: read data is at *data
1548 * - -EIO  if anything went wrong
1549 *
1550 ******************************/
1551 
1552 static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
1553                      u32 addr,
1554                      u32 *data, u32 flags)
1555 {
1556     u8 buf[sizeof(*data)];
1557     int rc;
1558 
1559     if (!data)
1560         return -EINVAL;
1561 
1562     rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1563     *data = (((u32) buf[0]) << 0) +
1564         (((u32) buf[1]) << 8) +
1565         (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
1566     return rc;
1567 }
1568 
1569 /*****************************
1570 *
1571 * int drxdap_fasi_write_block (
1572 *      struct i2c_device_addr *dev_addr,    -- address of I2C device
1573 *      u32 addr,       -- address of chip register/memory
1574 *      u16            datasize,   -- number of bytes to read
1575 *      u8 *data,       -- data to receive
1576 *      u32 flags)      -- special device flags
1577 *
1578 * Write block data to chip address. Because the chip is word oriented,
1579 * the number of bytes to write must be even.
1580 *
1581 * Although this function expects an even number of bytes, it is still byte
1582 * oriented, and the data being written is NOT translated from the endianness of
1583 * the target platform.
1584 *
1585 * Output:
1586 * - 0     if writing was successful
1587 * - -EIO  if anything went wrong
1588 *
1589 ******************************/
1590 
1591 static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
1592                       u32 addr,
1593                       u16 datasize,
1594                       u8 *data, u32 flags)
1595 {
1596     u8 buf[DRXDAP_MAX_WCHUNKSIZE];
1597     int st = -EIO;
1598     int first_err = 0;
1599     u16 overhead_size = 0;
1600     u16 block_size = 0;
1601 
1602     /* Check parameters ******************************************************* */
1603     if (dev_addr == NULL)
1604         return -EINVAL;
1605 
1606     overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1607         (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1608 
1609     if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1610         ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1611          DRXDAP_FASI_LONG_FORMAT(addr)) ||
1612         (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1613         ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
1614         return -EINVAL;
1615 
1616     flags &= DRXDAP_FASI_FLAGS;
1617     flags &= ~DRXDAP_FASI_MODEFLAGS;
1618 #if DRXDAP_SINGLE_MASTER
1619     flags |= DRXDAP_FASI_SINGLE_MASTER;
1620 #endif
1621 
1622     /* Write block to I2C ***************************************************** */
1623     block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
1624     do {
1625         u16 todo = 0;
1626         u16 bufx = 0;
1627 
1628         /* Buffer device address */
1629         addr &= ~DRXDAP_FASI_FLAGS;
1630         addr |= flags;
1631 #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1632         /* short format address preferred but long format otherwise */
1633         if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1634 #endif
1635 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
1636             buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1637             buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1638             buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1639             buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1640 #endif
1641 #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1642         } else {
1643 #endif
1644 #if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
1645             buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1646             buf[bufx++] =
1647                 (u8) (((addr >> 16) & 0x0F) |
1648                     ((addr >> 18) & 0xF0));
1649 #endif
1650 #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1651         }
1652 #endif
1653 
1654         /*
1655            In single master mode block_size can be 0. In such a case this I2C
1656            sequense will be visible: (1) write address {i2c addr,
1657            4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
1658            (3) write address (4) write data etc...
1659            Address must be rewritten because HI is reset after data transport and
1660            expects an address.
1661          */
1662         todo = (block_size < datasize ? block_size : datasize);
1663         if (todo == 0) {
1664             u16 overhead_size_i2c_addr = 0;
1665             u16 data_block_size = 0;
1666 
1667             overhead_size_i2c_addr =
1668                 (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
1669             data_block_size =
1670                 (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
1671 
1672             /* write device address */
1673             st = drxbsp_i2c_write_read(dev_addr,
1674                           (u16) (bufx),
1675                           buf,
1676                           (struct i2c_device_addr *)(NULL),
1677                           0, (u8 *)(NULL));
1678 
1679             if ((st != 0) && (first_err == 0)) {
1680                 /* at the end, return the first error encountered */
1681                 first_err = st;
1682             }
1683             bufx = 0;
1684             todo =
1685                 (data_block_size <
1686                  datasize ? data_block_size : datasize);
1687         }
1688         memcpy(&buf[bufx], data, todo);
1689         /* write (address if can do and) data */
1690         st = drxbsp_i2c_write_read(dev_addr,
1691                       (u16) (bufx + todo),
1692                       buf,
1693                       (struct i2c_device_addr *)(NULL),
1694                       0, (u8 *)(NULL));
1695 
1696         if ((st != 0) && (first_err == 0)) {
1697             /* at the end, return the first error encountered */
1698             first_err = st;
1699         }
1700         datasize -= todo;
1701         data += todo;
1702         addr += (todo >> 1);
1703     } while (datasize);
1704 
1705     return first_err;
1706 }
1707 
1708 /*****************************
1709 *
1710 * int drxdap_fasi_write_reg16 (
1711 *     struct i2c_device_addr *dev_addr, -- address of I2C device
1712 *     u32 addr,    -- address of chip register/memory
1713 *     u16            data,    -- data to send
1714 *     u32 flags)   -- special device flags
1715 *
1716 * Write one 16-bit register or memory location. The data being written is
1717 * converted from the target platform's endianness to little endian.
1718 *
1719 * Output:
1720 * - 0     if writing was successful
1721 * - -EIO  if anything went wrong
1722 *
1723 ******************************/
1724 
1725 static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
1726                       u32 addr,
1727                       u16 data, u32 flags)
1728 {
1729     u8 buf[sizeof(data)];
1730 
1731     buf[0] = (u8) ((data >> 0) & 0xFF);
1732     buf[1] = (u8) ((data >> 8) & 0xFF);
1733 
1734     return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1735 }
1736 
1737 /*****************************
1738 *
1739 * int drxdap_fasi_read_modify_write_reg16 (
1740 *      struct i2c_device_addr *dev_addr,   -- address of I2C device
1741 *      u32 waddr,     -- address of chip register/memory
1742 *      u32 raddr,     -- chip address to read back from
1743 *      u16            wdata,     -- data to send
1744 *      u16 *rdata)     -- data to receive back
1745 *
1746 * Write 16-bit data, then read back the original contents of that location.
1747 * Requires long addressing format to be allowed.
1748 *
1749 * Before sending data, the data is converted to little endian. The
1750 * data received back is converted back to the target platform's endianness.
1751 *
1752 * WARNING: This function is only guaranteed to work if there is one
1753 * master on the I2C bus.
1754 *
1755 * Output:
1756 * - 0     if reading was successful
1757 *                  in that case: read back data is at *rdata
1758 * - -EIO  if anything went wrong
1759 *
1760 ******************************/
1761 
1762 static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1763                             u32 waddr,
1764                             u32 raddr,
1765                             u16 wdata, u16 *rdata)
1766 {
1767     int rc = -EIO;
1768 
1769 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1770     if (rdata == NULL)
1771         return -EINVAL;
1772 
1773     rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
1774     if (rc == 0)
1775         rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
1776 #endif
1777 
1778     return rc;
1779 }
1780 
1781 /*****************************
1782 *
1783 * int drxdap_fasi_write_reg32 (
1784 *     struct i2c_device_addr *dev_addr, -- address of I2C device
1785 *     u32 addr,    -- address of chip register/memory
1786 *     u32            data,    -- data to send
1787 *     u32 flags)   -- special device flags
1788 *
1789 * Write one 32-bit register or memory location. The data being written is
1790 * converted from the target platform's endianness to little endian.
1791 *
1792 * Output:
1793 * - 0     if writing was successful
1794 * - -EIO  if anything went wrong
1795 *
1796 ******************************/
1797 
1798 static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
1799                       u32 addr,
1800                       u32 data, u32 flags)
1801 {
1802     u8 buf[sizeof(data)];
1803 
1804     buf[0] = (u8) ((data >> 0) & 0xFF);
1805     buf[1] = (u8) ((data >> 8) & 0xFF);
1806     buf[2] = (u8) ((data >> 16) & 0xFF);
1807     buf[3] = (u8) ((data >> 24) & 0xFF);
1808 
1809     return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1810 }
1811 
1812 /*============================================================================*/
1813 
1814 /*
1815 * \fn int drxj_dap_rm_write_reg16short
1816 * \brief Read modify write 16 bits audio register using short format only.
1817 * \param dev_addr
1818 * \param waddr    Address to write to
1819 * \param raddr    Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1820 * \param wdata    Data to write
1821 * \param rdata    Buffer for data to read
1822 * \return int
1823 * \retval 0 Success
1824 * \retval -EIO Timeout, I2C error, illegal bank
1825 *
1826 * 16 bits register read modify write access using short addressing format only.
1827 * Requires knowledge of the registermap, thus device dependent.
1828 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1829 *
1830 */
1831 
1832 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1833    See comments drxj_dap_read_modify_write_reg16 */
1834 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1835 static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1836                           u32 waddr,
1837                           u32 raddr,
1838                           u16 wdata, u16 *rdata)
1839 {
1840     int rc;
1841 
1842     if (rdata == NULL)
1843         return -EINVAL;
1844 
1845     /* Set RMW flag */
1846     rc = drxdap_fasi_write_reg16(dev_addr,
1847                           SIO_HI_RA_RAM_S0_FLG_ACC__A,
1848                           SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1849                           0x0000);
1850     if (rc == 0) {
1851         /* Write new data: triggers RMW */
1852         rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
1853                               0x0000);
1854     }
1855     if (rc == 0) {
1856         /* Read old data */
1857         rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
1858                              0x0000);
1859     }
1860     if (rc == 0) {
1861         /* Reset RMW flag */
1862         rc = drxdap_fasi_write_reg16(dev_addr,
1863                               SIO_HI_RA_RAM_S0_FLG_ACC__A,
1864                               0, 0x0000);
1865     }
1866 
1867     return rc;
1868 }
1869 #endif
1870 
1871 /*============================================================================*/
1872 
1873 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1874                          u32 waddr,
1875                          u32 raddr,
1876                          u16 wdata, u16 *rdata)
1877 {
1878     /* TODO: correct short/long addressing format decision,
1879        now long format has higher prio then short because short also
1880        needs virt bnks (not impl yet) for certain audio registers */
1881 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1882     return drxdap_fasi_read_modify_write_reg16(dev_addr,
1883                               waddr,
1884                               raddr, wdata, rdata);
1885 #else
1886     return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1887 #endif
1888 }
1889 
1890 
1891 /*============================================================================*/
1892 
1893 /*
1894 * \fn int drxj_dap_read_aud_reg16
1895 * \brief Read 16 bits audio register
1896 * \param dev_addr
1897 * \param addr
1898 * \param data
1899 * \return int
1900 * \retval 0 Success
1901 * \retval -EIO Timeout, I2C error, illegal bank
1902 *
1903 * 16 bits register read access via audio token ring interface.
1904 *
1905 */
1906 static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1907                      u32 addr, u16 *data)
1908 {
1909     u32 start_timer = 0;
1910     u32 current_timer = 0;
1911     u32 delta_timer = 0;
1912     u16 tr_status = 0;
1913     int stat = -EIO;
1914 
1915     /* No read possible for bank 3, return with error */
1916     if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1917         stat = -EINVAL;
1918     } else {
1919         const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1920 
1921         /* Force reset write bit */
1922         addr &= (~write_bit);
1923 
1924         /* Set up read */
1925         start_timer = jiffies_to_msecs(jiffies);
1926         do {
1927             /* RMW to aud TR IF until request is granted or timeout */
1928             stat = drxj_dap_read_modify_write_reg16(dev_addr,
1929                                  addr,
1930                                  SIO_HI_RA_RAM_S0_RMWBUF__A,
1931                                  0x0000, &tr_status);
1932 
1933             if (stat != 0)
1934                 break;
1935 
1936             current_timer = jiffies_to_msecs(jiffies);
1937             delta_timer = current_timer - start_timer;
1938             if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1939                 stat = -EIO;
1940                 break;
1941             }
1942 
1943         } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1944               AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1945              ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1946               AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1947     }           /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1948 
1949     /* Wait for read ready status or timeout */
1950     if (stat == 0) {
1951         start_timer = jiffies_to_msecs(jiffies);
1952 
1953         while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1954                AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1955             stat = drxj_dap_read_reg16(dev_addr,
1956                           AUD_TOP_TR_CTR__A,
1957                           &tr_status, 0x0000);
1958             if (stat != 0)
1959                 break;
1960 
1961             current_timer = jiffies_to_msecs(jiffies);
1962             delta_timer = current_timer - start_timer;
1963             if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1964                 stat = -EIO;
1965                 break;
1966             }
1967         }       /* while ( ... ) */
1968     }
1969 
1970     /* Read value */
1971     if (stat == 0)
1972         stat = drxj_dap_read_modify_write_reg16(dev_addr,
1973                              AUD_TOP_TR_RD_REG__A,
1974                              SIO_HI_RA_RAM_S0_RMWBUF__A,
1975                              0x0000, data);
1976     return stat;
1977 }
1978 
1979 /*============================================================================*/
1980 
1981 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1982                       u32 addr,
1983                       u16 *data, u32 flags)
1984 {
1985     int stat = -EIO;
1986 
1987     /* Check param */
1988     if ((dev_addr == NULL) || (data == NULL))
1989         return -EINVAL;
1990 
1991     if (is_handled_by_aud_tr_if(addr))
1992         stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1993     else
1994         stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
1995 
1996     return stat;
1997 }
1998 /*============================================================================*/
1999 
2000 /*
2001 * \fn int drxj_dap_write_aud_reg16
2002 * \brief Write 16 bits audio register
2003 * \param dev_addr
2004 * \param addr
2005 * \param data
2006 * \return int
2007 * \retval 0 Success
2008 * \retval -EIO Timeout, I2C error, illegal bank
2009 *
2010 * 16 bits register write access via audio token ring interface.
2011 *
2012 */
2013 static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
2014                       u32 addr, u16 data)
2015 {
2016     int stat = -EIO;
2017 
2018     /* No write possible for bank 2, return with error */
2019     if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
2020         stat = -EINVAL;
2021     } else {
2022         u32 start_timer = 0;
2023         u32 current_timer = 0;
2024         u32 delta_timer = 0;
2025         u16 tr_status = 0;
2026         const u32 write_bit = ((dr_xaddr_t) 1) << 16;
2027 
2028         /* Force write bit */
2029         addr |= write_bit;
2030         start_timer = jiffies_to_msecs(jiffies);
2031         do {
2032             /* RMW to aud TR IF until request is granted or timeout */
2033             stat = drxj_dap_read_modify_write_reg16(dev_addr,
2034                                  addr,
2035                                  SIO_HI_RA_RAM_S0_RMWBUF__A,
2036                                  data, &tr_status);
2037             if (stat != 0)
2038                 break;
2039 
2040             current_timer = jiffies_to_msecs(jiffies);
2041             delta_timer = current_timer - start_timer;
2042             if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
2043                 stat = -EIO;
2044                 break;
2045             }
2046 
2047         } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
2048               AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
2049              ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
2050               AUD_TOP_TR_CTR_FIFO_FULL_FULL));
2051 
2052     }           /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
2053 
2054     return stat;
2055 }
2056 
2057 /*============================================================================*/
2058 
2059 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
2060                        u32 addr,
2061                        u16 data, u32 flags)
2062 {
2063     int stat = -EIO;
2064 
2065     /* Check param */
2066     if (dev_addr == NULL)
2067         return -EINVAL;
2068 
2069     if (is_handled_by_aud_tr_if(addr))
2070         stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
2071     else
2072         stat = drxdap_fasi_write_reg16(dev_addr,
2073                                 addr, data, flags);
2074 
2075     return stat;
2076 }
2077 
2078 /*============================================================================*/
2079 
2080 /* Free data ram in SIO HI */
2081 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2082 #define SIO_HI_RA_RAM_USR_END__A   0x420060
2083 
2084 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2085 #define DRXJ_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2086 #define DRXJ_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2087 #define DRXJ_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2088 
2089 /*
2090 * \fn int drxj_dap_atomic_read_write_block()
2091 * \brief Basic access routine for atomic read or write access
2092 * \param dev_addr  pointer to i2c dev address
2093 * \param addr     destination/source address
2094 * \param datasize size of data buffer in bytes
2095 * \param data     pointer to data buffer
2096 * \return int
2097 * \retval 0 Success
2098 * \retval -EIO Timeout, I2C error, illegal bank
2099 *
2100 */
2101 static
2102 int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2103                       u32 addr,
2104                       u16 datasize,
2105                       u8 *data, bool read_flag)
2106 {
2107     struct drxj_hi_cmd hi_cmd;
2108     int rc;
2109     u16 word;
2110     u16 dummy = 0;
2111     u16 i = 0;
2112 
2113     /* Parameter check */
2114     if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2115         return -EINVAL;
2116 
2117     /* Set up HI parameters to read or write n bytes */
2118     hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2119     hi_cmd.param1 =
2120         (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2121              DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2122     hi_cmd.param2 =
2123         (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2124     hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2125     if (!read_flag)
2126         hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2127     else
2128         hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2129     hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2130                 DRXDAP_FASI_ADDR2BANK(addr));
2131     hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2132 
2133     if (!read_flag) {
2134         /* write data to buffer */
2135         for (i = 0; i < (datasize / 2); i++) {
2136 
2137             word = ((u16) data[2 * i]);
2138             word += (((u16) data[(2 * i) + 1]) << 8);
2139             drxj_dap_write_reg16(dev_addr,
2140                          (DRXJ_HI_ATOMIC_BUF_START + i),
2141                         word, 0);
2142         }
2143     }
2144 
2145     rc = hi_command(dev_addr, &hi_cmd, &dummy);
2146     if (rc != 0) {
2147         pr_err("error %d\n", rc);
2148         goto rw_error;
2149     }
2150 
2151     if (read_flag) {
2152         /* read data from buffer */
2153         for (i = 0; i < (datasize / 2); i++) {
2154             rc = drxj_dap_read_reg16(dev_addr,
2155                          (DRXJ_HI_ATOMIC_BUF_START + i),
2156                          &word, 0);
2157             if (rc) {
2158                 pr_err("error %d\n", rc);
2159                 goto rw_error;
2160             }
2161             data[2 * i] = (u8) (word & 0xFF);
2162             data[(2 * i) + 1] = (u8) (word >> 8);
2163         }
2164     }
2165 
2166     return 0;
2167 
2168 rw_error:
2169     return rc;
2170 
2171 }
2172 
2173 /*============================================================================*/
2174 
2175 /*
2176 * \fn int drxj_dap_atomic_read_reg32()
2177 * \brief Atomic read of 32 bits words
2178 */
2179 static
2180 int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2181                      u32 addr,
2182                      u32 *data, u32 flags)
2183 {
2184     u8 buf[sizeof(*data)] = { 0 };
2185     int rc;
2186     u32 word = 0;
2187 
2188     if (!data)
2189         return -EINVAL;
2190 
2191     rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2192                           sizeof(*data), buf, true);
2193 
2194     if (rc < 0)
2195         return 0;
2196 
2197     word = (u32) buf[3];
2198     word <<= 8;
2199     word |= (u32) buf[2];
2200     word <<= 8;
2201     word |= (u32) buf[1];
2202     word <<= 8;
2203     word |= (u32) buf[0];
2204 
2205     *data = word;
2206 
2207     return rc;
2208 }
2209 
2210 /*============================================================================*/
2211 
2212 /*============================================================================*/
2213 /*==                        END DRXJ DAP FUNCTIONS                          ==*/
2214 /*============================================================================*/
2215 
2216 /*============================================================================*/
2217 /*============================================================================*/
2218 /*==                      HOST INTERFACE FUNCTIONS                          ==*/
2219 /*============================================================================*/
2220 /*============================================================================*/
2221 
2222 /*
2223 * \fn int hi_cfg_command()
2224 * \brief Configure HI with settings stored in the demod structure.
2225 * \param demod Demodulator.
2226 * \return int.
2227 *
2228 * This routine was created because to much orthogonal settings have
2229 * been put into one HI API function (configure). Especially the I2C bridge
2230 * enable/disable should not need re-configuration of the HI.
2231 *
2232 */
2233 static int hi_cfg_command(const struct drx_demod_instance *demod)
2234 {
2235     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2236     struct drxj_hi_cmd hi_cmd;
2237     u16 result = 0;
2238     int rc;
2239 
2240     ext_attr = (struct drxj_data *) demod->my_ext_attr;
2241 
2242     hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2243     hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2244     hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2245     hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2246     hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2247     hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2248     hi_cmd.param6 = ext_attr->hi_cfg_transmit;
2249 
2250     rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
2251     if (rc != 0) {
2252         pr_err("error %d\n", rc);
2253         goto rw_error;
2254     }
2255 
2256     /* Reset power down flag (set one call only) */
2257     ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2258 
2259     return 0;
2260 
2261 rw_error:
2262     return rc;
2263 }
2264 
2265 /*
2266 * \fn int hi_command()
2267 * \brief Configure HI with settings stored in the demod structure.
2268 * \param dev_addr I2C address.
2269 * \param cmd HI command.
2270 * \param result HI command result.
2271 * \return int.
2272 *
2273 * Sends command to HI
2274 *
2275 */
2276 static int
2277 hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2278 {
2279     u16 wait_cmd = 0;
2280     u16 nr_retries = 0;
2281     bool powerdown_cmd = false;
2282     int rc;
2283 
2284     /* Write parameters */
2285     switch (cmd->cmd) {
2286 
2287     case SIO_HI_RA_RAM_CMD_CONFIG:
2288     case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2289         rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
2290         if (rc != 0) {
2291             pr_err("error %d\n", rc);
2292             goto rw_error;
2293         }
2294         rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
2295         if (rc != 0) {
2296             pr_err("error %d\n", rc);
2297             goto rw_error;
2298         }
2299         rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
2300         if (rc != 0) {
2301             pr_err("error %d\n", rc);
2302             goto rw_error;
2303         }
2304         rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
2305         if (rc != 0) {
2306             pr_err("error %d\n", rc);
2307             goto rw_error;
2308         }
2309         fallthrough;
2310     case SIO_HI_RA_RAM_CMD_BRDCTRL:
2311         rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
2312         if (rc != 0) {
2313             pr_err("error %d\n", rc);
2314             goto rw_error;
2315         }
2316         rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
2317         if (rc != 0) {
2318             pr_err("error %d\n", rc);
2319             goto rw_error;
2320         }
2321         fallthrough;
2322     case SIO_HI_RA_RAM_CMD_NULL:
2323         /* No parameters */
2324         break;
2325 
2326     default:
2327         return -EINVAL;
2328     }
2329 
2330     /* Write command */
2331     rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
2332     if (rc != 0) {
2333         pr_err("error %d\n", rc);
2334         goto rw_error;
2335     }
2336 
2337     if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2338         msleep(1);
2339 
2340     /* Detect power down to omit reading result */
2341     powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2342                   (((cmd->
2343                      param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2344                    == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2345     if (!powerdown_cmd) {
2346         /* Wait until command rdy */
2347         do {
2348             nr_retries++;
2349             if (nr_retries > DRXJ_MAX_RETRIES) {
2350                 pr_err("timeout\n");
2351                 goto rw_error;
2352             }
2353 
2354             rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
2355             if (rc != 0) {
2356                 pr_err("error %d\n", rc);
2357                 goto rw_error;
2358             }
2359         } while (wait_cmd != 0);
2360 
2361         /* Read result */
2362         rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
2363         if (rc != 0) {
2364             pr_err("error %d\n", rc);
2365             goto rw_error;
2366         }
2367 
2368     }
2369     /* if ( powerdown_cmd == true ) */
2370     return 0;
2371 rw_error:
2372     return rc;
2373 }
2374 
2375 /*
2376 * \fn int init_hi( const struct drx_demod_instance *demod )
2377 * \brief Initialise and configurate HI.
2378 * \param demod pointer to demod data.
2379 * \return int Return status.
2380 * \retval 0 Success.
2381 * \retval -EIO Failure.
2382 *
2383 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2384 * Need to store configuration in driver because of the way I2C
2385 * bridging is controlled.
2386 *
2387 */
2388 static int init_hi(const struct drx_demod_instance *demod)
2389 {
2390     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2391     struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2392     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2393     int rc;
2394 
2395     ext_attr = (struct drxj_data *) demod->my_ext_attr;
2396     common_attr = (struct drx_common_attr *) demod->my_common_attr;
2397     dev_addr = demod->my_i2c_dev_addr;
2398 
2399     /* PATCH for bug 5003, HI ucode v3.1.0 */
2400     rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);
2401     if (rc != 0) {
2402         pr_err("error %d\n", rc);
2403         goto rw_error;
2404     }
2405 
2406     /* Timing div, 250ns/Psys */
2407     /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2408     ext_attr->hi_cfg_timing_div =
2409         (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2410     /* Clipping */
2411     if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2412         ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2413     /* Bridge delay, uses oscilator clock */
2414     /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2415     /* SDA brdige delay */
2416     ext_attr->hi_cfg_bridge_delay =
2417         (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2418         1000;
2419     /* Clipping */
2420     if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2421         ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2422     /* SCL bridge delay, same as SDA for now */
2423     ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
2424                       SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2425     /* Wakeup key, setting the read flag (as suggest in the documentation) does
2426        not always result into a working solution (barebones worked VI2C failed).
2427        Not setting the bit works in all cases . */
2428     ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2429     /* port/bridge/power down ctrl */
2430     ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2431     /* transit mode time out delay and watch dog divider */
2432     ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2433 
2434     rc = hi_cfg_command(demod);
2435     if (rc != 0) {
2436         pr_err("error %d\n", rc);
2437         goto rw_error;
2438     }
2439 
2440     return 0;
2441 
2442 rw_error:
2443     return rc;
2444 }
2445 
2446 /*============================================================================*/
2447 /*==                   END HOST INTERFACE FUNCTIONS                         ==*/
2448 /*============================================================================*/
2449 
2450 /*============================================================================*/
2451 /*============================================================================*/
2452 /*==                        AUXILIARY FUNCTIONS                             ==*/
2453 /*============================================================================*/
2454 /*============================================================================*/
2455 
2456 /*
2457 * \fn int get_device_capabilities()
2458 * \brief Get and store device capabilities.
2459 * \param demod  Pointer to demodulator instance.
2460 * \return int.
2461 * \return 0    Success
2462 * \retval -EIO Failure
2463 *
2464 * Depending on pulldowns on MDx pins the following internals are set:
2465 *  * common_attr->osc_clock_freq
2466 *  * ext_attr->has_lna
2467 *  * ext_attr->has_ntsc
2468 *  * ext_attr->has_btsc
2469 *  * ext_attr->has_oob
2470 *
2471 */
2472 static int get_device_capabilities(struct drx_demod_instance *demod)
2473 {
2474     struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2475     struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2476     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2477     u16 sio_pdr_ohw_cfg = 0;
2478     u32 sio_top_jtagid_lo = 0;
2479     u16 bid = 0;
2480     int rc;
2481 
2482     common_attr = (struct drx_common_attr *) demod->my_common_attr;
2483     ext_attr = (struct drxj_data *) demod->my_ext_attr;
2484     dev_addr = demod->my_i2c_dev_addr;
2485 
2486     rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2487     if (rc != 0) {
2488         pr_err("error %d\n", rc);
2489         goto rw_error;
2490     }
2491     rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
2492     if (rc != 0) {
2493         pr_err("error %d\n", rc);
2494         goto rw_error;
2495     }
2496     rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2497     if (rc != 0) {
2498         pr_err("error %d\n", rc);
2499         goto rw_error;
2500     }
2501 
2502     switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2503     case 0:
2504         /* ignore (bypass ?) */
2505         break;
2506     case 1:
2507         /* 27 MHz */
2508         common_attr->osc_clock_freq = 27000;
2509         break;
2510     case 2:
2511         /* 20.25 MHz */
2512         common_attr->osc_clock_freq = 20250;
2513         break;
2514     case 3:
2515         /* 4 MHz */
2516         common_attr->osc_clock_freq = 4000;
2517         break;
2518     default:
2519         return -EIO;
2520     }
2521 
2522     /*
2523        Determine device capabilities
2524        Based on pinning v47
2525      */
2526     rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
2527     if (rc != 0) {
2528         pr_err("error %d\n", rc);
2529         goto rw_error;
2530     }
2531     ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2532 
2533     switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2534     case 0x31:
2535         rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2536         if (rc != 0) {
2537             pr_err("error %d\n", rc);
2538             goto rw_error;
2539         }
2540         rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
2541         if (rc != 0) {
2542             pr_err("error %d\n", rc);
2543             goto rw_error;
2544         }
2545         bid = (bid >> 10) & 0xf;
2546         rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2547         if (rc != 0) {
2548             pr_err("error %d\n", rc);
2549             goto rw_error;
2550         }
2551 
2552         ext_attr->has_lna = true;
2553         ext_attr->has_ntsc = false;
2554         ext_attr->has_btsc = false;
2555         ext_attr->has_oob = false;
2556         ext_attr->has_smatx = true;
2557         ext_attr->has_smarx = false;
2558         ext_attr->has_gpio = false;
2559         ext_attr->has_irqn = false;
2560         break;
2561     case 0x33:
2562         ext_attr->has_lna = false;
2563         ext_attr->has_ntsc = false;
2564         ext_attr->has_btsc = false;
2565         ext_attr->has_oob = false;
2566         ext_attr->has_smatx = true;
2567         ext_attr->has_smarx = false;
2568         ext_attr->has_gpio = false;
2569         ext_attr->has_irqn = false;
2570         break;
2571     case 0x45:
2572         ext_attr->has_lna = true;
2573         ext_attr->has_ntsc = true;
2574         ext_attr->has_btsc = false;
2575         ext_attr->has_oob = false;
2576         ext_attr->has_smatx = true;
2577         ext_attr->has_smarx = true;
2578         ext_attr->has_gpio = true;
2579         ext_attr->has_irqn = false;
2580         break;
2581     case 0x46:
2582         ext_attr->has_lna = false;
2583         ext_attr->has_ntsc = true;
2584         ext_attr->has_btsc = false;
2585         ext_attr->has_oob = false;
2586         ext_attr->has_smatx = true;
2587         ext_attr->has_smarx = true;
2588         ext_attr->has_gpio = true;
2589         ext_attr->has_irqn = false;
2590         break;
2591     case 0x41:
2592         ext_attr->has_lna = true;
2593         ext_attr->has_ntsc = true;
2594         ext_attr->has_btsc = true;
2595         ext_attr->has_oob = false;
2596         ext_attr->has_smatx = true;
2597         ext_attr->has_smarx = true;
2598         ext_attr->has_gpio = true;
2599         ext_attr->has_irqn = false;
2600         break;
2601     case 0x43:
2602         ext_attr->has_lna = false;
2603         ext_attr->has_ntsc = true;
2604         ext_attr->has_btsc = true;
2605         ext_attr->has_oob = false;
2606         ext_attr->has_smatx = true;
2607         ext_attr->has_smarx = true;
2608         ext_attr->has_gpio = true;
2609         ext_attr->has_irqn = false;
2610         break;
2611     case 0x32:
2612         ext_attr->has_lna = true;
2613         ext_attr->has_ntsc = false;
2614         ext_attr->has_btsc = false;
2615         ext_attr->has_oob = true;
2616         ext_attr->has_smatx = true;
2617         ext_attr->has_smarx = true;
2618         ext_attr->has_gpio = true;
2619         ext_attr->has_irqn = true;
2620         break;
2621     case 0x34:
2622         ext_attr->has_lna = false;
2623         ext_attr->has_ntsc = true;
2624         ext_attr->has_btsc = true;
2625         ext_attr->has_oob = true;
2626         ext_attr->has_smatx = true;
2627         ext_attr->has_smarx = true;
2628         ext_attr->has_gpio = true;
2629         ext_attr->has_irqn = true;
2630         break;
2631     case 0x42:
2632         ext_attr->has_lna = true;
2633         ext_attr->has_ntsc = true;
2634         ext_attr->has_btsc = true;
2635         ext_attr->has_oob = true;
2636         ext_attr->has_smatx = true;
2637         ext_attr->has_smarx = true;
2638         ext_attr->has_gpio = true;
2639         ext_attr->has_irqn = true;
2640         break;
2641     case 0x44:
2642         ext_attr->has_lna = false;
2643         ext_attr->has_ntsc = true;
2644         ext_attr->has_btsc = true;
2645         ext_attr->has_oob = true;
2646         ext_attr->has_smatx = true;
2647         ext_attr->has_smarx = true;
2648         ext_attr->has_gpio = true;
2649         ext_attr->has_irqn = true;
2650         break;
2651     default:
2652         /* Unknown device variant */
2653         return -EIO;
2654         break;
2655     }
2656 
2657     return 0;
2658 rw_error:
2659     return rc;
2660 }
2661 
2662 /*
2663 * \fn int power_up_device()
2664 * \brief Power up device.
2665 * \param demod  Pointer to demodulator instance.
2666 * \return int.
2667 * \return 0    Success
2668 * \retval -EIO Failure, I2C or max retries reached
2669 *
2670 */
2671 
2672 #ifndef DRXJ_MAX_RETRIES_POWERUP
2673 #define DRXJ_MAX_RETRIES_POWERUP 10
2674 #endif
2675 
2676 static int power_up_device(struct drx_demod_instance *demod)
2677 {
2678     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2679     u8 data = 0;
2680     u16 retry_count = 0;
2681     struct i2c_device_addr wake_up_addr;
2682 
2683     dev_addr = demod->my_i2c_dev_addr;
2684     wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2685     wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2686     wake_up_addr.user_data = dev_addr->user_data;
2687     /*
2688      * I2C access may fail in this case: no ack
2689      * dummy write must be used to wake uop device, dummy read must be used to
2690      * reset HI state machine (avoiding actual writes)
2691      */
2692     do {
2693         data = 0;
2694         drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
2695                       (struct i2c_device_addr *)(NULL), 0,
2696                      (u8 *)(NULL));
2697         msleep(10);
2698         retry_count++;
2699     } while ((drxbsp_i2c_write_read
2700           ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
2701            &data)
2702           != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2703 
2704     /* Need some recovery time .... */
2705     msleep(10);
2706 
2707     if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2708         return -EIO;
2709 
2710     return 0;
2711 }
2712 
2713 /*----------------------------------------------------------------------------*/
2714 /* MPEG Output Configuration Functions - begin                                */
2715 /*----------------------------------------------------------------------------*/
2716 /*
2717 * \fn int ctrl_set_cfg_mpeg_output()
2718 * \brief Set MPEG output configuration of the device.
2719 * \param devmod  Pointer to demodulator instance.
2720 * \param cfg_data Pointer to mpeg output configuaration.
2721 * \return int.
2722 *
2723 *  Configure MPEG output parameters.
2724 *
2725 */
2726 static int
2727 ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2728 {
2729     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2730     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2731     struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2732     int rc;
2733     u16 fec_oc_reg_mode = 0;
2734     u16 fec_oc_reg_ipr_mode = 0;
2735     u16 fec_oc_reg_ipr_invert = 0;
2736     u32 max_bit_rate = 0;
2737     u32 rcn_rate = 0;
2738     u32 nr_bits = 0;
2739     u16 sio_pdr_md_cfg = 0;
2740     /* data mask for the output data byte */
2741     u16 invert_data_mask =
2742         FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2743         FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2744         FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2745         FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2746 
2747     /* check arguments */
2748     if ((demod == NULL) || (cfg_data == NULL))
2749         return -EINVAL;
2750 
2751     dev_addr = demod->my_i2c_dev_addr;
2752     ext_attr = (struct drxj_data *) demod->my_ext_attr;
2753     common_attr = (struct drx_common_attr *) demod->my_common_attr;
2754 
2755     if (cfg_data->enable_mpeg_output == true) {
2756         /* quick and dirty patch to set MPEG in case current std is not
2757            producing MPEG */
2758         switch (ext_attr->standard) {
2759         case DRX_STANDARD_8VSB:
2760         case DRX_STANDARD_ITU_A:
2761         case DRX_STANDARD_ITU_B:
2762         case DRX_STANDARD_ITU_C:
2763             break;
2764         default:
2765             return 0;
2766         }
2767 
2768         rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
2769         if (rc != 0) {
2770             pr_err("error %d\n", rc);
2771             goto rw_error;
2772         }
2773         switch (ext_attr->standard) {
2774         case DRX_STANDARD_8VSB:
2775             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
2776             if (rc != 0) {
2777                 pr_err("error %d\n", rc);
2778                 goto rw_error;
2779             }   /* 2048 bytes fifo ram */
2780             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
2781             if (rc != 0) {
2782                 pr_err("error %d\n", rc);
2783                 goto rw_error;
2784             }
2785             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
2786             if (rc != 0) {
2787                 pr_err("error %d\n", rc);
2788                 goto rw_error;
2789             }
2790             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
2791             if (rc != 0) {
2792                 pr_err("error %d\n", rc);
2793                 goto rw_error;
2794             }
2795             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
2796             if (rc != 0) {
2797                 pr_err("error %d\n", rc);
2798                 goto rw_error;
2799             }
2800             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
2801             if (rc != 0) {
2802                 pr_err("error %d\n", rc);
2803                 goto rw_error;
2804             }
2805             /* Low Water Mark for synchronization  */
2806             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
2807             if (rc != 0) {
2808                 pr_err("error %d\n", rc);
2809                 goto rw_error;
2810             }
2811             /* High Water Mark for synchronization */
2812             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
2813             if (rc != 0) {
2814                 pr_err("error %d\n", rc);
2815                 goto rw_error;
2816             }
2817             break;
2818         case DRX_STANDARD_ITU_A:
2819         case DRX_STANDARD_ITU_C:
2820             switch (ext_attr->constellation) {
2821             case DRX_CONSTELLATION_QAM256:
2822                 nr_bits = 8;
2823                 break;
2824             case DRX_CONSTELLATION_QAM128:
2825                 nr_bits = 7;
2826                 break;
2827             case DRX_CONSTELLATION_QAM64:
2828                 nr_bits = 6;
2829                 break;
2830             case DRX_CONSTELLATION_QAM32:
2831                 nr_bits = 5;
2832                 break;
2833             case DRX_CONSTELLATION_QAM16:
2834                 nr_bits = 4;
2835                 break;
2836             default:
2837                 return -EIO;
2838             }   /* ext_attr->constellation */
2839             /* max_bit_rate = symbol_rate * nr_bits * coef */
2840             /* coef = 188/204                          */
2841             max_bit_rate =
2842                 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2843             fallthrough;    /* as b/c Annex A/C need following settings */
2844         case DRX_STANDARD_ITU_B:
2845             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
2846             if (rc != 0) {
2847                 pr_err("error %d\n", rc);
2848                 goto rw_error;
2849             }
2850             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
2851             if (rc != 0) {
2852                 pr_err("error %d\n", rc);
2853                 goto rw_error;
2854             }
2855             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
2856             if (rc != 0) {
2857                 pr_err("error %d\n", rc);
2858                 goto rw_error;
2859             }
2860             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
2861             if (rc != 0) {
2862                 pr_err("error %d\n", rc);
2863                 goto rw_error;
2864             }
2865             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
2866             if (rc != 0) {
2867                 pr_err("error %d\n", rc);
2868                 goto rw_error;
2869             }
2870             if (cfg_data->static_clk == true) {
2871                 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
2872                 if (rc != 0) {
2873                     pr_err("error %d\n", rc);
2874                     goto rw_error;
2875                 }
2876             } else {
2877                 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
2878                 if (rc != 0) {
2879                     pr_err("error %d\n", rc);
2880                     goto rw_error;
2881                 }
2882             }
2883             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
2884             if (rc != 0) {
2885                 pr_err("error %d\n", rc);
2886                 goto rw_error;
2887             }
2888             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
2889             if (rc != 0) {
2890                 pr_err("error %d\n", rc);
2891                 goto rw_error;
2892             }
2893             break;
2894         default:
2895             break;
2896         }       /* switch (standard) */
2897 
2898         /* Check insertion of the Reed-Solomon parity bytes */
2899         rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
2900         if (rc != 0) {
2901             pr_err("error %d\n", rc);
2902             goto rw_error;
2903         }
2904         rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
2905         if (rc != 0) {
2906             pr_err("error %d\n", rc);
2907             goto rw_error;
2908         }
2909         if (cfg_data->insert_rs_byte == true) {
2910             /* enable parity symbol forward */
2911             fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2912             /* MVAL disable during parity bytes */
2913             fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2914             switch (ext_attr->standard) {
2915             case DRX_STANDARD_8VSB:
2916                 rcn_rate = 0x004854D3;
2917                 break;
2918             case DRX_STANDARD_ITU_B:
2919                 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2920                 switch (ext_attr->constellation) {
2921                 case DRX_CONSTELLATION_QAM256:
2922                     rcn_rate = 0x008945E7;
2923                     break;
2924                 case DRX_CONSTELLATION_QAM64:
2925                     rcn_rate = 0x005F64D4;
2926                     break;
2927                 default:
2928                     return -EIO;
2929                 }
2930                 break;
2931             case DRX_STANDARD_ITU_A:
2932             case DRX_STANDARD_ITU_C:
2933                 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2934                 rcn_rate =
2935                     (frac28
2936                      (max_bit_rate,
2937                       (u32) (common_attr->sys_clock_freq / 8))) /
2938                     188;
2939                 break;
2940             default:
2941                 return -EIO;
2942             }   /* ext_attr->standard */
2943         } else {    /* insert_rs_byte == false */
2944 
2945             /* disable parity symbol forward */
2946             fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2947             /* MVAL enable during parity bytes */
2948             fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2949             switch (ext_attr->standard) {
2950             case DRX_STANDARD_8VSB:
2951                 rcn_rate = 0x0041605C;
2952                 break;
2953             case DRX_STANDARD_ITU_B:
2954                 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2955                 switch (ext_attr->constellation) {
2956                 case DRX_CONSTELLATION_QAM256:
2957                     rcn_rate = 0x0082D6A0;
2958                     break;
2959                 case DRX_CONSTELLATION_QAM64:
2960                     rcn_rate = 0x005AEC1A;
2961                     break;
2962                 default:
2963                     return -EIO;
2964                 }
2965                 break;
2966             case DRX_STANDARD_ITU_A:
2967             case DRX_STANDARD_ITU_C:
2968                 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2969                 rcn_rate =
2970                     (frac28
2971                      (max_bit_rate,
2972                       (u32) (common_attr->sys_clock_freq / 8))) /
2973                     204;
2974                 break;
2975             default:
2976                 return -EIO;
2977             }   /* ext_attr->standard */
2978         }
2979 
2980         if (cfg_data->enable_parallel == true) {    /* MPEG data output is parallel -> clear ipr_mode[0] */
2981             fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2982         } else {    /* MPEG data output is serial -> set ipr_mode[0] */
2983             fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2984         }
2985 
2986         /* Control slective inversion of output bits */
2987         if (cfg_data->invert_data == true)
2988             fec_oc_reg_ipr_invert |= invert_data_mask;
2989         else
2990             fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2991 
2992         if (cfg_data->invert_err == true)
2993             fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2994         else
2995             fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2996 
2997         if (cfg_data->invert_str == true)
2998             fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2999         else
3000             fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
3001 
3002         if (cfg_data->invert_val == true)
3003             fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
3004         else
3005             fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
3006 
3007         if (cfg_data->invert_clk == true)
3008             fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
3009         else
3010             fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
3011 
3012 
3013         if (cfg_data->static_clk == true) { /* Static mode */
3014             u32 dto_rate = 0;
3015             u32 bit_rate = 0;
3016             u16 fec_oc_dto_burst_len = 0;
3017             u16 fec_oc_dto_period = 0;
3018 
3019             fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
3020 
3021             switch (ext_attr->standard) {
3022             case DRX_STANDARD_8VSB:
3023                 fec_oc_dto_period = 4;
3024                 if (cfg_data->insert_rs_byte == true)
3025                     fec_oc_dto_burst_len = 208;
3026                 break;
3027             case DRX_STANDARD_ITU_A:
3028                 {
3029                     u32 symbol_rate_th = 6400000;
3030                     if (cfg_data->insert_rs_byte == true) {
3031                         fec_oc_dto_burst_len = 204;
3032                         symbol_rate_th = 5900000;
3033                     }
3034                     if (ext_attr->curr_symbol_rate >=
3035                         symbol_rate_th) {
3036                         fec_oc_dto_period = 0;
3037                     } else {
3038                         fec_oc_dto_period = 1;
3039                     }
3040                 }
3041                 break;
3042             case DRX_STANDARD_ITU_B:
3043                 fec_oc_dto_period = 1;
3044                 if (cfg_data->insert_rs_byte == true)
3045                     fec_oc_dto_burst_len = 128;
3046                 break;
3047             case DRX_STANDARD_ITU_C:
3048                 fec_oc_dto_period = 1;
3049                 if (cfg_data->insert_rs_byte == true)
3050                     fec_oc_dto_burst_len = 204;
3051                 break;
3052             default:
3053                 return -EIO;
3054             }
3055             bit_rate =
3056                 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
3057                                    2);
3058             dto_rate =
3059                 frac28(bit_rate, common_attr->sys_clock_freq * 1000);
3060             dto_rate >>= 3;
3061             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
3062             if (rc != 0) {
3063                 pr_err("error %d\n", rc);
3064                 goto rw_error;
3065             }
3066             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
3067             if (rc != 0) {
3068                 pr_err("error %d\n", rc);
3069                 goto rw_error;
3070             }
3071             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
3072             if (rc != 0) {
3073                 pr_err("error %d\n", rc);
3074                 goto rw_error;
3075             }
3076             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
3077             if (rc != 0) {
3078                 pr_err("error %d\n", rc);
3079                 goto rw_error;
3080             }
3081             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
3082             if (rc != 0) {
3083                 pr_err("error %d\n", rc);
3084                 goto rw_error;
3085             }
3086             if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3087                 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
3088             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
3089             if (rc != 0) {
3090                 pr_err("error %d\n", rc);
3091                 goto rw_error;
3092             }
3093         } else {    /* Dynamic mode */
3094 
3095             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
3096             if (rc != 0) {
3097                 pr_err("error %d\n", rc);
3098                 goto rw_error;
3099             }
3100             rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
3101             if (rc != 0) {
3102                 pr_err("error %d\n", rc);
3103                 goto rw_error;
3104             }
3105         }
3106 
3107         rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
3108         if (rc != 0) {
3109             pr_err("error %d\n", rc);
3110             goto rw_error;
3111         }
3112 
3113         /* Write appropriate registers with requested configuration */
3114         rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
3115         if (rc != 0) {
3116             pr_err("error %d\n", rc);
3117             goto rw_error;
3118         }
3119         rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
3120         if (rc != 0) {
3121             pr_err("error %d\n", rc);
3122             goto rw_error;
3123         }
3124         rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
3125         if (rc != 0) {
3126             pr_err("error %d\n", rc);
3127             goto rw_error;
3128         }
3129 
3130         /* enabling for both parallel and serial now */
3131         /*  Write magic word to enable pdr reg write */
3132         rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3133         if (rc != 0) {
3134             pr_err("error %d\n", rc);
3135             goto rw_error;
3136         }
3137         /*  Set MPEG TS pads to outputmode */
3138         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
3139         if (rc != 0) {
3140             pr_err("error %d\n", rc);
3141             goto rw_error;
3142         }
3143         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
3144         if (rc != 0) {
3145             pr_err("error %d\n", rc);
3146             goto rw_error;
3147         }
3148         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B | 0x03 << SIO_PDR_MCLK_CFG_MODE__B, 0);
3149         if (rc != 0) {
3150             pr_err("error %d\n", rc);
3151             goto rw_error;
3152         }
3153         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
3154         if (rc != 0) {
3155             pr_err("error %d\n", rc);
3156             goto rw_error;
3157         }
3158         sio_pdr_md_cfg =
3159             MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3160             SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3161         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3162         if (rc != 0) {
3163             pr_err("error %d\n", rc);
3164             goto rw_error;
3165         }
3166         if (cfg_data->enable_parallel == true) {    /* MPEG data output is parallel -> set MD1 to MD7 to output mode */
3167             sio_pdr_md_cfg =
3168                 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3169                 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3170                 SIO_PDR_MD0_CFG_MODE__B;
3171             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3172             if (rc != 0) {
3173                 pr_err("error %d\n", rc);
3174                 goto rw_error;
3175             }
3176             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
3177             if (rc != 0) {
3178                 pr_err("error %d\n", rc);
3179                 goto rw_error;
3180             }
3181             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
3182             if (rc != 0) {
3183                 pr_err("error %d\n", rc);
3184                 goto rw_error;
3185             }
3186             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
3187             if (rc != 0) {
3188                 pr_err("error %d\n", rc);
3189                 goto rw_error;
3190             }
3191             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
3192             if (rc != 0) {
3193                 pr_err("error %d\n", rc);
3194                 goto rw_error;
3195             }
3196             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
3197             if (rc != 0) {
3198                 pr_err("error %d\n", rc);
3199                 goto rw_error;
3200             }
3201             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
3202             if (rc != 0) {
3203                 pr_err("error %d\n", rc);
3204                 goto rw_error;
3205             }
3206             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
3207             if (rc != 0) {
3208                 pr_err("error %d\n", rc);
3209                 goto rw_error;
3210             }
3211         } else {    /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3212             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3213             if (rc != 0) {
3214                 pr_err("error %d\n", rc);
3215                 goto rw_error;
3216             }
3217             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3218             if (rc != 0) {
3219                 pr_err("error %d\n", rc);
3220                 goto rw_error;
3221             }
3222             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3223             if (rc != 0) {
3224                 pr_err("error %d\n", rc);
3225                 goto rw_error;
3226             }
3227             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3228             if (rc != 0) {
3229                 pr_err("error %d\n", rc);
3230                 goto rw_error;
3231             }
3232             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3233             if (rc != 0) {
3234                 pr_err("error %d\n", rc);
3235                 goto rw_error;
3236             }
3237             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3238             if (rc != 0) {
3239                 pr_err("error %d\n", rc);
3240                 goto rw_error;
3241             }
3242             rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3243             if (rc != 0) {
3244                 pr_err("error %d\n", rc);
3245                 goto rw_error;
3246             }
3247         }
3248         /*  Enable Monitor Bus output over MPEG pads and ctl input */
3249         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3250         if (rc != 0) {
3251             pr_err("error %d\n", rc);
3252             goto rw_error;
3253         }
3254         /*  Write nomagic word to enable pdr reg write */
3255         rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3256         if (rc != 0) {
3257             pr_err("error %d\n", rc);
3258             goto rw_error;
3259         }
3260     } else {
3261         /*  Write magic word to enable pdr reg write */
3262         rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3263         if (rc != 0) {
3264             pr_err("error %d\n", rc);
3265             goto rw_error;
3266         }
3267         /*  Set MPEG TS pads to inputmode */
3268         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
3269         if (rc != 0) {
3270             pr_err("error %d\n", rc);
3271             goto rw_error;
3272         }
3273         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
3274         if (rc != 0) {
3275             pr_err("error %d\n", rc);
3276             goto rw_error;
3277         }
3278         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
3279         if (rc != 0) {
3280             pr_err("error %d\n", rc);
3281             goto rw_error;
3282         }
3283         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
3284         if (rc != 0) {
3285             pr_err("error %d\n", rc);
3286             goto rw_error;
3287         }
3288         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
3289         if (rc != 0) {
3290             pr_err("error %d\n", rc);
3291             goto rw_error;
3292         }
3293         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3294         if (rc != 0) {
3295             pr_err("error %d\n", rc);
3296             goto rw_error;
3297         }
3298         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3299         if (rc != 0) {
3300             pr_err("error %d\n", rc);
3301             goto rw_error;
3302         }
3303         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3304         if (rc != 0) {
3305             pr_err("error %d\n", rc);
3306             goto rw_error;
3307         }
3308         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3309         if (rc != 0) {
3310             pr_err("error %d\n", rc);
3311             goto rw_error;
3312         }
3313         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3314         if (rc != 0) {
3315             pr_err("error %d\n", rc);
3316             goto rw_error;
3317         }
3318         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3319         if (rc != 0) {
3320             pr_err("error %d\n", rc);
3321             goto rw_error;
3322         }
3323         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3324         if (rc != 0) {
3325             pr_err("error %d\n", rc);
3326             goto rw_error;
3327         }
3328         /* Enable Monitor Bus output over MPEG pads and ctl input */
3329         rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3330         if (rc != 0) {
3331             pr_err("error %d\n", rc);
3332             goto rw_error;
3333         }
3334         /* Write nomagic word to enable pdr reg write */
3335         rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3336         if (rc != 0) {
3337             pr_err("error %d\n", rc);
3338             goto rw_error;
3339         }
3340     }
3341 
3342     /* save values for restore after re-acquire */
3343     common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3344 
3345     return 0;
3346 rw_error:
3347     return rc;
3348 }
3349 
3350 /*----------------------------------------------------------------------------*/
3351 
3352 
3353 /*----------------------------------------------------------------------------*/
3354 /* MPEG Output Configuration Functions - end                                  */
3355 /*----------------------------------------------------------------------------*/
3356 
3357 /*----------------------------------------------------------------------------*/
3358 /* miscellaneous configurations - begin                           */
3359 /*----------------------------------------------------------------------------*/
3360 
3361 /*
3362 * \fn int set_mpegtei_handling()
3363 * \brief Activate MPEG TEI handling settings.
3364 * \param devmod  Pointer to demodulator instance.
3365 * \return int.
3366 *
3367 * This routine should be called during a set channel of QAM/VSB
3368 *
3369 */
3370 static int set_mpegtei_handling(struct drx_demod_instance *demod)
3371 {
3372     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3373     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3374     int rc;
3375     u16 fec_oc_dpr_mode = 0;
3376     u16 fec_oc_snc_mode = 0;
3377     u16 fec_oc_ems_mode = 0;
3378 
3379     dev_addr = demod->my_i2c_dev_addr;
3380     ext_attr = (struct drxj_data *) demod->my_ext_attr;
3381 
3382     rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
3383     if (rc != 0) {
3384         pr_err("error %d\n", rc);
3385         goto rw_error;
3386     }
3387     rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
3388     if (rc != 0) {
3389         pr_err("error %d\n", rc);
3390         goto rw_error;
3391     }
3392     rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
3393     if (rc != 0) {
3394         pr_err("error %d\n", rc);
3395         goto rw_error;
3396     }
3397 
3398     /* reset to default, allow TEI bit to be changed */
3399     fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3400     fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3401                FEC_OC_SNC_MODE_CORR_DISABLE__M));
3402     fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3403 
3404     if (ext_attr->disable_te_ihandling) {
3405         /* do not change TEI bit */
3406         fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3407         fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3408             ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3409         fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3410     }
3411 
3412     rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
3413     if (rc != 0) {
3414         pr_err("error %d\n", rc);
3415         goto rw_error;
3416     }
3417     rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
3418     if (rc != 0) {
3419         pr_err("error %d\n", rc);
3420         goto rw_error;
3421     }
3422     rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
3423     if (rc != 0) {
3424         pr_err("error %d\n", rc);
3425         goto rw_error;
3426     }
3427 
3428     return 0;
3429 rw_error:
3430     return rc;
3431 }
3432 
3433 /*----------------------------------------------------------------------------*/
3434 /*
3435 * \fn int bit_reverse_mpeg_output()
3436 * \brief Set MPEG output bit-endian settings.
3437 * \param devmod  Pointer to demodulator instance.
3438 * \return int.
3439 *
3440 * This routine should be called during a set channel of QAM/VSB
3441 *
3442 */
3443 static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3444 {
3445     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3446     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3447     int rc;
3448     u16 fec_oc_ipr_mode = 0;
3449 
3450     dev_addr = demod->my_i2c_dev_addr;
3451     ext_attr = (struct drxj_data *) demod->my_ext_attr;
3452 
3453     rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
3454     if (rc != 0) {
3455         pr_err("error %d\n", rc);
3456         goto rw_error;
3457     }
3458 
3459     /* reset to default (normal bit order) */
3460     fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3461 
3462     if (ext_attr->bit_reverse_mpeg_outout)
3463         fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3464 
3465     rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
3466     if (rc != 0) {
3467         pr_err("error %d\n", rc);
3468         goto rw_error;
3469     }
3470 
3471     return 0;
3472 rw_error:
3473     return rc;
3474 }
3475 
3476 /*----------------------------------------------------------------------------*/
3477 /*
3478 * \fn int set_mpeg_start_width()
3479 * \brief Set MPEG start width.
3480 * \param devmod  Pointer to demodulator instance.
3481 * \return int.
3482 *
3483 * This routine should be called during a set channel of QAM/VSB
3484 *
3485 */
3486 static int set_mpeg_start_width(struct drx_demod_instance *demod)
3487 {
3488     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3489     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3490     struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3491     int rc;
3492     u16 fec_oc_comm_mb = 0;
3493 
3494     dev_addr = demod->my_i2c_dev_addr;
3495     ext_attr = (struct drxj_data *) demod->my_ext_attr;
3496     common_attr = demod->my_common_attr;
3497 
3498     if ((common_attr->mpeg_cfg.static_clk == true)
3499         && (common_attr->mpeg_cfg.enable_parallel == false)) {
3500         rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
3501         if (rc != 0) {
3502             pr_err("error %d\n", rc);
3503             goto rw_error;
3504         }
3505         fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3506         if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3507             fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3508         rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
3509         if (rc != 0) {
3510             pr_err("error %d\n", rc);
3511             goto rw_error;
3512         }
3513     }
3514 
3515     return 0;
3516 rw_error:
3517     return rc;
3518 }
3519 
3520 /*----------------------------------------------------------------------------*/
3521 /* miscellaneous configurations - end                             */
3522 /*----------------------------------------------------------------------------*/
3523 
3524 /*----------------------------------------------------------------------------*/
3525 /* UIO Configuration Functions - begin                                        */
3526 /*----------------------------------------------------------------------------*/
3527 /*
3528 * \fn int ctrl_set_uio_cfg()
3529 * \brief Configure modus oprandi UIO.
3530 * \param demod Pointer to demodulator instance.
3531 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3532 * \return int.
3533 */
3534 static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3535 {
3536     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3537     int rc;
3538 
3539     if ((uio_cfg == NULL) || (demod == NULL))
3540         return -EINVAL;
3541 
3542     ext_attr = (struct drxj_data *) demod->my_ext_attr;
3543 
3544     /*  Write magic word to enable pdr reg write               */
3545     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3546     if (rc != 0) {
3547         pr_err("error %d\n", rc);
3548         goto rw_error;
3549     }
3550     switch (uio_cfg->uio) {
3551       /*====================================================================*/
3552     case DRX_UIO1:
3553         /* DRX_UIO1: SMA_TX UIO-1 */
3554         if (!ext_attr->has_smatx)
3555             return -EIO;
3556         switch (uio_cfg->mode) {
3557         case DRX_UIO_MODE_FIRMWARE_SMA:
3558         case DRX_UIO_MODE_FIRMWARE_SAW:
3559         case DRX_UIO_MODE_READWRITE:
3560             ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3561             break;
3562         case DRX_UIO_MODE_DISABLE:
3563             ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3564             /* pad configuration register is set 0 - input mode */
3565             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
3566             if (rc != 0) {
3567                 pr_err("error %d\n", rc);
3568                 goto rw_error;
3569             }
3570             break;
3571         default:
3572             return -EINVAL;
3573         }       /* switch ( uio_cfg->mode ) */
3574         break;
3575       /*====================================================================*/
3576     case DRX_UIO2:
3577         /* DRX_UIO2: SMA_RX UIO-2 */
3578         if (!ext_attr->has_smarx)
3579             return -EIO;
3580         switch (uio_cfg->mode) {
3581         case DRX_UIO_MODE_FIRMWARE0:
3582         case DRX_UIO_MODE_READWRITE:
3583             ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3584             break;
3585         case DRX_UIO_MODE_DISABLE:
3586             ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3587             /* pad configuration register is set 0 - input mode */
3588             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
3589             if (rc != 0) {
3590                 pr_err("error %d\n", rc);
3591                 goto rw_error;
3592             }
3593             break;
3594         default:
3595             return -EINVAL;
3596         }       /* switch ( uio_cfg->mode ) */
3597         break;
3598       /*====================================================================*/
3599     case DRX_UIO3:
3600         /* DRX_UIO3: GPIO UIO-3 */
3601         if (!ext_attr->has_gpio)
3602             return -EIO;
3603         switch (uio_cfg->mode) {
3604         case DRX_UIO_MODE_FIRMWARE0:
3605         case DRX_UIO_MODE_READWRITE:
3606             ext_attr->uio_gpio_mode = uio_cfg->mode;
3607             break;
3608         case DRX_UIO_MODE_DISABLE:
3609             ext_attr->uio_gpio_mode = uio_cfg->mode;
3610             /* pad configuration register is set 0 - input mode */
3611             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
3612             if (rc != 0) {
3613                 pr_err("error %d\n", rc);
3614                 goto rw_error;
3615             }
3616             break;
3617         default:
3618             return -EINVAL;
3619         }       /* switch ( uio_cfg->mode ) */
3620         break;
3621       /*====================================================================*/
3622     case DRX_UIO4:
3623         /* DRX_UIO4: IRQN UIO-4 */
3624         if (!ext_attr->has_irqn)
3625             return -EIO;
3626         switch (uio_cfg->mode) {
3627         case DRX_UIO_MODE_READWRITE:
3628             ext_attr->uio_irqn_mode = uio_cfg->mode;
3629             break;
3630         case DRX_UIO_MODE_DISABLE:
3631             /* pad configuration register is set 0 - input mode */
3632             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
3633             if (rc != 0) {
3634                 pr_err("error %d\n", rc);
3635                 goto rw_error;
3636             }
3637             ext_attr->uio_irqn_mode = uio_cfg->mode;
3638             break;
3639         case DRX_UIO_MODE_FIRMWARE0:
3640         default:
3641             return -EINVAL;
3642         }       /* switch ( uio_cfg->mode ) */
3643         break;
3644       /*====================================================================*/
3645     default:
3646         return -EINVAL;
3647     }           /* switch ( uio_cfg->uio ) */
3648 
3649     /*  Write magic word to disable pdr reg write               */
3650     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3651     if (rc != 0) {
3652         pr_err("error %d\n", rc);
3653         goto rw_error;
3654     }
3655 
3656     return 0;
3657 rw_error:
3658     return rc;
3659 }
3660 
3661 /*
3662 * \fn int ctrl_uio_write()
3663 * \brief Write to a UIO.
3664 * \param demod Pointer to demodulator instance.
3665 * \param uio_data Pointer to data container for a certain UIO.
3666 * \return int.
3667 */
3668 static int
3669 ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3670 {
3671     struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3672     int rc;
3673     u16 pin_cfg_value = 0;
3674     u16 value = 0;
3675 
3676     if ((uio_data == NULL) || (demod == NULL))
3677         return -EINVAL;
3678 
3679     ext_attr = (struct drxj_data *) demod->my_ext_attr;
3680 
3681     /*  Write magic word to enable pdr reg write               */
3682     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3683     if (rc != 0) {
3684         pr_err("error %d\n", rc);
3685         goto rw_error;
3686     }
3687     switch (uio_data->uio) {
3688       /*====================================================================*/
3689     case DRX_UIO1:
3690         /* DRX_UIO1: SMA_TX UIO-1 */
3691         if (!ext_attr->has_smatx)
3692             return -EIO;
3693         if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3694             && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3695             return -EIO;
3696         }
3697         pin_cfg_value = 0;
3698         /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3699         pin_cfg_value |= 0x0113;
3700         /* io_pad_cfg_mode output mode is drive always */
3701         /* io_pad_cfg_drive is set to power 2 (23 mA) */
3702 
3703         /* write to io pad configuration register - output mode */
3704         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
3705         if (rc != 0) {
3706             pr_err("error %d\n", rc);
3707             goto rw_error;
3708         }
3709 
3710         /* use corresponding bit in io data output registar */
3711         rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3712         if (rc != 0) {
3713             pr_err("error %d\n", rc);
3714             goto rw_error;
3715         }
3716         if (!uio_data->value)
3717             value &= 0x7FFF;    /* write zero to 15th bit - 1st UIO */
3718         else
3719             value |= 0x8000;    /* write one to 15th bit - 1st UIO */
3720 
3721         /* write back to io data output register */
3722         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3723         if (rc != 0) {
3724             pr_err("error %d\n", rc);
3725             goto rw_error;
3726         }
3727         break;
3728    /*======================================================================*/
3729     case DRX_UIO2:
3730         /* DRX_UIO2: SMA_RX UIO-2 */
3731         if (!ext_attr->has_smarx)
3732             return -EIO;
3733         if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3734             return -EIO;
3735 
3736         pin_cfg_value = 0;
3737         /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3738         pin_cfg_value |= 0x0113;
3739         /* io_pad_cfg_mode output mode is drive always */
3740         /* io_pad_cfg_drive is set to power 2 (23 mA) */
3741 
3742         /* write to io pad configuration register - output mode */
3743         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
3744         if (rc != 0) {
3745             pr_err("error %d\n", rc);
3746             goto rw_error;
3747         }
3748 
3749         /* use corresponding bit in io data output registar */
3750         rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3751         if (rc != 0) {
3752             pr_err("error %d\n", rc);
3753             goto rw_error;
3754         }
3755         if (!uio_data->value)
3756             value &= 0xBFFF;    /* write zero to 14th bit - 2nd UIO */
3757         else
3758             value |= 0x4000;    /* write one to 14th bit - 2nd UIO */
3759 
3760         /* write back to io data output register */
3761         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3762         if (rc != 0) {
3763             pr_err("error %d\n", rc);
3764             goto rw_error;
3765         }
3766         break;
3767    /*====================================================================*/
3768     case DRX_UIO3:
3769         /* DRX_UIO3: ASEL UIO-3 */
3770         if (!ext_attr->has_gpio)
3771             return -EIO;
3772         if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
3773             return -EIO;
3774 
3775         pin_cfg_value = 0;
3776         /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3777         pin_cfg_value |= 0x0113;
3778         /* io_pad_cfg_mode output mode is drive always */
3779         /* io_pad_cfg_drive is set to power 2 (23 mA) */
3780 
3781         /* write to io pad configuration register - output mode */
3782         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
3783         if (rc != 0) {
3784             pr_err("error %d\n", rc);
3785             goto rw_error;
3786         }
3787 
3788         /* use corresponding bit in io data output registar */
3789         rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
3790         if (rc != 0) {
3791             pr_err("error %d\n", rc);
3792             goto rw_error;
3793         }
3794         if (!uio_data->value)
3795             value &= 0xFFFB;    /* write zero to 2nd bit - 3rd UIO */
3796         else
3797             value |= 0x0004;    /* write one to 2nd bit - 3rd UIO */
3798 
3799         /* write back to io data output register */
3800         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
3801         if (rc != 0) {
3802             pr_err("error %d\n", rc);
3803             goto rw_error;
3804         }
3805         break;
3806    /*=====================================================================*/
3807     case DRX_UIO4:
3808         /* DRX_UIO4: IRQN UIO-4 */
3809         if (!ext_attr->has_irqn)
3810             return -EIO;
3811 
3812         if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
3813             return -EIO;
3814 
3815         pin_cfg_value = 0;
3816         /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3817         pin_cfg_value |= 0x0113;
3818         /* io_pad_cfg_mode output mode is drive always */
3819         /* io_pad_cfg_drive is set to power 2 (23 mA) */
3820 
3821         /* write to io pad configuration register - output mode */
3822         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
3823         if (rc != 0) {
3824             pr_err("error %d\n", rc);
3825             goto rw_error;
3826         }
3827 
3828         /* use corresponding bit in io data output registar */
3829         rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3830         if (rc != 0) {
3831             pr_err("error %d\n", rc);
3832             goto rw_error;
3833         }
3834         if (uio_data->value == false)
3835             value &= 0xEFFF;    /* write zero to 12th bit - 4th UIO */
3836         else
3837             value |= 0x1000;    /* write one to 12th bit - 4th UIO */
3838 
3839         /* write back to io data output register */
3840         rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3841         if (rc != 0) {
3842             pr_err("error %d\n", rc);
3843             goto rw_error;
3844         }
3845         break;
3846       /*=====================================================================*/
3847     default:
3848         return -EINVAL;
3849     }           /* switch ( uio_data->uio ) */
3850 
3851     /*  Write magic word to disable pdr reg write               */
3852     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3853     if (rc != 0) {
3854         pr_err("error %d\n", rc);
3855         goto rw_error;
3856     }
3857 
3858     return 0;
3859 rw_error:
3860     return rc;
3861 }
3862 
3863 /*---------------------------------------------------------------------------*/
3864 /* UIO Configuration Functions - end                                         */
3865 /*---------------------------------------------------------------------------*/
3866 
3867 /*----------------------------------------------------------------------------*/
3868 /* I2C Bridge Functions - begin                                               */
3869 /*----------------------------------------------------------------------------*/
3870 /*
3871 * \fn int ctrl_i2c_bridge()
3872 * \brief Open or close the I2C switch to tuner.
3873 * \param demod Pointer to demodulator instance.
3874 * \param bridge_closed Pointer to bool indication if bridge is closed not.
3875 * \return int.
3876 
3877 */
3878 static int
3879 ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
3880 {
3881     struct drxj_hi_cmd hi_cmd;
3882     u16 result = 0;
3883 
3884     /* check arguments */
3885     if (bridge_closed == NULL)
3886         return -EINVAL;
3887 
3888     hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3889     hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
3890     if (*bridge_closed)
3891         hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
3892     else
3893         hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
3894 
3895     return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
3896 }
3897 
3898 /*----------------------------------------------------------------------------*/
3899 /* I2C Bridge Functions - end                                                 */
3900 /*----------------------------------------------------------------------------*/
3901 
3902 /*----------------------------------------------------------------------------*/
3903 /* Smart antenna Functions - begin                                            */
3904 /*----------------------------------------------------------------------------*/
3905 /*
3906 * \fn int smart_ant_init()
3907 * \brief Initialize Smart Antenna.
3908 * \param pointer to struct drx_demod_instance.
3909 * \return int.
3910 *
3911 */
3912 static int smart_ant_init(struct drx_demod_instance *demod)
3913 {
3914     struct drxj_data *ext_attr = NULL;
3915     struct i2c_device_addr *dev_addr = NULL;
3916     struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
3917     int rc;
3918     u16 data = 0;
3919 
3920     dev_addr = demod->my_i2c_dev_addr;
3921     ext_attr = (struct drxj_data *) demod->my_ext_attr;
3922 
3923     /*  Write magic word to enable pdr reg write               */
3924     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3925     if (rc != 0) {
3926         pr_err("error %d\n", rc);
3927         goto rw_error;
3928     }
3929     /* init smart antenna */
3930     rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
3931     if (rc != 0) {
3932         pr_err("error %d\n", rc);
3933         goto rw_error;
3934     }
3935     if (ext_attr->smart_ant_inverted) {
3936         rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
3937         if (rc != 0) {
3938             pr_err("error %d\n", rc);
3939             goto rw_error;
3940         }
3941     } else {
3942         rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
3943         if (rc != 0) {
3944             pr_err("error %d\n", rc);
3945             goto rw_error;
3946         }
3947     }
3948 
3949     /* config SMA_TX pin to smart antenna mode */
3950     rc = ctrl_set_uio_cfg(demod, &uio_cfg);
3951     if (rc != 0) {
3952         pr_err("error %d\n", rc);
3953         goto rw_error;
3954     }
3955     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
3956     if (rc != 0) {
3957         pr_err("error %d\n", rc);
3958         goto rw_error;
3959     }
3960     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
3961     if (rc != 0) {
3962         pr_err("error %d\n", rc);
3963         goto rw_error;
3964     }
3965 
3966     /*  Write magic word to disable pdr reg write               */
3967     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3968     if (rc != 0) {
3969         pr_err("error %d\n", rc);
3970         goto rw_error;
3971     }
3972 
3973     return 0;
3974 rw_error:
3975     return rc;
3976 }
3977 
3978 static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
3979 {
3980     int rc;
3981     u16 cur_cmd = 0;
3982     unsigned long timeout;
3983 
3984     /* Check param */
3985     if (cmd == NULL)
3986         return -EINVAL;
3987 
3988     /* Wait until SCU command interface is ready to receive command */
3989     rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
3990     if (rc != 0) {
3991         pr_err("error %d\n", rc);
3992         goto rw_error;
3993     }
3994     if (cur_cmd != DRX_SCU_READY)
3995         return -EIO;
3996 
3997     switch (cmd->parameter_len) {
3998     case 5:
3999         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
4000         if (rc != 0) {
4001             pr_err("error %d\n", rc);
4002             goto rw_error;
4003         }
4004         fallthrough;
4005     case 4:
4006         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
4007         if (rc != 0) {
4008             pr_err("error %d\n", rc);
4009             goto rw_error;
4010         }
4011         fallthrough;
4012     case 3:
4013         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
4014         if (rc != 0) {
4015             pr_err("error %d\n", rc);
4016             goto rw_error;
4017         }
4018         fallthrough;
4019     case 2:
4020         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
4021         if (rc != 0) {
4022             pr_err("error %d\n", rc);
4023             goto rw_error;
4024         }
4025         fallthrough;
4026     case 1:
4027         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
4028         if (rc != 0) {
4029             pr_err("error %d\n", rc);
4030             goto rw_error;
4031         }
4032         fallthrough;
4033     case 0:
4034         /* do nothing */
4035         break;
4036     default:
4037         /* this number of parameters is not supported */
4038         return -EIO;
4039     }
4040     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
4041     if (rc != 0) {
4042         pr_err("error %d\n", rc);
4043         goto rw_error;
4044     }
4045 
4046     /* Wait until SCU has processed command */
4047     timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
4048     while (time_is_after_jiffies(timeout)) {
4049         rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4050         if (rc != 0) {
4051             pr_err("error %d\n", rc);
4052             goto rw_error;
4053         }
4054         if (cur_cmd == DRX_SCU_READY)
4055             break;
4056         usleep_range(1000, 2000);
4057     }
4058 
4059     if (cur_cmd != DRX_SCU_READY)
4060         return -EIO;
4061 
4062     /* read results */
4063     if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4064         s16 err;
4065 
4066         switch (cmd->result_len) {
4067         case 4:
4068             rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
4069             if (rc != 0) {
4070                 pr_err("error %d\n", rc);
4071                 goto rw_error;
4072             }
4073             fallthrough;
4074         case 3:
4075             rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
4076             if (rc != 0) {
4077                 pr_err("error %d\n", rc);
4078                 goto rw_error;
4079             }
4080             fallthrough;
4081         case 2:
4082             rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
4083             if (rc != 0) {
4084                 pr_err("error %d\n", rc);
4085                 goto rw_error;
4086             }
4087             fallthrough;
4088         case 1:
4089             rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
4090             if (rc != 0) {
4091                 pr_err("error %d\n", rc);
4092                 goto rw_error;
4093             }
4094             fallthrough;
4095         case 0:
4096             /* do nothing */
4097             break;
4098         default:
4099             /* this number of parameters is not supported */
4100             return -EIO;
4101         }
4102 
4103         /* Check if an error was reported by SCU */
4104         err = cmd->result[0];
4105 
4106         /* check a few fixed error codes */
4107         if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4108             || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4109             || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4110             || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4111             ) {
4112             return -EINVAL;
4113         }
4114         /* here it is assumed that negative means error, and positive no error */
4115         else if (err < 0)
4116             return -EIO;
4117         else
4118             return 0;
4119     }
4120 
4121     return 0;
4122 
4123 rw_error:
4124     return rc;
4125 }
4126 
4127 /*
4128 * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4129 * \brief Basic access routine for SCU atomic read or write access
4130 * \param dev_addr  pointer to i2c dev address
4131 * \param addr     destination/source address
4132 * \param datasize size of data buffer in bytes
4133 * \param data     pointer to data buffer
4134 * \return int
4135 * \retval 0 Success
4136 * \retval -EIO Timeout, I2C error, illegal bank
4137 *
4138 */
4139 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4140 static
4141 int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 addr, u16 datasize,  /* max 30 bytes because the limit of SCU parameter */
4142                           u8 *data, bool read_flag)
4143 {
4144     struct drxjscu_cmd scu_cmd;
4145     int rc;
4146     u16 set_param_parameters[18];
4147     u16 cmd_result[15];
4148 
4149     /* Parameter check */
4150     if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4151         return -EINVAL;
4152 
4153     set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4154     if (read_flag) {        /* read */
4155         set_param_parameters[0] = ((~(0x0080)) & datasize);
4156         scu_cmd.parameter_len = 2;
4157         scu_cmd.result_len = datasize / 2 + 2;
4158     } else {
4159         int i = 0;
4160 
4161         set_param_parameters[0] = 0x0080 | datasize;
4162         for (i = 0; i < (datasize / 2); i++) {
4163             set_param_parameters[i + 2] =
4164                 (data[2 * i] | (data[(2 * i) + 1] << 8));
4165         }
4166         scu_cmd.parameter_len = datasize / 2 + 2;
4167         scu_cmd.result_len = 1;
4168     }
4169 
4170     scu_cmd.command =
4171         SCU_RAM_COMMAND_STANDARD_TOP |
4172         SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4173     scu_cmd.result = cmd_result;
4174     scu_cmd.parameter = set_param_parameters;
4175     rc = scu_command(dev_addr, &scu_cmd);
4176     if (rc != 0) {
4177         pr_err("error %d\n", rc);
4178         goto rw_error;
4179     }
4180 
4181     if (read_flag) {
4182         int i = 0;
4183         /* read data from buffer */
4184         for (i = 0; i < (datasize / 2); i++) {
4185             data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4186             data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4187         }
4188     }
4189 
4190     return 0;
4191 
4192 rw_error:
4193     return rc;
4194 
4195 }
4196 
4197 /*============================================================================*/
4198 
4199 /*
4200 * \fn int DRXJ_DAP_AtomicReadReg16()
4201 * \brief Atomic read of 16 bits words
4202 */
4203 static
4204 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4205                      u32 addr,
4206                      u16 *data, u32 flags)
4207 {
4208     u8 buf[2] = { 0 };
4209     int rc;
4210     u16 word = 0;
4211 
4212     if (!data)
4213         return -EINVAL;
4214 
4215     rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
4216     if (rc < 0)
4217         return rc;
4218 
4219     word = (u16) (buf[0] + (buf[1] << 8));
4220 
4221     *data = word;
4222 
4223     return rc;
4224 }
4225 
4226 /*============================================================================*/
4227 /*
4228 * \fn int drxj_dap_scu_atomic_write_reg16()
4229 * \brief Atomic read of 16 bits words
4230 */
4231 static
4232 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4233                       u32 addr,
4234                       u16 data, u32 flags)
4235 {
4236     u8 buf[2];
4237     int rc;
4238 
4239     buf[0] = (u8) (data & 0xff);
4240     buf[1] = (u8) ((data >> 8) & 0xff);
4241 
4242     rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
4243 
4244     return rc;
4245 }
4246 
4247 /* -------------------------------------------------------------------------- */
4248 /*
4249 * \brief Measure result of ADC synchronisation
4250 * \param demod demod instance
4251 * \param count (returned) count
4252 * \return int.
4253 * \retval 0    Success
4254 * \retval -EIO Failure: I2C error
4255 *
4256 */
4257 static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4258 {
4259     struct i2c_device_addr *dev_addr = NULL;
4260     int rc;
4261     u16 data = 0;
4262 
4263     dev_addr = demod->my_i2c_dev_addr;
4264 
4265     /* Start measurement */
4266     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
4267     if (rc != 0) {
4268         pr_err("error %d\n", rc);
4269         goto rw_error;
4270     }
4271     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
4272     if (rc != 0) {
4273         pr_err("error %d\n", rc);
4274         goto rw_error;
4275     }
4276 
4277     /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4278     msleep(1);
4279 
4280     *count = 0;
4281     rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);
4282     if (rc != 0) {
4283         pr_err("error %d\n", rc);
4284         goto rw_error;
4285     }
4286     if (data == 127)
4287         *count = *count + 1;
4288     rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);
4289     if (rc != 0) {
4290         pr_err("error %d\n", rc);
4291         goto rw_error;
4292     }
4293     if (data == 127)
4294         *count = *count + 1;
4295     rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);
4296     if (rc != 0) {
4297         pr_err("error %d\n", rc);
4298         goto rw_error;
4299     }
4300     if (data == 127)
4301         *count = *count + 1;
4302 
4303     return 0;
4304 rw_error:
4305     return rc;
4306 }
4307 
4308 /*
4309 * \brief Synchronize analog and digital clock domains
4310 * \param demod demod instance
4311 * \return int.
4312 * \retval 0    Success
4313 * \retval -EIO Failure: I2C error or failure to synchronize
4314 *
4315 * An IQM reset will also reset the results of this synchronization.
4316 * After an IQM reset this routine needs to be called again.
4317 *
4318 */
4319 
4320 static int adc_synchronization(struct drx_demod_instance *demod)
4321 {
4322     struct i2c_device_addr *dev_addr = NULL;
4323     int rc;
4324     u16 count = 0;
4325 
4326     dev_addr = demod->my_i2c_dev_addr;
4327 
4328     rc = adc_sync_measurement(demod, &count);
4329     if (rc != 0) {
4330         pr_err("error %d\n", rc);
4331         goto rw_error;
4332     }
4333 
4334     if (count == 1) {
4335         /* Try sampling on a different edge */
4336         u16 clk_neg = 0;
4337 
4338         rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
4339         if (rc != 0) {
4340             pr_err("error %d\n", rc);
4341             goto rw_error;
4342         }
4343 
4344         clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4345         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
4346         if (rc != 0) {
4347             pr_err("error %d\n", rc);
4348             goto rw_error;
4349         }
4350 
4351         rc = adc_sync_measurement(demod, &count);
4352         if (rc != 0) {
4353             pr_err("error %d\n", rc);
4354             goto rw_error;
4355         }
4356     }
4357 
4358     /* TODO: implement fallback scenarios */
4359     if (count < 2)
4360         return -EIO;
4361 
4362     return 0;
4363 rw_error:
4364     return rc;
4365 }
4366 
4367 /*============================================================================*/
4368 /*==                      END AUXILIARY FUNCTIONS                           ==*/
4369 /*============================================================================*/
4370 
4371 /*============================================================================*/
4372 /*============================================================================*/
4373 /*==                8VSB & QAM COMMON DATAPATH FUNCTIONS                    ==*/
4374 /*============================================================================*/
4375 /*============================================================================*/
4376 /*
4377 * \fn int init_agc ()
4378 * \brief Initialize AGC for all standards.
4379 * \param demod instance of demodulator.
4380 * \param channel pointer to channel data.
4381 * \return int.
4382 */
4383 static int init_agc(struct drx_demod_instance *demod)
4384 {
4385     struct i2c_device_addr *dev_addr = NULL;
4386     struct drx_common_attr *common_attr = NULL;
4387     struct drxj_data *ext_attr = NULL;
4388     struct drxj_cfg_agc *p_agc_rf_settings = NULL;
4389     struct drxj_cfg_agc *p_agc_if_settings = NULL;
4390     int rc;
4391     u16 ingain_tgt_max = 0;
4392     u16 clp_dir_to = 0;
4393     u16 sns_sum_max = 0;
4394     u16 clp_sum_max = 0;
4395     u16 sns_dir_to = 0;
4396     u16 ki_innergain_min = 0;
4397     u16 agc_ki = 0;
4398     u16 ki_max = 0;
4399     u16 if_iaccu_hi_tgt_min = 0;
4400     u16 data = 0;
4401     u16 agc_ki_dgain = 0;
4402     u16 ki_min = 0;
4403     u16 clp_ctrl_mode = 0;
4404     u16 agc_rf = 0;
4405     u16 agc_if = 0;
4406 
4407     dev_addr = demod->my_i2c_dev_addr;
4408     common_attr = (struct drx_common_attr *) demod->my_common_attr;
4409     ext_attr = (struct drxj_data *) demod->my_ext_attr;
4410 
4411     switch (ext_attr->standard) {
4412     case DRX_STANDARD_8VSB:
4413         clp_sum_max = 1023;
4414         clp_dir_to = (u16) (-9);
4415         sns_sum_max = 1023;
4416         sns_dir_to = (u16) (-9);
4417         ki_innergain_min = (u16) (-32768);
4418         ki_max = 0x032C;
4419         agc_ki_dgain = 0xC;
4420         if_iaccu_hi_tgt_min = 2047;
4421         ki_min = 0x0117;
4422         ingain_tgt_max = 16383;
4423         clp_ctrl_mode = 0;
4424         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
4425         if (rc != 0) {
4426             pr_err("error %d\n", rc);
4427             goto rw_error;
4428         }
4429         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
4430         if (rc != 0) {
4431             pr_err("error %d\n", rc);
4432             goto rw_error;
4433         }
4434         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
4435         if (rc != 0) {
4436             pr_err("error %d\n", rc);
4437             goto rw_error;
4438         }
4439         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
4440         if (rc != 0) {
4441             pr_err("error %d\n", rc);
4442             goto rw_error;
4443         }
4444         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
4445         if (rc != 0) {
4446             pr_err("error %d\n", rc);
4447             goto rw_error;
4448         }
4449         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
4450         if (rc != 0) {
4451             pr_err("error %d\n", rc);
4452             goto rw_error;
4453         }
4454         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
4455         if (rc != 0) {
4456             pr_err("error %d\n", rc);
4457             goto rw_error;
4458         }
4459         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
4460         if (rc != 0) {
4461             pr_err("error %d\n", rc);
4462             goto rw_error;
4463         }
4464         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
4465         if (rc != 0) {
4466             pr_err("error %d\n", rc);
4467             goto rw_error;
4468         }
4469         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
4470         if (rc != 0) {
4471             pr_err("error %d\n", rc);
4472             goto rw_error;
4473         }
4474         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
4475         if (rc != 0) {
4476             pr_err("error %d\n", rc);
4477             goto rw_error;
4478         }
4479         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
4480         if (rc != 0) {
4481             pr_err("error %d\n", rc);
4482             goto rw_error;
4483         }
4484         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
4485         if (rc != 0) {
4486             pr_err("error %d\n", rc);
4487             goto rw_error;
4488         }
4489         p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
4490         p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
4491         break;
4492 #ifndef DRXJ_VSB_ONLY
4493     case DRX_STANDARD_ITU_A:
4494     case DRX_STANDARD_ITU_C:
4495     case DRX_STANDARD_ITU_B:
4496         ingain_tgt_max = 5119;
4497         clp_sum_max = 1023;
4498         clp_dir_to = (u16) (-5);
4499         sns_sum_max = 127;
4500         sns_dir_to = (u16) (-3);
4501         ki_innergain_min = 0;
4502         ki_max = 0x0657;
4503         if_iaccu_hi_tgt_min = 2047;
4504         agc_ki_dgain = 0x7;
4505         ki_min = 0x0117;
4506         clp_ctrl_mode = 0;
4507         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
4508         if (rc != 0) {
4509             pr_err("error %d\n", rc);
4510             goto rw_error;
4511         }
4512         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
4513         if (rc != 0) {
4514             pr_err("error %d\n", rc);
4515             goto rw_error;
4516         }
4517         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
4518         if (rc != 0) {
4519             pr_err("error %d\n", rc);
4520             goto rw_error;
4521         }
4522         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
4523         if (rc != 0) {
4524             pr_err("error %d\n", rc);
4525             goto rw_error;
4526         }
4527         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
4528         if (rc != 0) {
4529             pr_err("error %d\n", rc);
4530             goto rw_error;
4531         }
4532         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
4533         if (rc != 0) {
4534             pr_err("error %d\n", rc);
4535             goto rw_error;
4536         }
4537         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
4538         if (rc != 0) {
4539             pr_err("error %d\n", rc);
4540             goto rw_error;
4541         }
4542         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
4543         if (rc != 0) {
4544             pr_err("error %d\n", rc);
4545             goto rw_error;
4546         }
4547         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
4548         if (rc != 0) {
4549             pr_err("error %d\n", rc);
4550             goto rw_error;
4551         }
4552         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
4553         if (rc != 0) {
4554             pr_err("error %d\n", rc);
4555             goto rw_error;
4556         }
4557         p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
4558         p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
4559         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
4560         if (rc != 0) {
4561             pr_err("error %d\n", rc);
4562             goto rw_error;
4563         }
4564 
4565         rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
4566         if (rc != 0) {
4567             pr_err("error %d\n", rc);
4568             goto rw_error;
4569         }
4570         agc_ki &= 0xf000;
4571         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
4572         if (rc != 0) {
4573             pr_err("error %d\n", rc);
4574             goto rw_error;
4575         }
4576         break;
4577 #endif
4578     default:
4579         return -EINVAL;
4580     }
4581 
4582     /* for new AGC interface */
4583     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
4584     if (rc != 0) {
4585         pr_err("error %d\n", rc);
4586         goto rw_error;
4587     }
4588     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
4589     if (rc != 0) {
4590         pr_err("error %d\n", rc);
4591         goto rw_error;
4592     }   /* Gain fed from inner to outer AGC */
4593     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
4594     if (rc != 0) {
4595         pr_err("error %d\n", rc);
4596         goto rw_error;
4597     }
4598     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
4599     if (rc != 0) {
4600         pr_err("error %d\n", rc);
4601         goto rw_error;
4602     }
4603     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
4604     if (rc != 0) {
4605         pr_err("error %d\n", rc);
4606         goto rw_error;
4607     }   /* set to p_agc_settings->top before */
4608     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
4609     if (rc != 0) {
4610         pr_err("error %d\n", rc);
4611         goto rw_error;
4612     }
4613     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
4614     if (rc != 0) {
4615         pr_err("error %d\n", rc);
4616         goto rw_error;
4617     }
4618     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
4619     if (rc != 0) {
4620         pr_err("error %d\n", rc);
4621         goto rw_error;
4622     }
4623     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
4624     if (rc != 0) {
4625         pr_err("error %d\n", rc);
4626         goto rw_error;
4627     }
4628     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
4629     if (rc != 0) {
4630         pr_err("error %d\n", rc);
4631         goto rw_error;
4632     }
4633     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
4634     if (rc != 0) {
4635         pr_err("error %d\n", rc);
4636         goto rw_error;
4637     }
4638     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
4639     if (rc != 0) {
4640         pr_err("error %d\n", rc);
4641         goto rw_error;
4642     }
4643     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
4644     if (rc != 0) {
4645         pr_err("error %d\n", rc);
4646         goto rw_error;
4647     }
4648     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
4649     if (rc != 0) {
4650         pr_err("error %d\n", rc);
4651         goto rw_error;
4652     }
4653     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
4654     if (rc != 0) {
4655         pr_err("error %d\n", rc);
4656         goto rw_error;
4657     }
4658     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
4659     if (rc != 0) {
4660         pr_err("error %d\n", rc);
4661         goto rw_error;
4662     }
4663     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
4664     if (rc != 0) {
4665         pr_err("error %d\n", rc);
4666         goto rw_error;
4667     }
4668     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
4669     if (rc != 0) {
4670         pr_err("error %d\n", rc);
4671         goto rw_error;
4672     }
4673     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
4674     if (rc != 0) {
4675         pr_err("error %d\n", rc);
4676         goto rw_error;
4677     }
4678     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
4679     if (rc != 0) {
4680         pr_err("error %d\n", rc);
4681         goto rw_error;
4682     }
4683     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
4684     if (rc != 0) {
4685         pr_err("error %d\n", rc);
4686         goto rw_error;
4687     }
4688     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
4689     if (rc != 0) {
4690         pr_err("error %d\n", rc);
4691         goto rw_error;
4692     }
4693     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
4694     if (rc != 0) {
4695         pr_err("error %d\n", rc);
4696         goto rw_error;
4697     }
4698     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
4699     if (rc != 0) {
4700         pr_err("error %d\n", rc);
4701         goto rw_error;
4702     }
4703     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
4704     if (rc != 0) {
4705         pr_err("error %d\n", rc);
4706         goto rw_error;
4707     }
4708     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
4709     if (rc != 0) {
4710         pr_err("error %d\n", rc);
4711         goto rw_error;
4712     }
4713 
4714     agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
4715     if (common_attr->tuner_rf_agc_pol == true)
4716         agc_rf = 0x87ff - agc_rf;
4717 
4718     agc_if = 0x800;
4719     if (common_attr->tuner_if_agc_pol == true)
4720         agc_rf = 0x87ff - agc_rf;
4721 
4722     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
4723     if (rc != 0) {
4724         pr_err("error %d\n", rc);
4725         goto rw_error;
4726     }
4727     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
4728     if (rc != 0) {
4729         pr_err("error %d\n", rc);
4730         goto rw_error;
4731     }
4732 
4733     /* Set/restore Ki DGAIN factor */
4734     rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
4735     if (rc != 0) {
4736         pr_err("error %d\n", rc);
4737         goto rw_error;
4738     }
4739     data &= ~SCU_RAM_AGC_KI_DGAIN__M;
4740     data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
4741     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
4742     if (rc != 0) {
4743         pr_err("error %d\n", rc);
4744         goto rw_error;
4745     }
4746 
4747     return 0;
4748 rw_error:
4749     return rc;
4750 }
4751 
4752 /*
4753 * \fn int set_frequency ()
4754 * \brief Set frequency shift.
4755 * \param demod instance of demodulator.
4756 * \param channel pointer to channel data.
4757 * \param tuner_freq_offset residual frequency from tuner.
4758 * \return int.
4759 */
4760 static int
4761 set_frequency(struct drx_demod_instance *demod,
4762           struct drx_channel *channel, s32 tuner_freq_offset)
4763 {
4764     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4765     struct drxj_data *ext_attr = demod->my_ext_attr;
4766     int rc;
4767     s32 sampling_frequency = 0;
4768     s32 frequency_shift = 0;
4769     s32 if_freq_actual = 0;
4770     s32 rf_freq_residual = -1 * tuner_freq_offset;
4771     s32 adc_freq = 0;
4772     s32 intermediate_freq = 0;
4773     u32 iqm_fs_rate_ofs = 0;
4774     bool adc_flip = true;
4775     bool select_pos_image = false;
4776     bool rf_mirror;
4777     bool tuner_mirror;
4778     bool image_to_select;
4779     s32 fm_frequency_shift = 0;
4780 
4781     rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
4782     tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
4783     /*
4784        Program frequency shifter
4785        No need to account for mirroring on RF
4786      */
4787     switch (ext_attr->standard) {
4788     case DRX_STANDARD_ITU_A:
4789     case DRX_STANDARD_ITU_C:
4790     case DRX_STANDARD_PAL_SECAM_LP:
4791     case DRX_STANDARD_8VSB:
4792         select_pos_image = true;
4793         break;
4794     case DRX_STANDARD_FM:
4795         /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4796            Sound carrier is already 3Mhz above centre frequency due
4797            to tuner setting so now add an extra shift of 1MHz... */
4798         fm_frequency_shift = 1000;
4799         fallthrough;
4800     case DRX_STANDARD_ITU_B:
4801     case DRX_STANDARD_NTSC:
4802     case DRX_STANDARD_PAL_SECAM_BG:
4803     case DRX_STANDARD_PAL_SECAM_DK:
4804     case DRX_STANDARD_PAL_SECAM_I:
4805     case DRX_STANDARD_PAL_SECAM_L:
4806         select_pos_image = false;
4807         break;
4808     default:
4809         return -EINVAL;
4810     }
4811     intermediate_freq = demod->my_common_attr->intermediate_freq;
4812     sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
4813     if (tuner_mirror)
4814         if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
4815     else
4816         if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
4817     if (if_freq_actual > sampling_frequency / 2) {
4818         /* adc mirrors */
4819         adc_freq = sampling_frequency - if_freq_actual;
4820         adc_flip = true;
4821     } else {
4822         /* adc doesn't mirror */
4823         adc_freq = if_freq_actual;
4824         adc_flip = false;
4825     }
4826 
4827     frequency_shift = adc_freq;
4828     image_to_select =
4829         (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
4830     iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
4831 
4832     if (image_to_select)
4833         iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
4834 
4835     /* Program frequency shifter with tuner offset compensation */
4836     /* frequency_shift += tuner_freq_offset; TODO */
4837     rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
4838     if (rc != 0) {
4839         pr_err("error %d\n", rc);
4840         goto rw_error;
4841     }
4842     ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
4843     ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
4844 
4845     return 0;
4846 rw_error:
4847     return rc;
4848 }
4849 
4850 /*
4851 * \fn int get_acc_pkt_err()
4852 * \brief Retrieve signal strength for VSB and QAM.
4853 * \param demod Pointer to demod instance
4854 * \param packet_err Pointer to packet error
4855 * \return int.
4856 * \retval 0 sig_strength contains valid data.
4857 * \retval -EINVAL sig_strength is NULL.
4858 * \retval -EIO Erroneous data, sig_strength contains invalid data.
4859 */
4860 #ifdef DRXJ_SIGNAL_ACCUM_ERR
4861 static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
4862 {
4863     int rc;
4864     static u16 pkt_err;
4865     static u16 last_pkt_err;
4866     u16 data = 0;
4867     struct drxj_data *ext_attr = NULL;
4868     struct i2c_device_addr *dev_addr = NULL;
4869 
4870     ext_attr = (struct drxj_data *) demod->my_ext_attr;
4871     dev_addr = demod->my_i2c_dev_addr;
4872 
4873     rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
4874     if (rc != 0) {
4875         pr_err("error %d\n", rc);
4876         goto rw_error;
4877     }
4878     if (ext_attr->reset_pkt_err_acc) {
4879         last_pkt_err = data;
4880         pkt_err = 0;
4881         ext_attr->reset_pkt_err_acc = false;
4882     }
4883 
4884     if (data < last_pkt_err) {
4885         pkt_err += 0xffff - last_pkt_err;
4886         pkt_err += data;
4887     } else {
4888         pkt_err += (data - last_pkt_err);
4889     }
4890     *packet_err = pkt_err;
4891     last_pkt_err = data;
4892 
4893     return 0;
4894 rw_error:
4895     return rc;
4896 }
4897 #endif
4898 
4899 
4900 /*============================================================================*/
4901 
4902 /*
4903 * \fn int set_agc_rf ()
4904 * \brief Configure RF AGC
4905 * \param demod instance of demodulator.
4906 * \param agc_settings AGC configuration structure
4907 * \return int.
4908 */
4909 static int
4910 set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
4911 {
4912     struct i2c_device_addr *dev_addr = NULL;
4913     struct drxj_data *ext_attr = NULL;
4914     struct drxj_cfg_agc *p_agc_settings = NULL;
4915     struct drx_common_attr *common_attr = NULL;
4916     int rc;
4917     drx_write_reg16func_t scu_wr16 = NULL;
4918     drx_read_reg16func_t scu_rr16 = NULL;
4919 
4920     common_attr = (struct drx_common_attr *) demod->my_common_attr;
4921     dev_addr = demod->my_i2c_dev_addr;
4922     ext_attr = (struct drxj_data *) demod->my_ext_attr;
4923 
4924     if (atomic) {
4925         scu_rr16 = drxj_dap_scu_atomic_read_reg16;
4926         scu_wr16 = drxj_dap_scu_atomic_write_reg16;
4927     } else {
4928         scu_rr16 = drxj_dap_read_reg16;
4929         scu_wr16 = drxj_dap_write_reg16;
4930     }
4931 
4932     /* Configure AGC only if standard is currently active */
4933     if ((ext_attr->standard == agc_settings->standard) ||
4934         (DRXJ_ISQAMSTD(ext_attr->standard) &&
4935          DRXJ_ISQAMSTD(agc_settings->standard)) ||
4936         (DRXJ_ISATVSTD(ext_attr->standard) &&
4937          DRXJ_ISATVSTD(agc_settings->standard))) {
4938         u16 data = 0;
4939 
4940         switch (agc_settings->ctrl_mode) {
4941         case DRX_AGC_CTRL_AUTO:
4942 
4943             /* Enable RF AGC DAC */
4944             rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
4945             if (rc != 0) {
4946                 pr_err("error %d\n", rc);
4947                 goto rw_error;
4948             }
4949             data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
4950             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
4951             if (rc != 0) {
4952                 pr_err("error %d\n", rc);
4953                 goto rw_error;
4954             }
4955 
4956             /* Enable SCU RF AGC loop */
4957             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
4958             if (rc != 0) {
4959                 pr_err("error %d\n", rc);
4960                 goto rw_error;
4961             }
4962             data &= ~SCU_RAM_AGC_KI_RF__M;
4963             if (ext_attr->standard == DRX_STANDARD_8VSB)
4964                 data |= (2 << SCU_RAM_AGC_KI_RF__B);
4965             else if (DRXJ_ISQAMSTD(ext_attr->standard))
4966                 data |= (5 << SCU_RAM_AGC_KI_RF__B);
4967             else
4968                 data |= (4 << SCU_RAM_AGC_KI_RF__B);
4969 
4970             if (common_attr->tuner_rf_agc_pol)
4971                 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
4972             else
4973                 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
4974             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
4975             if (rc != 0) {
4976                 pr_err("error %d\n", rc);
4977                 goto rw_error;
4978             }
4979 
4980             /* Set speed ( using complementary reduction value ) */
4981             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
4982             if (rc != 0) {
4983                 pr_err("error %d\n", rc);
4984                 goto rw_error;
4985             }
4986             data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
4987             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_RAGC_RED__B) & SCU_RAM_AGC_KI_RED_RAGC_RED__M) | data, 0);
4988             if (rc != 0) {
4989                 pr_err("error %d\n", rc);
4990                 goto rw_error;
4991             }
4992 
4993             if (agc_settings->standard == DRX_STANDARD_8VSB)
4994                 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
4995             else if (DRXJ_ISQAMSTD(agc_settings->standard))
4996                 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
4997             else if (DRXJ_ISATVSTD(agc_settings->standard))
4998                 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
4999             else
5000                 return -EINVAL;
5001 
5002             /* Set TOP, only if IF-AGC is in AUTO mode */
5003             if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5004                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
5005                 if (rc != 0) {
5006                     pr_err("error %d\n", rc);
5007                     goto rw_error;
5008                 }
5009                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
5010                 if (rc != 0) {
5011                     pr_err("error %d\n", rc);
5012                     goto rw_error;
5013                 }
5014             }
5015 
5016             /* Cut-Off current */
5017             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
5018             if (rc != 0) {
5019                 pr_err("error %d\n", rc);
5020                 goto rw_error;
5021             }
5022             break;
5023         case DRX_AGC_CTRL_USER:
5024 
5025             /* Enable RF AGC DAC */
5026             rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5027             if (rc != 0) {
5028                 pr_err("error %d\n", rc);
5029                 goto rw_error;
5030             }
5031             data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
5032             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5033             if (rc != 0) {
5034                 pr_err("error %d\n", rc);
5035                 goto rw_error;
5036             }
5037 
5038             /* Disable SCU RF AGC loop */
5039             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5040             if (rc != 0) {
5041                 pr_err("error %d\n", rc);
5042                 goto rw_error;
5043             }
5044             data &= ~SCU_RAM_AGC_KI_RF__M;
5045             if (common_attr->tuner_rf_agc_pol)
5046                 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5047             else
5048                 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5049             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5050             if (rc != 0) {
5051                 pr_err("error %d\n", rc);
5052                 goto rw_error;
5053             }
5054 
5055             /* Write value to output pin */
5056             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
5057             if (rc != 0) {
5058                 pr_err("error %d\n", rc);
5059                 goto rw_error;
5060             }
5061             break;
5062         case DRX_AGC_CTRL_OFF:
5063 
5064             /* Disable RF AGC DAC */
5065             rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5066             if (rc != 0) {
5067                 pr_err("error %d\n", rc);
5068                 goto rw_error;
5069             }
5070             data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5071             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5072             if (rc != 0) {
5073                 pr_err("error %d\n", rc);
5074                 goto rw_error;
5075             }
5076 
5077             /* Disable SCU RF AGC loop */
5078             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5079             if (rc != 0) {
5080                 pr_err("error %d\n", rc);
5081                 goto rw_error;
5082             }
5083             data &= ~SCU_RAM_AGC_KI_RF__M;
5084             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5085             if (rc != 0) {
5086                 pr_err("error %d\n", rc);
5087                 goto rw_error;
5088             }
5089             break;
5090         default:
5091             return -EINVAL;
5092         }       /* switch ( agcsettings->ctrl_mode ) */
5093     }
5094 
5095     /* Store rf agc settings */
5096     switch (agc_settings->standard) {
5097     case DRX_STANDARD_8VSB:
5098         ext_attr->vsb_rf_agc_cfg = *agc_settings;
5099         break;
5100 #ifndef DRXJ_VSB_ONLY
5101     case DRX_STANDARD_ITU_A:
5102     case DRX_STANDARD_ITU_B:
5103     case DRX_STANDARD_ITU_C:
5104         ext_attr->qam_rf_agc_cfg = *agc_settings;
5105         break;
5106 #endif
5107     default:
5108         return -EIO;
5109     }
5110 
5111     return 0;
5112 rw_error:
5113     return rc;
5114 }
5115 
5116 /*
5117 * \fn int set_agc_if ()
5118 * \brief Configure If AGC
5119 * \param demod instance of demodulator.
5120 * \param agc_settings AGC configuration structure
5121 * \return int.
5122 */
5123 static int
5124 set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
5125 {
5126     struct i2c_device_addr *dev_addr = NULL;
5127     struct drxj_data *ext_attr = NULL;
5128     struct drxj_cfg_agc *p_agc_settings = NULL;
5129     struct drx_common_attr *common_attr = NULL;
5130     drx_write_reg16func_t scu_wr16 = NULL;
5131     drx_read_reg16func_t scu_rr16 = NULL;
5132     int rc;
5133 
5134     common_attr = (struct drx_common_attr *) demod->my_common_attr;
5135     dev_addr = demod->my_i2c_dev_addr;
5136     ext_attr = (struct drxj_data *) demod->my_ext_attr;
5137 
5138     if (atomic) {
5139         scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5140         scu_wr16 = drxj_dap_scu_atomic_write_reg16;
5141     } else {
5142         scu_rr16 = drxj_dap_read_reg16;
5143         scu_wr16 = drxj_dap_write_reg16;
5144     }
5145 
5146     /* Configure AGC only if standard is currently active */
5147     if ((ext_attr->standard == agc_settings->standard) ||
5148         (DRXJ_ISQAMSTD(ext_attr->standard) &&
5149          DRXJ_ISQAMSTD(agc_settings->standard)) ||
5150         (DRXJ_ISATVSTD(ext_attr->standard) &&
5151          DRXJ_ISATVSTD(agc_settings->standard))) {
5152         u16 data = 0;
5153 
5154         switch (agc_settings->ctrl_mode) {
5155         case DRX_AGC_CTRL_AUTO:
5156             /* Enable IF AGC DAC */
5157             rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5158             if (rc != 0) {
5159                 pr_err("error %d\n", rc);
5160                 goto rw_error;
5161             }
5162             data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5163             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5164             if (rc != 0) {
5165                 pr_err("error %d\n", rc);
5166                 goto rw_error;
5167             }
5168 
5169             /* Enable SCU IF AGC loop */
5170             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5171             if (rc != 0) {
5172                 pr_err("error %d\n", rc);
5173                 goto rw_error;
5174             }
5175             data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5176             data &= ~SCU_RAM_AGC_KI_IF__M;
5177             if (ext_attr->standard == DRX_STANDARD_8VSB)
5178                 data |= (3 << SCU_RAM_AGC_KI_IF__B);
5179             else if (DRXJ_ISQAMSTD(ext_attr->standard))
5180                 data |= (6 << SCU_RAM_AGC_KI_IF__B);
5181             else
5182                 data |= (5 << SCU_RAM_AGC_KI_IF__B);
5183 
5184             if (common_attr->tuner_if_agc_pol)
5185                 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5186             else
5187                 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5188             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5189             if (rc != 0) {
5190                 pr_err("error %d\n", rc);
5191                 goto rw_error;
5192             }
5193 
5194             /* Set speed (using complementary reduction value) */
5195             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
5196             if (rc != 0) {
5197                 pr_err("error %d\n", rc);
5198                 goto rw_error;
5199             }
5200             data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
5201             rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_IAGC_RED__B) & SCU_RAM_AGC_KI_RED_IAGC_RED__M) | data, 0);
5202             if (rc != 0) {
5203                 pr_err("error %d\n", rc);
5204                 goto rw_error;
5205             }
5206 
5207             if (agc_settings->standard == DRX_STANDARD_8VSB)
5208                 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
5209             else if (DRXJ_ISQAMSTD(agc_settings->standard))
5210                 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
5211             else if (DRXJ_ISATVSTD(agc_settings->standard))
5212                 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
5213             else
5214                 return -EINVAL;
5215 
5216             /* Restore TOP */
5217             if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5218                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
5219                 if (rc != 0) {
5220                     pr_err("error %d\n", rc);
5221                     goto rw_error;
5222                 }
5223                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
5224                 if (rc != 0) {
5225                     pr_err("error %d\n", rc);
5226                     goto rw_error;
5227                 }
5228             } else {
5229                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
5230                 if (rc != 0) {
5231                     pr_err("error %d\n", rc);
5232                     goto rw_error;
5233                 }
5234                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
5235                 if (rc != 0) {
5236                     pr_err("error %d\n", rc);
5237                     goto rw_error;
5238                 }
5239             }
5240             break;
5241 
5242         case DRX_AGC_CTRL_USER:
5243 
5244             /* Enable IF AGC DAC */
5245             rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5246             if (rc != 0) {
5247                 pr_err("error %d\n", rc);
5248                 goto rw_error;
5249             }
5250             data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5251             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5252             if (rc != 0) {
5253                 pr_err("error %d\n", rc);
5254                 goto rw_error;
5255             }
5256 
5257             /* Disable SCU IF AGC loop */
5258             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5259             if (rc != 0) {
5260                 pr_err("error %d\n", rc);
5261                 goto rw_error;
5262             }
5263             data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5264             data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5265             if (common_attr->tuner_if_agc_pol)
5266                 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5267             else
5268                 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5269             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5270             if (rc != 0) {
5271                 pr_err("error %d\n", rc);
5272                 goto rw_error;
5273             }
5274 
5275             /* Write value to output pin */
5276             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
5277             if (rc != 0) {
5278                 pr_err("error %d\n", rc);
5279                 goto rw_error;
5280             }
5281             break;
5282 
5283         case DRX_AGC_CTRL_OFF:
5284 
5285             /* Disable If AGC DAC */
5286             rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5287             if (rc != 0) {
5288                 pr_err("error %d\n", rc);
5289                 goto rw_error;
5290             }
5291             data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
5292             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5293             if (rc != 0) {
5294                 pr_err("error %d\n", rc);
5295                 goto rw_error;
5296             }
5297 
5298             /* Disable SCU IF AGC loop */
5299             rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5300             if (rc != 0) {
5301                 pr_err("error %d\n", rc);
5302                 goto rw_error;
5303             }
5304             data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5305             data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5306             rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5307             if (rc != 0) {
5308                 pr_err("error %d\n", rc);
5309                 goto rw_error;
5310             }
5311             break;
5312         default:
5313             return -EINVAL;
5314         }       /* switch ( agcsettings->ctrl_mode ) */
5315 
5316         /* always set the top to support configurations without if-loop */
5317         rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
5318         if (rc != 0) {
5319             pr_err("error %d\n", rc);
5320             goto rw_error;
5321         }
5322     }
5323 
5324     /* Store if agc settings */
5325     switch (agc_settings->standard) {
5326     case DRX_STANDARD_8VSB:
5327         ext_attr->vsb_if_agc_cfg = *agc_settings;
5328         break;
5329 #ifndef DRXJ_VSB_ONLY
5330     case DRX_STANDARD_ITU_A:
5331     case DRX_STANDARD_ITU_B:
5332     case DRX_STANDARD_ITU_C:
5333         ext_attr->qam_if_agc_cfg = *agc_settings;
5334         break;
5335 #endif
5336     default:
5337         return -EIO;
5338     }
5339 
5340     return 0;
5341 rw_error:
5342     return rc;
5343 }
5344 
5345 /*
5346 * \fn int set_iqm_af ()
5347 * \brief Configure IQM AF registers
5348 * \param demod instance of demodulator.
5349 * \param active
5350 * \return int.
5351 */
5352 static int set_iqm_af(struct drx_demod_instance *demod, bool active)
5353 {
5354     u16 data = 0;
5355     struct i2c_device_addr *dev_addr = NULL;
5356     int rc;
5357 
5358     dev_addr = demod->my_i2c_dev_addr;
5359 
5360     /* Configure IQM */
5361     rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5362     if (rc != 0) {
5363         pr_err("error %d\n", rc);
5364         goto rw_error;
5365     }
5366     if (!active)
5367         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));
5368     else
5369         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);
5370     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5371     if (rc != 0) {
5372         pr_err("error %d\n", rc);
5373         goto rw_error;
5374     }
5375 
5376     return 0;
5377 rw_error:
5378     return rc;
5379 }
5380 
5381 /*============================================================================*/
5382 /*==              END 8VSB & QAM COMMON DATAPATH FUNCTIONS                  ==*/
5383 /*============================================================================*/
5384 
5385 /*============================================================================*/
5386 /*============================================================================*/
5387 /*==                       8VSB DATAPATH FUNCTIONS                          ==*/
5388 /*============================================================================*/
5389 /*============================================================================*/
5390 
5391 /*
5392 * \fn int power_down_vsb ()
5393 * \brief Powr down QAM related blocks.
5394 * \param demod instance of demodulator.
5395 * \param channel pointer to channel data.
5396 * \return int.
5397 */
5398 static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
5399 {
5400     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5401     struct drxjscu_cmd cmd_scu = { /* command     */ 0,
5402         /* parameter_len */ 0,
5403         /* result_len    */ 0,
5404         /* *parameter   */ NULL,
5405         /* *result      */ NULL
5406     };
5407     struct drx_cfg_mpeg_output cfg_mpeg_output;
5408     int rc;
5409     u16 cmd_result = 0;
5410 
5411     /*
5412        STOP demodulator
5413        reset of FEC and VSB HW
5414      */
5415     cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
5416         SCU_RAM_COMMAND_CMD_DEMOD_STOP;
5417     cmd_scu.parameter_len = 0;
5418     cmd_scu.result_len = 1;
5419     cmd_scu.parameter = NULL;
5420     cmd_scu.result = &cmd_result;
5421     rc = scu_command(dev_addr, &cmd_scu);
5422     if (rc != 0) {
5423         pr_err("error %d\n", rc);
5424         goto rw_error;
5425     }
5426 
5427     /* stop all comm_exec */
5428     rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
5429     if (rc != 0) {
5430         pr_err("error %d\n", rc);
5431         goto rw_error;
5432     }
5433     rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
5434     if (rc != 0) {
5435         pr_err("error %d\n", rc);
5436         goto rw_error;
5437     }
5438     if (primary) {
5439         rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
5440         if (rc != 0) {
5441             pr_err("error %d\n", rc);
5442             goto rw_error;
5443         }
5444         rc = set_iqm_af(demod, false);
5445         if (rc != 0) {
5446             pr_err("error %d\n", rc);
5447             goto rw_error;
5448         }
5449     } else {
5450         rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
5451         if (rc != 0) {
5452             pr_err("error %d\n", rc);
5453             goto rw_error;
5454         }
5455         rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
5456         if (rc != 0) {
5457             pr_err("error %d\n", rc);
5458             goto rw_error;
5459         }
5460         rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
5461         if (rc != 0) {
5462             pr_err("error %d\n", rc);
5463             goto rw_error;
5464         }
5465         rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
5466         if (rc != 0) {
5467             pr_err("error %d\n", rc);
5468             goto rw_error;
5469         }
5470         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
5471         if (rc != 0) {
5472             pr_err("error %d\n", rc);
5473             goto rw_error;
5474         }
5475     }
5476 
5477     cfg_mpeg_output.enable_mpeg_output = false;
5478     rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
5479     if (rc != 0) {
5480         pr_err("error %d\n", rc);
5481         goto rw_error;
5482     }
5483 
5484     return 0;
5485 rw_error:
5486     return rc;
5487 }
5488 
5489 /*
5490 * \fn int set_vsb_leak_n_gain ()
5491 * \brief Set ATSC demod.
5492 * \param demod instance of demodulator.
5493 * \return int.
5494 */
5495 static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
5496 {
5497     struct i2c_device_addr *dev_addr = NULL;
5498     int rc;
5499 
5500     static const u8 vsb_ffe_leak_gain_ram0[] = {
5501         DRXJ_16TO8(0x8),    /* FFETRAINLKRATIO1  */
5502         DRXJ_16TO8(0x8),    /* FFETRAINLKRATIO2  */
5503         DRXJ_16TO8(0x8),    /* FFETRAINLKRATIO3  */
5504         DRXJ_16TO8(0xf),    /* FFETRAINLKRATIO4  */
5505         DRXJ_16TO8(0xf),    /* FFETRAINLKRATIO5  */
5506         DRXJ_16TO8(0xf),    /* FFETRAINLKRATIO6  */
5507         DRXJ_16TO8(0xf),    /* FFETRAINLKRATIO7  */
5508         DRXJ_16TO8(0xf),    /* FFETRAINLKRATIO8  */
5509         DRXJ_16TO8(0xf),    /* FFETRAINLKRATIO9  */
5510         DRXJ_16TO8(0x8),    /* FFETRAINLKRATIO10  */
5511         DRXJ_16TO8(0x8),    /* FFETRAINLKRATIO11 */
5512         DRXJ_16TO8(0x8),    /* FFETRAINLKRATIO12 */
5513         DRXJ_16TO8(0x10),   /* FFERCA1TRAINLKRATIO1 */
5514         DRXJ_16TO8(0x10),   /* FFERCA1TRAINLKRATIO2 */
5515         DRXJ_16TO8(0x10),   /* FFERCA1TRAINLKRATIO3 */
5516         DRXJ_16TO8(0x20),   /* FFERCA1TRAINLKRATIO4 */
5517         DRXJ_16TO8(0x20),   /* FFERCA1TRAINLKRATIO5 */
5518         DRXJ_16TO8(0x20),   /* FFERCA1TRAINLKRATIO6 */
5519         DRXJ_16TO8(0x20),   /* FFERCA1TRAINLKRATIO7 */
5520         DRXJ_16TO8(0x20),   /* FFERCA1TRAINLKRATIO8 */
5521         DRXJ_16TO8(0x20),   /* FFERCA1TRAINLKRATIO9 */
5522         DRXJ_16TO8(0x10),   /* FFERCA1TRAINLKRATIO10 */
5523         DRXJ_16TO8(0x10),   /* FFERCA1TRAINLKRATIO11 */
5524         DRXJ_16TO8(0x10),   /* FFERCA1TRAINLKRATIO12 */
5525         DRXJ_16TO8(0x10),   /* FFERCA1DATALKRATIO1 */
5526         DRXJ_16TO8(0x10),   /* FFERCA1DATALKRATIO2 */
5527         DRXJ_16TO8(0x10),   /* FFERCA1DATALKRATIO3 */
5528         DRXJ_16TO8(0x20),   /* FFERCA1DATALKRATIO4 */
5529         DRXJ_16TO8(0x20),   /* FFERCA1DATALKRATIO5 */
5530         DRXJ_16TO8(0x20),   /* FFERCA1DATALKRATIO6 */
5531         DRXJ_16TO8(0x20),   /* FFERCA1DATALKRATIO7 */
5532         DRXJ_16TO8(0x20),   /* FFERCA1DATALKRATIO8 */
5533         DRXJ_16TO8(0x20),   /* FFERCA1DATALKRATIO9 */
5534         DRXJ_16TO8(0x10),   /* FFERCA1DATALKRATIO10 */
5535         DRXJ_16TO8(0x10),   /* FFERCA1DATALKRATIO11 */
5536         DRXJ_16TO8(0x10),   /* FFERCA1DATALKRATIO12 */
5537         DRXJ_16TO8(0x10),   /* FFERCA2TRAINLKRATIO1 */
5538         DRXJ_16TO8(0x10),   /* FFERCA2TRAINLKRATIO2 */
5539         DRXJ_16TO8(0x10),   /* FFERCA2TRAINLKRATIO3 */
5540         DRXJ_16TO8(0x20),   /* FFERCA2TRAINLKRATIO4 */
5541         DRXJ_16TO8(0x20),   /* FFERCA2TRAINLKRATIO5 */
5542         DRXJ_16TO8(0x20),   /* FFERCA2TRAINLKRATIO6 */
5543         DRXJ_16TO8(0x20),   /* FFERCA2TRAINLKRATIO7 */
5544         DRXJ_16TO8(0x20),   /* FFERCA2TRAINLKRATIO8 */
5545         DRXJ_16TO8(0x20),   /* FFERCA2TRAINLKRATIO9 */
5546         DRXJ_16TO8(0x10),   /* FFERCA2TRAINLKRATIO10 */
5547         DRXJ_16TO8(0x10),   /* FFERCA2TRAINLKRATIO11 */
5548         DRXJ_16TO8(0x10),   /* FFERCA2TRAINLKRATIO12 */
5549         DRXJ_16TO8(0x10),   /* FFERCA2DATALKRATIO1 */
5550         DRXJ_16TO8(0x10),   /* FFERCA2DATALKRATIO2 */
5551         DRXJ_16TO8(0x10),   /* FFERCA2DATALKRATIO3 */
5552         DRXJ_16TO8(0x20),   /* FFERCA2DATALKRATIO4 */
5553         DRXJ_16TO8(0x20),   /* FFERCA2DATALKRATIO5 */
5554         DRXJ_16TO8(0x20),   /* FFERCA2DATALKRATIO6 */
5555         DRXJ_16TO8(0x20),   /* FFERCA2DATALKRATIO7 */
5556         DRXJ_16TO8(0x20),   /* FFERCA2DATALKRATIO8 */
5557         DRXJ_16TO8(0x20),   /* FFERCA2DATALKRATIO9 */
5558         DRXJ_16TO8(0x10),   /* FFERCA2DATALKRATIO10 */
5559         DRXJ_16TO8(0x10),   /* FFERCA2DATALKRATIO11 */
5560         DRXJ_16TO8(0x10),   /* FFERCA2DATALKRATIO12 */
5561         DRXJ_16TO8(0x07),   /* FFEDDM1TRAINLKRATIO1 */
5562         DRXJ_16TO8(0x07),   /* FFEDDM1TRAINLKRATIO2 */
5563         DRXJ_16TO8(0x07),   /* FFEDDM1TRAINLKRATIO3 */
5564         DRXJ_16TO8(0x0e),   /* FFEDDM1TRAINLKRATIO4 */
5565         DRXJ_16TO8(0x0e),   /* FFEDDM1TRAINLKRATIO5 */
5566         DRXJ_16TO8(0x0e),   /* FFEDDM1TRAINLKRATIO6 */
5567         DRXJ_16TO8(0x0e),   /* FFEDDM1TRAINLKRATIO7 */
5568         DRXJ_16TO8(0x0e),   /* FFEDDM1TRAINLKRATIO8 */
5569         DRXJ_16TO8(0x0e),   /* FFEDDM1TRAINLKRATIO9 */
5570         DRXJ_16TO8(0x07),   /* FFEDDM1TRAINLKRATIO10 */
5571         DRXJ_16TO8(0x07),   /* FFEDDM1TRAINLKRATIO11 */
5572         DRXJ_16TO8(0x07),   /* FFEDDM1TRAINLKRATIO12 */
5573         DRXJ_16TO8(0x07),   /* FFEDDM1DATALKRATIO1 */
5574         DRXJ_16TO8(0x07),   /* FFEDDM1DATALKRATIO2 */
5575         DRXJ_16TO8(0x07),   /* FFEDDM1DATALKRATIO3 */
5576         DRXJ_16TO8(0x0e),   /* FFEDDM1DATALKRATIO4 */
5577         DRXJ_16TO8(0x0e),   /* FFEDDM1DATALKRATIO5 */
5578         DRXJ_16TO8(0x0e),   /* FFEDDM1DATALKRATIO6 */
5579         DRXJ_16TO8(0x0e),   /* FFEDDM1DATALKRATIO7 */
5580         DRXJ_16TO8(0x0e),   /* FFEDDM1DATALKRATIO8 */
5581         DRXJ_16TO8(0x0e),   /* FFEDDM1DATALKRATIO9 */
5582         DRXJ_16TO8(0x07),   /* FFEDDM1DATALKRATIO10 */
5583         DRXJ_16TO8(0x07),   /* FFEDDM1DATALKRATIO11 */
5584         DRXJ_16TO8(0x07),   /* FFEDDM1DATALKRATIO12 */
5585         DRXJ_16TO8(0x06),   /* FFEDDM2TRAINLKRATIO1 */
5586         DRXJ_16TO8(0x06),   /* FFEDDM2TRAINLKRATIO2 */
5587         DRXJ_16TO8(0x06),   /* FFEDDM2TRAINLKRATIO3 */
5588         DRXJ_16TO8(0x0c),   /* FFEDDM2TRAINLKRATIO4 */
5589         DRXJ_16TO8(0x0c),   /* FFEDDM2TRAINLKRATIO5 */
5590         DRXJ_16TO8(0x0c),   /* FFEDDM2TRAINLKRATIO6 */
5591         DRXJ_16TO8(0x0c),   /* FFEDDM2TRAINLKRATIO7 */
5592         DRXJ_16TO8(0x0c),   /* FFEDDM2TRAINLKRATIO8 */
5593         DRXJ_16TO8(0x0c),   /* FFEDDM2TRAINLKRATIO9 */
5594         DRXJ_16TO8(0x06),   /* FFEDDM2TRAINLKRATIO10 */
5595         DRXJ_16TO8(0x06),   /* FFEDDM2TRAINLKRATIO11 */
5596         DRXJ_16TO8(0x06),   /* FFEDDM2TRAINLKRATIO12 */
5597         DRXJ_16TO8(0x06),   /* FFEDDM2DATALKRATIO1 */
5598         DRXJ_16TO8(0x06),   /* FFEDDM2DATALKRATIO2 */
5599         DRXJ_16TO8(0x06),   /* FFEDDM2DATALKRATIO3 */
5600         DRXJ_16TO8(0x0c),   /* FFEDDM2DATALKRATIO4 */
5601         DRXJ_16TO8(0x0c),   /* FFEDDM2DATALKRATIO5 */
5602         DRXJ_16TO8(0x0c),   /* FFEDDM2DATALKRATIO6 */
5603         DRXJ_16TO8(0x0c),   /* FFEDDM2DATALKRATIO7 */
5604         DRXJ_16TO8(0x0c),   /* FFEDDM2DATALKRATIO8 */
5605         DRXJ_16TO8(0x0c),   /* FFEDDM2DATALKRATIO9 */
5606         DRXJ_16TO8(0x06),   /* FFEDDM2DATALKRATIO10 */
5607         DRXJ_16TO8(0x06),   /* FFEDDM2DATALKRATIO11 */
5608         DRXJ_16TO8(0x06),   /* FFEDDM2DATALKRATIO12 */
5609         DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
5610         DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
5611         DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
5612         DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
5613         DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
5614         DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
5615         DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
5616         DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
5617         DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
5618         DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
5619         DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
5620         DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
5621         DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
5622         DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
5623         DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
5624         DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
5625         DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
5626         DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
5627         DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
5628         DRXJ_16TO8(0x1010)  /* FIRRCA1GAIN8 */
5629     };
5630 
5631     static const u8 vsb_ffe_leak_gain_ram1[] = {
5632         DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
5633         DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
5634         DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
5635         DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
5636         DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
5637         DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
5638         DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
5639         DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
5640         DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
5641         DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
5642         DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
5643         DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
5644         DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
5645         DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
5646         DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
5647         DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
5648         DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
5649         DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
5650         DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
5651         DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
5652         DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
5653         DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
5654         DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
5655         DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
5656         DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
5657         DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
5658         DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
5659         DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
5660         DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
5661         DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
5662         DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
5663         DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
5664         DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
5665         DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
5666         DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
5667         DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
5668         DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
5669         DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
5670         DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
5671         DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
5672         DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
5673         DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
5674         DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
5675         DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
5676         DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
5677         DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
5678         DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
5679         DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
5680         DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
5681         DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
5682         DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
5683         DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
5684         DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
5685         DRXJ_16TO8(0x1212)  /* DFEDDM2GAIN */
5686     };
5687 
5688     dev_addr = demod->my_i2c_dev_addr;
5689     rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
5690     if (rc != 0) {
5691         pr_err("error %d\n", rc);
5692         goto rw_error;
5693     }
5694     rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
5695     if (rc != 0) {
5696         pr_err("error %d\n", rc);
5697         goto rw_error;
5698     }
5699 
5700     return 0;
5701 rw_error:
5702     return rc;
5703 }
5704 
5705 /*
5706 * \fn int set_vsb()
5707 * \brief Set 8VSB demod.
5708 * \param demod instance of demodulator.
5709 * \return int.
5710 *
5711 */
5712 static int set_vsb(struct drx_demod_instance *demod)
5713 {
5714     struct i2c_device_addr *dev_addr = NULL;
5715     int rc;
5716     struct drx_common_attr *common_attr = NULL;
5717     struct drxjscu_cmd cmd_scu;
5718     struct drxj_data *ext_attr = NULL;
5719     u16 cmd_result = 0;
5720     u16 cmd_param = 0;
5721     static const u8 vsb_taps_re[] = {
5722         DRXJ_16TO8(-2), /* re0  */
5723         DRXJ_16TO8(4),  /* re1  */
5724         DRXJ_16TO8(1),  /* re2  */
5725         DRXJ_16TO8(-4), /* re3  */
5726         DRXJ_16TO8(1),  /* re4  */
5727         DRXJ_16TO8(4),  /* re5  */
5728         DRXJ_16TO8(-3), /* re6  */
5729         DRXJ_16TO8(-3), /* re7  */
5730         DRXJ_16TO8(6),  /* re8  */
5731         DRXJ_16TO8(1),  /* re9  */
5732         DRXJ_16TO8(-9), /* re10 */
5733         DRXJ_16TO8(3),  /* re11 */
5734         DRXJ_16TO8(12), /* re12 */
5735         DRXJ_16TO8(-9), /* re13 */
5736         DRXJ_16TO8(-15),    /* re14 */
5737         DRXJ_16TO8(17), /* re15 */
5738         DRXJ_16TO8(19), /* re16 */
5739         DRXJ_16TO8(-29),    /* re17 */
5740         DRXJ_16TO8(-22),    /* re18 */
5741         DRXJ_16TO8(45), /* re19 */
5742         DRXJ_16TO8(25), /* re20 */
5743         DRXJ_16TO8(-70),    /* re21 */
5744         DRXJ_16TO8(-28),    /* re22 */
5745         DRXJ_16TO8(111),    /* re23 */
5746         DRXJ_16TO8(30), /* re24 */
5747         DRXJ_16TO8(-201),   /* re25 */
5748         DRXJ_16TO8(-31),    /* re26 */
5749         DRXJ_16TO8(629) /* re27 */
5750     };
5751 
5752     dev_addr = demod->my_i2c_dev_addr;
5753     common_attr = (struct drx_common_attr *) demod->my_common_attr;
5754     ext_attr = (struct drxj_data *) demod->my_ext_attr;
5755 
5756     /* stop all comm_exec */
5757     rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
5758     if (rc != 0) {
5759         pr_err("error %d\n", rc);
5760         goto rw_error;
5761     }
5762     rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
5763     if (rc != 0) {
5764         pr_err("error %d\n", rc);
5765         goto rw_error;
5766     }
5767     rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
5768     if (rc != 0) {
5769         pr_err("error %d\n", rc);
5770         goto rw_error;
5771     }
5772     rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
5773     if (rc != 0) {
5774         pr_err("error %d\n", rc);
5775         goto rw_error;
5776     }
5777     rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
5778     if (rc != 0) {
5779         pr_err("error %d\n", rc);
5780         goto rw_error;
5781     }
5782     rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
5783     if (rc != 0) {
5784         pr_err("error %d\n", rc);
5785         goto rw_error;
5786     }
5787     rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
5788     if (rc != 0) {
5789         pr_err("error %d\n", rc);
5790         goto rw_error;
5791     }
5792 
5793     /* reset demodulator */
5794     cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
5795         | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
5796     cmd_scu.parameter_len = 0;
5797     cmd_scu.result_len = 1;
5798     cmd_scu.parameter = NULL;
5799     cmd_scu.result = &cmd_result;
5800     rc = scu_command(dev_addr, &cmd_scu);
5801     if (rc != 0) {
5802         pr_err("error %d\n", rc);
5803         goto rw_error;
5804     }
5805 
5806     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
5807     if (rc != 0) {
5808         pr_err("error %d\n", rc);
5809         goto rw_error;
5810     }
5811     rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
5812     if (rc != 0) {
5813         pr_err("error %d\n", rc);
5814         goto rw_error;
5815     }
5816     rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
5817     if (rc != 0) {
5818         pr_err("error %d\n", rc);
5819         goto rw_error;
5820     }
5821     ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
5822     rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
5823     if (rc != 0) {
5824         pr_err("error %d\n", rc);
5825         goto rw_error;
5826     }
5827     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
5828     if (rc != 0) {
5829         pr_err("error %d\n", rc);
5830         goto rw_error;
5831     }
5832     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
5833     if (rc != 0) {
5834         pr_err("error %d\n", rc);
5835         goto rw_error;
5836     }
5837 
5838     rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
5839     if (rc != 0) {
5840         pr_err("error %d\n", rc);
5841         goto rw_error;
5842     }
5843     rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);
5844     if (rc != 0) {
5845         pr_err("error %d\n", rc);
5846         goto rw_error;
5847     }
5848     rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
5849     if (rc != 0) {
5850         pr_err("error %d\n", rc);
5851         goto rw_error;
5852     }
5853     rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
5854     if (rc != 0) {
5855         pr_err("error %d\n", rc);
5856         goto rw_error;
5857     }
5858     rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
5859     if (rc != 0) {
5860         pr_err("error %d\n", rc);
5861         goto rw_error;
5862     }
5863     rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
5864     if (rc != 0) {
5865         pr_err("error %d\n", rc);
5866         goto rw_error;
5867     }
5868     rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);
5869     if (rc != 0) {
5870         pr_err("error %d\n", rc);
5871         goto rw_error;
5872     }
5873     rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
5874     if (rc != 0) {
5875         pr_err("error %d\n", rc);
5876         goto rw_error;
5877     }
5878     rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
5879     if (rc != 0) {
5880         pr_err("error %d\n", rc);
5881         goto rw_error;
5882     }
5883 
5884     rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
5885     if (rc != 0) {
5886         pr_err("error %d\n", rc);
5887         goto rw_error;
5888     }
5889     rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
5890     if (rc != 0) {
5891         pr_err("error %d\n", rc);
5892         goto rw_error;
5893     }
5894 
5895     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
5896     if (rc != 0) {
5897         pr_err("error %d\n", rc);
5898         goto rw_error;
5899     }   /* set higher threshold */
5900     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
5901     if (rc != 0) {
5902         pr_err("error %d\n", rc);
5903         goto rw_error;
5904     }   /* burst detection on   */
5905     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
5906     if (rc != 0) {
5907         pr_err("error %d\n", rc);
5908         goto rw_error;
5909     }   /* drop thresholds by 1 dB */
5910     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
5911     if (rc != 0) {
5912         pr_err("error %d\n", rc);
5913         goto rw_error;
5914     }   /* drop thresholds by 2 dB */
5915     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
5916     if (rc != 0) {
5917         pr_err("error %d\n", rc);
5918         goto rw_error;
5919     }   /* cma on               */
5920     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
5921     if (rc != 0) {
5922         pr_err("error %d\n", rc);
5923         goto rw_error;
5924     }   /* GPIO               */
5925 
5926     /* Initialize the FEC Subsystem */
5927     rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
5928     if (rc != 0) {
5929         pr_err("error %d\n", rc);
5930         goto rw_error;
5931     }
5932     {
5933         u16 fec_oc_snc_mode = 0;
5934         rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
5935         if (rc != 0) {
5936             pr_err("error %d\n", rc);
5937             goto rw_error;
5938         }
5939         /* output data even when not locked */
5940         rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
5941         if (rc != 0) {
5942             pr_err("error %d\n", rc);
5943             goto rw_error;
5944         }
5945     }
5946 
5947     /* set clip */
5948     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
5949     if (rc != 0) {
5950         pr_err("error %d\n", rc);
5951         goto rw_error;
5952     }
5953     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
5954     if (rc != 0) {
5955         pr_err("error %d\n", rc);
5956         goto rw_error;
5957     }
5958     rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
5959     if (rc != 0) {
5960         pr_err("error %d\n", rc);
5961         goto rw_error;
5962     }
5963     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
5964     if (rc != 0) {
5965         pr_err("error %d\n", rc);
5966         goto rw_error;
5967     }
5968     /* no transparent, no A&C framing; parity is set in mpegoutput */
5969     {
5970         u16 fec_oc_reg_mode = 0;
5971         rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
5972         if (rc != 0) {
5973             pr_err("error %d\n", rc);
5974             goto rw_error;
5975         }
5976         rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), 0);
5977         if (rc != 0) {
5978             pr_err("error %d\n", rc);
5979             goto rw_error;
5980         }
5981     }
5982 
5983     rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
5984     if (rc != 0) {
5985         pr_err("error %d\n", rc);
5986         goto rw_error;
5987     }   /* timeout counter for restarting */
5988     rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
5989     if (rc != 0) {
5990         pr_err("error %d\n", rc);
5991         goto rw_error;
5992     }
5993     rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);
5994     if (rc != 0) {
5995         pr_err("error %d\n", rc);
5996         goto rw_error;
5997     }   /* bypass disabled */
5998     /* initialize RS packet error measurement parameters */
5999     rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
6000     if (rc != 0) {
6001         pr_err("error %d\n", rc);
6002         goto rw_error;
6003     }
6004     rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
6005     if (rc != 0) {
6006         pr_err("error %d\n", rc);
6007         goto rw_error;
6008     }
6009 
6010     /* init measurement period of MER/SER */
6011     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
6012     if (rc != 0) {
6013         pr_err("error %d\n", rc);
6014         goto rw_error;
6015     }
6016     rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
6017     if (rc != 0) {
6018         pr_err("error %d\n", rc);
6019         goto rw_error;
6020     }
6021     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
6022     if (rc != 0) {
6023         pr_err("error %d\n", rc);
6024         goto rw_error;
6025     }
6026     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
6027     if (rc != 0) {
6028         pr_err("error %d\n", rc);
6029         goto rw_error;
6030     }
6031 
6032     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
6033     if (rc != 0) {
6034         pr_err("error %d\n", rc);
6035         goto rw_error;
6036     }
6037     /* B-Input to ADC, PGA+filter in standby */
6038     if (!ext_attr->has_lna) {
6039         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
6040         if (rc != 0) {
6041             pr_err("error %d\n", rc);
6042             goto rw_error;
6043         }
6044     }
6045 
6046     /* turn on IQMAF. It has to be in front of setAgc**() */
6047     rc = set_iqm_af(demod, true);
6048     if (rc != 0) {
6049         pr_err("error %d\n", rc);
6050         goto rw_error;
6051     }
6052     rc = adc_synchronization(demod);
6053     if (rc != 0) {
6054         pr_err("error %d\n", rc);
6055         goto rw_error;
6056     }
6057 
6058     rc = init_agc(demod);
6059     if (rc != 0) {
6060         pr_err("error %d\n", rc);
6061         goto rw_error;
6062     }
6063     rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
6064     if (rc != 0) {
6065         pr_err("error %d\n", rc);
6066         goto rw_error;
6067     }
6068     rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
6069     if (rc != 0) {
6070         pr_err("error %d\n", rc);
6071         goto rw_error;
6072     }
6073     {
6074         /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
6075            of only the gain */
6076         struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
6077 
6078         vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
6079         rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
6080         if (rc != 0) {
6081             pr_err("error %d\n", rc);
6082             goto rw_error;
6083         }
6084     }
6085     rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
6086     if (rc != 0) {
6087         pr_err("error %d\n", rc);
6088         goto rw_error;
6089     }
6090 
6091     /* Mpeg output has to be in front of FEC active */
6092     rc = set_mpegtei_handling(demod);
6093     if (rc != 0) {
6094         pr_err("error %d\n", rc);
6095         goto rw_error;
6096     }
6097     rc = bit_reverse_mpeg_output(demod);
6098     if (rc != 0) {
6099         pr_err("error %d\n", rc);
6100         goto rw_error;
6101     }
6102     rc = set_mpeg_start_width(demod);
6103     if (rc != 0) {
6104         pr_err("error %d\n", rc);
6105         goto rw_error;
6106     }
6107     {
6108         /* TODO: move to set_standard after hardware reset value problem is solved */
6109         /* Configure initial MPEG output */
6110         struct drx_cfg_mpeg_output cfg_mpeg_output;
6111 
6112         memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6113         cfg_mpeg_output.enable_mpeg_output = true;
6114 
6115         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6116         if (rc != 0) {
6117             pr_err("error %d\n", rc);
6118             goto rw_error;
6119         }
6120     }
6121 
6122     /* TBD: what parameters should be set */
6123     cmd_param = 0x00;   /* Default mode AGC on, etc */
6124     cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6125         | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
6126     cmd_scu.parameter_len = 1;
6127     cmd_scu.result_len = 1;
6128     cmd_scu.parameter = &cmd_param;
6129     cmd_scu.result = &cmd_result;
6130     rc = scu_command(dev_addr, &cmd_scu);
6131     if (rc != 0) {
6132         pr_err("error %d\n", rc);
6133         goto rw_error;
6134     }
6135 
6136     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
6137     if (rc != 0) {
6138         pr_err("error %d\n", rc);
6139         goto rw_error;
6140     }
6141     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
6142     if (rc != 0) {
6143         pr_err("error %d\n", rc);
6144         goto rw_error;
6145     }
6146     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
6147     if (rc != 0) {
6148         pr_err("error %d\n", rc);
6149         goto rw_error;
6150     }
6151     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
6152     if (rc != 0) {
6153         pr_err("error %d\n", rc);
6154         goto rw_error;
6155     }
6156     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
6157     if (rc != 0) {
6158         pr_err("error %d\n", rc);
6159         goto rw_error;
6160     }
6161     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
6162     if (rc != 0) {
6163         pr_err("error %d\n", rc);
6164         goto rw_error;
6165     }
6166     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
6167     if (rc != 0) {
6168         pr_err("error %d\n", rc);
6169         goto rw_error;
6170     }
6171     rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
6172     if (rc != 0) {
6173         pr_err("error %d\n", rc);
6174         goto rw_error;
6175     }
6176 
6177     /* start demodulator */
6178     cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6179         | SCU_RAM_COMMAND_CMD_DEMOD_START;
6180     cmd_scu.parameter_len = 0;
6181     cmd_scu.result_len = 1;
6182     cmd_scu.parameter = NULL;
6183     cmd_scu.result = &cmd_result;
6184     rc = scu_command(dev_addr, &cmd_scu);
6185     if (rc != 0) {
6186         pr_err("error %d\n", rc);
6187         goto rw_error;
6188     }
6189 
6190     rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
6191     if (rc != 0) {
6192         pr_err("error %d\n", rc);
6193         goto rw_error;
6194     }
6195     rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
6196     if (rc != 0) {
6197         pr_err("error %d\n", rc);
6198         goto rw_error;
6199     }
6200     rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
6201     if (rc != 0) {
6202         pr_err("error %d\n", rc);
6203         goto rw_error;
6204     }
6205 
6206     return 0;
6207 rw_error:
6208     return rc;
6209 }
6210 
6211 /*
6212 * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
6213 * \brief Get the values of packet error in 8VSB mode
6214 * \return Error code
6215 */
6216 static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
6217                    u32 *pck_errs, u32 *pck_count)
6218 {
6219     int rc;
6220     u16 data = 0;
6221     u16 period = 0;
6222     u16 prescale = 0;
6223     u16 packet_errors_mant = 0;
6224     u16 packet_errors_exp = 0;
6225 
6226     rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
6227     if (rc != 0) {
6228         pr_err("error %d\n", rc);
6229         goto rw_error;
6230     }
6231     packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6232     packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
6233         >> FEC_RS_NR_FAILURES_EXP__B;
6234     period = FEC_RS_MEASUREMENT_PERIOD;
6235     prescale = FEC_RS_MEASUREMENT_PRESCALE;
6236     /* packet error rate = (error packet number) per second */
6237     /* 77.3 us is time for per packet */
6238     if (period * prescale == 0) {
6239         pr_err("error: period and/or prescale is zero!\n");
6240         return -EIO;
6241     }
6242     *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
6243     *pck_count = period * prescale * 77;
6244 
6245     return 0;
6246 rw_error:
6247     return rc;
6248 }
6249 
6250 /*
6251 * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
6252 * \brief Get the values of ber in VSB mode
6253 * \return Error code
6254 */
6255 static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
6256                     u32 *ber, u32 *cnt)
6257 {
6258     int rc;
6259     u16 data = 0;
6260     u16 period = 0;
6261     u16 prescale = 0;
6262     u16 bit_errors_mant = 0;
6263     u16 bit_errors_exp = 0;
6264 
6265     rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
6266     if (rc != 0) {
6267         pr_err("error %d\n", rc);
6268         goto rw_error;
6269     }
6270     period = FEC_RS_MEASUREMENT_PERIOD;
6271     prescale = FEC_RS_MEASUREMENT_PRESCALE;
6272 
6273     bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6274     bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
6275         >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6276 
6277     *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
6278 
6279     if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
6280         *ber = (*cnt) * 26570;
6281     else {
6282         if (period * prescale == 0) {
6283             pr_err("error: period and/or prescale is zero!\n");
6284             return -EIO;
6285         }
6286         *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
6287             (bit_errors_exp - 3) : bit_errors_exp);
6288     }
6289 
6290     return 0;
6291 rw_error:
6292     return rc;
6293 }
6294 
6295 /*
6296 * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
6297 * \brief Get the values of ber in VSB mode
6298 * \return Error code
6299 */
6300 static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
6301                    u32 *ber, u32 *cnt)
6302 {
6303     u16 data = 0;
6304     int rc;
6305 
6306     rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
6307     if (rc != 0) {
6308         pr_err("error %d\n", rc);
6309         return -EIO;
6310     }
6311     *ber = data;
6312     *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
6313 
6314     return 0;
6315 }
6316 
6317 /*
6318 * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6319 * \brief Get the values of MER
6320 * \return Error code
6321 */
6322 static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6323 {
6324     int rc;
6325     u16 data_hi = 0;
6326 
6327     rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
6328     if (rc != 0) {
6329         pr_err("error %d\n", rc);
6330         goto rw_error;
6331     }
6332     *mer =
6333         (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
6334 
6335     return 0;
6336 rw_error:
6337     return rc;
6338 }
6339 
6340 
6341 /*============================================================================*/
6342 /*==                     END 8VSB DATAPATH FUNCTIONS                        ==*/
6343 /*============================================================================*/
6344 
6345 /*============================================================================*/
6346 /*============================================================================*/
6347 /*==                       QAM DATAPATH FUNCTIONS                           ==*/
6348 /*============================================================================*/
6349 /*============================================================================*/
6350 
6351 /*
6352 * \fn int power_down_qam ()
6353 * \brief Powr down QAM related blocks.
6354 * \param demod instance of demodulator.
6355 * \param channel pointer to channel data.
6356 * \return int.
6357 */
6358 static int power_down_qam(struct drx_demod_instance *demod, bool primary)
6359 {
6360     struct drxjscu_cmd cmd_scu = { /* command      */ 0,
6361         /* parameter_len */ 0,
6362         /* result_len    */ 0,
6363         /* *parameter   */ NULL,
6364         /* *result      */ NULL
6365     };
6366     int rc;
6367     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6368     struct drx_cfg_mpeg_output cfg_mpeg_output;
6369     struct drx_common_attr *common_attr = demod->my_common_attr;
6370     u16 cmd_result = 0;
6371 
6372     /*
6373        STOP demodulator
6374        resets IQM, QAM and FEC HW blocks
6375      */
6376     /* stop all comm_exec */
6377     rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
6378     if (rc != 0) {
6379         pr_err("error %d\n", rc);
6380         goto rw_error;
6381     }
6382     rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
6383     if (rc != 0) {
6384         pr_err("error %d\n", rc);
6385         goto rw_error;
6386     }
6387 
6388     cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
6389         SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6390     cmd_scu.parameter_len = 0;
6391     cmd_scu.result_len = 1;
6392     cmd_scu.parameter = NULL;
6393     cmd_scu.result = &cmd_result;
6394     rc = scu_command(dev_addr, &cmd_scu);
6395     if (rc != 0) {
6396         pr_err("error %d\n", rc);
6397         goto rw_error;
6398     }
6399 
6400     if (primary) {
6401         rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
6402         if (rc != 0) {
6403             pr_err("error %d\n", rc);
6404             goto rw_error;
6405         }
6406         rc = set_iqm_af(demod, false);
6407         if (rc != 0) {
6408             pr_err("error %d\n", rc);
6409             goto rw_error;
6410         }
6411     } else {
6412         rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
6413         if (rc != 0) {
6414             pr_err("error %d\n", rc);
6415             goto rw_error;
6416         }
6417         rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
6418         if (rc != 0) {
6419             pr_err("error %d\n", rc);
6420             goto rw_error;
6421         }
6422         rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
6423         if (rc != 0) {
6424             pr_err("error %d\n", rc);
6425             goto rw_error;
6426         }
6427         rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
6428         if (rc != 0) {
6429             pr_err("error %d\n", rc);
6430             goto rw_error;
6431         }
6432         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
6433         if (rc != 0) {
6434             pr_err("error %d\n", rc);
6435             goto rw_error;
6436         }
6437     }
6438 
6439     memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6440     cfg_mpeg_output.enable_mpeg_output = false;
6441 
6442     rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6443     if (rc != 0) {
6444         pr_err("error %d\n", rc);
6445         goto rw_error;
6446     }
6447 
6448     return 0;
6449 rw_error:
6450     return rc;
6451 }
6452 
6453 /*============================================================================*/
6454 
6455 /*
6456 * \fn int set_qam_measurement ()
6457 * \brief Setup of the QAM Measuremnt intervals for signal quality
6458 * \param demod instance of demod.
6459 * \param constellation current constellation.
6460 * \return int.
6461 *
6462 *  NOTE:
6463 *  Take into account that for certain settings the errorcounters can overflow.
6464 *  The implementation does not check this.
6465 *
6466 *  TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
6467 *  constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
6468 *  field ?
6469 *
6470 */
6471 #ifndef DRXJ_VSB_ONLY
6472 static int
6473 set_qam_measurement(struct drx_demod_instance *demod,
6474             enum drx_modulation constellation, u32 symbol_rate)
6475 {
6476     struct i2c_device_addr *dev_addr = NULL;    /* device address for I2C writes */
6477     struct drxj_data *ext_attr = NULL;  /* Global data container for DRXJ specific data */
6478     int rc;
6479     u32 fec_bits_desired = 0;   /* BER accounting period */
6480     u16 fec_rs_plen = 0;    /* defines RS BER measurement period */
6481     u16 fec_rs_prescale = 0;    /* ReedSolomon Measurement Prescale */
6482     u32 fec_rs_period = 0;  /* Value for corresponding I2C register */
6483     u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
6484     u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
6485     u32 qam_vd_period = 0;  /* Value for corresponding I2C register */
6486     u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
6487     u16 fec_vd_plen = 0;    /* no of trellis symbols: VD SER measur period */
6488     u16 qam_vd_prescale = 0;    /* Viterbi Measurement Prescale */
6489 
6490     dev_addr = demod->my_i2c_dev_addr;
6491     ext_attr = (struct drxj_data *) demod->my_ext_attr;
6492 
6493     fec_bits_desired = ext_attr->fec_bits_desired;
6494     fec_rs_prescale = ext_attr->fec_rs_prescale;
6495 
6496     switch (constellation) {
6497     case DRX_CONSTELLATION_QAM16:
6498         fec_bits_desired = 4 * symbol_rate;
6499         break;
6500     case DRX_CONSTELLATION_QAM32:
6501         fec_bits_desired = 5 * symbol_rate;
6502         break;
6503     case DRX_CONSTELLATION_QAM64:
6504         fec_bits_desired = 6 * symbol_rate;
6505         break;
6506     case DRX_CONSTELLATION_QAM128:
6507         fec_bits_desired = 7 * symbol_rate;
6508         break;
6509     case DRX_CONSTELLATION_QAM256:
6510         fec_bits_desired = 8 * symbol_rate;
6511         break;
6512     default:
6513         return -EINVAL;
6514     }
6515 
6516     /* Parameters for Reed-Solomon Decoder */
6517     /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6518     /* rs_bit_cnt   = fecrs_period*fecrs_prescale*plen                  */
6519     /*     result is within 32 bit arithmetic ->                        */
6520     /*     no need for mult or frac functions                           */
6521 
6522     /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
6523     switch (ext_attr->standard) {
6524     case DRX_STANDARD_ITU_A:
6525     case DRX_STANDARD_ITU_C:
6526         fec_rs_plen = 204 * 8;
6527         break;
6528     case DRX_STANDARD_ITU_B:
6529         fec_rs_plen = 128 * 7;
6530         break;
6531     default:
6532         return -EINVAL;
6533     }
6534 
6535     ext_attr->fec_rs_plen = fec_rs_plen;    /* for getSigQual */
6536     fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage   */
6537     if (fec_rs_bit_cnt == 0) {
6538         pr_err("error: fec_rs_bit_cnt is zero!\n");
6539         return -EIO;
6540     }
6541     fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1;  /* ceil */
6542     if (ext_attr->standard != DRX_STANDARD_ITU_B)
6543         fec_oc_snc_fail_period = fec_rs_period;
6544 
6545     /* limit to max 16 bit value (I2C register width) if needed */
6546     if (fec_rs_period > 0xFFFF)
6547         fec_rs_period = 0xFFFF;
6548 
6549     /* write corresponding registers */
6550     switch (ext_attr->standard) {
6551     case DRX_STANDARD_ITU_A:
6552     case DRX_STANDARD_ITU_C:
6553         break;
6554     case DRX_STANDARD_ITU_B:
6555         switch (constellation) {
6556         case DRX_CONSTELLATION_QAM64:
6557             fec_rs_period = 31581;
6558             fec_oc_snc_fail_period = 17932;
6559             break;
6560         case DRX_CONSTELLATION_QAM256:
6561             fec_rs_period = 45446;
6562             fec_oc_snc_fail_period = 25805;
6563             break;
6564         default:
6565             return -EINVAL;
6566         }
6567         break;
6568     default:
6569         return -EINVAL;
6570     }
6571 
6572     rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
6573     if (rc != 0) {
6574         pr_err("error %d\n", rc);
6575         goto rw_error;
6576     }
6577     rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
6578     if (rc != 0) {
6579         pr_err("error %d\n", rc);
6580         goto rw_error;
6581     }
6582     rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
6583     if (rc != 0) {
6584         pr_err("error %d\n", rc);
6585         goto rw_error;
6586     }
6587     ext_attr->fec_rs_period = (u16) fec_rs_period;
6588     ext_attr->fec_rs_prescale = fec_rs_prescale;
6589     rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
6590     if (rc != 0) {
6591         pr_err("error %d\n", rc);
6592         goto rw_error;
6593     }
6594     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
6595     if (rc != 0) {
6596         pr_err("error %d\n", rc);
6597         goto rw_error;
6598     }
6599     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
6600     if (rc != 0) {
6601         pr_err("error %d\n", rc);
6602         goto rw_error;
6603     }
6604 
6605     if (ext_attr->standard == DRX_STANDARD_ITU_B) {
6606         /* Parameters for Viterbi Decoder */
6607         /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/                      */
6608         /*                    (qamvd_prescale*plen*(qam_constellation+1))) */
6609         /* vd_bit_cnt   = qamvd_period*qamvd_prescale*plen                 */
6610         /*     result is within 32 bit arithmetic ->                       */
6611         /*     no need for mult or frac functions                          */
6612 
6613         /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
6614         fec_vd_plen = ext_attr->fec_vd_plen;
6615         qam_vd_prescale = ext_attr->qam_vd_prescale;
6616         qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
6617 
6618         switch (constellation) {
6619         case DRX_CONSTELLATION_QAM64:
6620             /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
6621             qam_vd_period =
6622                 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
6623                 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6624             break;
6625         case DRX_CONSTELLATION_QAM256:
6626             /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
6627             qam_vd_period =
6628                 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
6629                 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6630             break;
6631         default:
6632             return -EINVAL;
6633         }
6634         if (qam_vd_period == 0) {
6635             pr_err("error: qam_vd_period is zero!\n");
6636             return -EIO;
6637         }
6638         qam_vd_period = fec_bits_desired / qam_vd_period;
6639         /* limit to max 16 bit value (I2C register width) if needed */
6640         if (qam_vd_period > 0xFFFF)
6641             qam_vd_period = 0xFFFF;
6642 
6643         /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
6644         qam_vd_bit_cnt *= qam_vd_period;
6645 
6646         rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
6647         if (rc != 0) {
6648             pr_err("error %d\n", rc);
6649             goto rw_error;
6650         }
6651         rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
6652         if (rc != 0) {
6653             pr_err("error %d\n", rc);
6654             goto rw_error;
6655         }
6656         ext_attr->qam_vd_period = (u16) qam_vd_period;
6657         ext_attr->qam_vd_prescale = qam_vd_prescale;
6658     }
6659 
6660     return 0;
6661 rw_error:
6662     return rc;
6663 }
6664 
6665 /*============================================================================*/
6666 
6667 /*
6668 * \fn int set_qam16 ()
6669 * \brief QAM16 specific setup
6670 * \param demod instance of demod.
6671 * \return int.
6672 */
6673 static int set_qam16(struct drx_demod_instance *demod)
6674 {
6675     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6676     int rc;
6677     static const u8 qam_dq_qual_fun[] = {
6678         DRXJ_16TO8(2),  /* fun0  */
6679         DRXJ_16TO8(2),  /* fun1  */
6680         DRXJ_16TO8(2),  /* fun2  */
6681         DRXJ_16TO8(2),  /* fun3  */
6682         DRXJ_16TO8(3),  /* fun4  */
6683         DRXJ_16TO8(3),  /* fun5  */
6684     };
6685     static const u8 qam_eq_cma_rad[] = {
6686         DRXJ_16TO8(13517),  /* RAD0  */
6687         DRXJ_16TO8(13517),  /* RAD1  */
6688         DRXJ_16TO8(13517),  /* RAD2  */
6689         DRXJ_16TO8(13517),  /* RAD3  */
6690         DRXJ_16TO8(13517),  /* RAD4  */
6691         DRXJ_16TO8(13517),  /* RAD5  */
6692     };
6693 
6694     rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
6695     if (rc != 0) {
6696         pr_err("error %d\n", rc);
6697         goto rw_error;
6698     }
6699     rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
6700     if (rc != 0) {
6701         pr_err("error %d\n", rc);
6702         goto rw_error;
6703     }
6704 
6705     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
6706     if (rc != 0) {
6707         pr_err("error %d\n", rc);
6708         goto rw_error;
6709     }
6710     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
6711     if (rc != 0) {
6712         pr_err("error %d\n", rc);
6713         goto rw_error;
6714     }
6715     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
6716     if (rc != 0) {
6717         pr_err("error %d\n", rc);
6718         goto rw_error;
6719     }
6720     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
6721     if (rc != 0) {
6722         pr_err("error %d\n", rc);
6723         goto rw_error;
6724     }
6725     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
6726     if (rc != 0) {
6727         pr_err("error %d\n", rc);
6728         goto rw_error;
6729     }
6730     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
6731     if (rc != 0) {
6732         pr_err("error %d\n", rc);
6733         goto rw_error;
6734     }
6735 
6736     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
6737     if (rc != 0) {
6738         pr_err("error %d\n", rc);
6739         goto rw_error;
6740     }
6741     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
6742     if (rc != 0) {
6743         pr_err("error %d\n", rc);
6744         goto rw_error;
6745     }
6746     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
6747     if (rc != 0) {
6748         pr_err("error %d\n", rc);
6749         goto rw_error;
6750     }
6751 
6752     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
6753     if (rc != 0) {
6754         pr_err("error %d\n", rc);
6755         goto rw_error;
6756     }
6757     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
6758     if (rc != 0) {
6759         pr_err("error %d\n", rc);
6760         goto rw_error;
6761     }
6762     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
6763     if (rc != 0) {
6764         pr_err("error %d\n", rc);
6765         goto rw_error;
6766     }
6767     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
6768     if (rc != 0) {
6769         pr_err("error %d\n", rc);
6770         goto rw_error;
6771     }
6772     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
6773     if (rc != 0) {
6774         pr_err("error %d\n", rc);
6775         goto rw_error;
6776     }
6777     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
6778     if (rc != 0) {
6779         pr_err("error %d\n", rc);
6780         goto rw_error;
6781     }
6782     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
6783     if (rc != 0) {
6784         pr_err("error %d\n", rc);
6785         goto rw_error;
6786     }
6787 
6788     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
6789     if (rc != 0) {
6790         pr_err("error %d\n", rc);
6791         goto rw_error;
6792     }
6793     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
6794     if (rc != 0) {
6795         pr_err("error %d\n", rc);
6796         goto rw_error;
6797     }
6798     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
6799     if (rc != 0) {
6800         pr_err("error %d\n", rc);
6801         goto rw_error;
6802     }
6803     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
6804     if (rc != 0) {
6805         pr_err("error %d\n", rc);
6806         goto rw_error;
6807     }
6808     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
6809     if (rc != 0) {
6810         pr_err("error %d\n", rc);
6811         goto rw_error;
6812     }
6813     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
6814     if (rc != 0) {
6815         pr_err("error %d\n", rc);
6816         goto rw_error;
6817     }
6818     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
6819     if (rc != 0) {
6820         pr_err("error %d\n", rc);
6821         goto rw_error;
6822     }
6823     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
6824     if (rc != 0) {
6825         pr_err("error %d\n", rc);
6826         goto rw_error;
6827     }
6828     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
6829     if (rc != 0) {
6830         pr_err("error %d\n", rc);
6831         goto rw_error;
6832     }
6833     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
6834     if (rc != 0) {
6835         pr_err("error %d\n", rc);
6836         goto rw_error;
6837     }
6838     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
6839     if (rc != 0) {
6840         pr_err("error %d\n", rc);
6841         goto rw_error;
6842     }
6843     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
6844     if (rc != 0) {
6845         pr_err("error %d\n", rc);
6846         goto rw_error;
6847     }
6848     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
6849     if (rc != 0) {
6850         pr_err("error %d\n", rc);
6851         goto rw_error;
6852     }
6853     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
6854     if (rc != 0) {
6855         pr_err("error %d\n", rc);
6856         goto rw_error;
6857     }
6858     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
6859     if (rc != 0) {
6860         pr_err("error %d\n", rc);
6861         goto rw_error;
6862     }
6863     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
6864     if (rc != 0) {
6865         pr_err("error %d\n", rc);
6866         goto rw_error;
6867     }
6868     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
6869     if (rc != 0) {
6870         pr_err("error %d\n", rc);
6871         goto rw_error;
6872     }
6873     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
6874     if (rc != 0) {
6875         pr_err("error %d\n", rc);
6876         goto rw_error;
6877     }
6878     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
6879     if (rc != 0) {
6880         pr_err("error %d\n", rc);
6881         goto rw_error;
6882     }
6883     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
6884     if (rc != 0) {
6885         pr_err("error %d\n", rc);
6886         goto rw_error;
6887     }
6888 
6889     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
6890     if (rc != 0) {
6891         pr_err("error %d\n", rc);
6892         goto rw_error;
6893     }
6894 
6895     return 0;
6896 rw_error:
6897     return rc;
6898 }
6899 
6900 /*============================================================================*/
6901 
6902 /*
6903 * \fn int set_qam32 ()
6904 * \brief QAM32 specific setup
6905 * \param demod instance of demod.
6906 * \return int.
6907 */
6908 static int set_qam32(struct drx_demod_instance *demod)
6909 {
6910     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6911     int rc;
6912     static const u8 qam_dq_qual_fun[] = {
6913         DRXJ_16TO8(3),  /* fun0  */
6914         DRXJ_16TO8(3),  /* fun1  */
6915         DRXJ_16TO8(3),  /* fun2  */
6916         DRXJ_16TO8(3),  /* fun3  */
6917         DRXJ_16TO8(4),  /* fun4  */
6918         DRXJ_16TO8(4),  /* fun5  */
6919     };
6920     static const u8 qam_eq_cma_rad[] = {
6921         DRXJ_16TO8(6707),   /* RAD0  */
6922         DRXJ_16TO8(6707),   /* RAD1  */
6923         DRXJ_16TO8(6707),   /* RAD2  */
6924         DRXJ_16TO8(6707),   /* RAD3  */
6925         DRXJ_16TO8(6707),   /* RAD4  */
6926         DRXJ_16TO8(6707),   /* RAD5  */
6927     };
6928 
6929     rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
6930     if (rc != 0) {
6931         pr_err("error %d\n", rc);
6932         goto rw_error;
6933     }
6934     rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
6935     if (rc != 0) {
6936         pr_err("error %d\n", rc);
6937         goto rw_error;
6938     }
6939 
6940     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
6941     if (rc != 0) {
6942         pr_err("error %d\n", rc);
6943         goto rw_error;
6944     }
6945     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
6946     if (rc != 0) {
6947         pr_err("error %d\n", rc);
6948         goto rw_error;
6949     }
6950     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
6951     if (rc != 0) {
6952         pr_err("error %d\n", rc);
6953         goto rw_error;
6954     }
6955     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
6956     if (rc != 0) {
6957         pr_err("error %d\n", rc);
6958         goto rw_error;
6959     }
6960     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
6961     if (rc != 0) {
6962         pr_err("error %d\n", rc);
6963         goto rw_error;
6964     }
6965     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
6966     if (rc != 0) {
6967         pr_err("error %d\n", rc);
6968         goto rw_error;
6969     }
6970 
6971     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
6972     if (rc != 0) {
6973         pr_err("error %d\n", rc);
6974         goto rw_error;
6975     }
6976     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
6977     if (rc != 0) {
6978         pr_err("error %d\n", rc);
6979         goto rw_error;
6980     }
6981     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
6982     if (rc != 0) {
6983         pr_err("error %d\n", rc);
6984         goto rw_error;
6985     }
6986 
6987     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
6988     if (rc != 0) {
6989         pr_err("error %d\n", rc);
6990         goto rw_error;
6991     }
6992     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
6993     if (rc != 0) {
6994         pr_err("error %d\n", rc);
6995         goto rw_error;
6996     }
6997     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
6998     if (rc != 0) {
6999         pr_err("error %d\n", rc);
7000         goto rw_error;
7001     }
7002     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
7003     if (rc != 0) {
7004         pr_err("error %d\n", rc);
7005         goto rw_error;
7006     }
7007     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
7008     if (rc != 0) {
7009         pr_err("error %d\n", rc);
7010         goto rw_error;
7011     }
7012     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
7013     if (rc != 0) {
7014         pr_err("error %d\n", rc);
7015         goto rw_error;
7016     }
7017     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
7018     if (rc != 0) {
7019         pr_err("error %d\n", rc);
7020         goto rw_error;
7021     }
7022 
7023     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7024     if (rc != 0) {
7025         pr_err("error %d\n", rc);
7026         goto rw_error;
7027     }
7028     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7029     if (rc != 0) {
7030         pr_err("error %d\n", rc);
7031         goto rw_error;
7032     }
7033     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7034     if (rc != 0) {
7035         pr_err("error %d\n", rc);
7036         goto rw_error;
7037     }
7038     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
7039     if (rc != 0) {
7040         pr_err("error %d\n", rc);
7041         goto rw_error;
7042     }
7043     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7044     if (rc != 0) {
7045         pr_err("error %d\n", rc);
7046         goto rw_error;
7047     }
7048     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7049     if (rc != 0) {
7050         pr_err("error %d\n", rc);
7051         goto rw_error;
7052     }
7053     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
7054     if (rc != 0) {
7055         pr_err("error %d\n", rc);
7056         goto rw_error;
7057     }
7058     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
7059     if (rc != 0) {
7060         pr_err("error %d\n", rc);
7061         goto rw_error;
7062     }
7063     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7064     if (rc != 0) {
7065         pr_err("error %d\n", rc);
7066         goto rw_error;
7067     }
7068     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7069     if (rc != 0) {
7070         pr_err("error %d\n", rc);
7071         goto rw_error;
7072     }
7073     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7074     if (rc != 0) {
7075         pr_err("error %d\n", rc);
7076         goto rw_error;
7077     }
7078     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7079     if (rc != 0) {
7080         pr_err("error %d\n", rc);
7081         goto rw_error;
7082     }
7083     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7084     if (rc != 0) {
7085         pr_err("error %d\n", rc);
7086         goto rw_error;
7087     }
7088     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7089     if (rc != 0) {
7090         pr_err("error %d\n", rc);
7091         goto rw_error;
7092     }
7093     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7094     if (rc != 0) {
7095         pr_err("error %d\n", rc);
7096         goto rw_error;
7097     }
7098     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
7099     if (rc != 0) {
7100         pr_err("error %d\n", rc);
7101         goto rw_error;
7102     }
7103     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
7104     if (rc != 0) {
7105         pr_err("error %d\n", rc);
7106         goto rw_error;
7107     }
7108     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7109     if (rc != 0) {
7110         pr_err("error %d\n", rc);
7111         goto rw_error;
7112     }
7113     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7114     if (rc != 0) {
7115         pr_err("error %d\n", rc);
7116         goto rw_error;
7117     }
7118     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
7119     if (rc != 0) {
7120         pr_err("error %d\n", rc);
7121         goto rw_error;
7122     }
7123 
7124     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
7125     if (rc != 0) {
7126         pr_err("error %d\n", rc);
7127         goto rw_error;
7128     }
7129 
7130     return 0;
7131 rw_error:
7132     return rc;
7133 }
7134 
7135 /*============================================================================*/
7136 
7137 /*
7138 * \fn int set_qam64 ()
7139 * \brief QAM64 specific setup
7140 * \param demod instance of demod.
7141 * \return int.
7142 */
7143 static int set_qam64(struct drx_demod_instance *demod)
7144 {
7145     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7146     int rc;
7147     static const u8 qam_dq_qual_fun[] = {
7148         /* this is hw reset value. no necessary to re-write */
7149         DRXJ_16TO8(4),  /* fun0  */
7150         DRXJ_16TO8(4),  /* fun1  */
7151         DRXJ_16TO8(4),  /* fun2  */
7152         DRXJ_16TO8(4),  /* fun3  */
7153         DRXJ_16TO8(6),  /* fun4  */
7154         DRXJ_16TO8(6),  /* fun5  */
7155     };
7156     static const u8 qam_eq_cma_rad[] = {
7157         DRXJ_16TO8(13336),  /* RAD0  */
7158         DRXJ_16TO8(12618),  /* RAD1  */
7159         DRXJ_16TO8(11988),  /* RAD2  */
7160         DRXJ_16TO8(13809),  /* RAD3  */
7161         DRXJ_16TO8(13809),  /* RAD4  */
7162         DRXJ_16TO8(15609),  /* RAD5  */
7163     };
7164 
7165     rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7166     if (rc != 0) {
7167         pr_err("error %d\n", rc);
7168         goto rw_error;
7169     }
7170     rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7171     if (rc != 0) {
7172         pr_err("error %d\n", rc);
7173         goto rw_error;
7174     }
7175 
7176     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
7177     if (rc != 0) {
7178         pr_err("error %d\n", rc);
7179         goto rw_error;
7180     }
7181     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7182     if (rc != 0) {
7183         pr_err("error %d\n", rc);
7184         goto rw_error;
7185     }
7186     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7187     if (rc != 0) {
7188         pr_err("error %d\n", rc);
7189         goto rw_error;
7190     }
7191     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
7192     if (rc != 0) {
7193         pr_err("error %d\n", rc);
7194         goto rw_error;
7195     }
7196     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7197     if (rc != 0) {
7198         pr_err("error %d\n", rc);
7199         goto rw_error;
7200     }
7201     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
7202     if (rc != 0) {
7203         pr_err("error %d\n", rc);
7204         goto rw_error;
7205     }
7206 
7207     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7208     if (rc != 0) {
7209         pr_err("error %d\n", rc);
7210         goto rw_error;
7211     }
7212     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
7213     if (rc != 0) {
7214         pr_err("error %d\n", rc);
7215         goto rw_error;
7216     }
7217     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7218     if (rc != 0) {
7219         pr_err("error %d\n", rc);
7220         goto rw_error;
7221     }
7222 
7223     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
7224     if (rc != 0) {
7225         pr_err("error %d\n", rc);
7226         goto rw_error;
7227     }
7228     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
7229     if (rc != 0) {
7230         pr_err("error %d\n", rc);
7231         goto rw_error;
7232     }
7233     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
7234     if (rc != 0) {
7235         pr_err("error %d\n", rc);
7236         goto rw_error;
7237     }
7238     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
7239     if (rc != 0) {
7240         pr_err("error %d\n", rc);
7241         goto rw_error;
7242     }
7243     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
7244     if (rc != 0) {
7245         pr_err("error %d\n", rc);
7246         goto rw_error;
7247     }
7248     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
7249     if (rc != 0) {
7250         pr_err("error %d\n", rc);
7251         goto rw_error;
7252     }
7253     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
7254     if (rc != 0) {
7255         pr_err("error %d\n", rc);
7256         goto rw_error;
7257     }
7258 
7259     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7260     if (rc != 0) {
7261         pr_err("error %d\n", rc);
7262         goto rw_error;
7263     }
7264     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7265     if (rc != 0) {
7266         pr_err("error %d\n", rc);
7267         goto rw_error;
7268     }
7269     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7270     if (rc != 0) {
7271         pr_err("error %d\n", rc);
7272         goto rw_error;
7273     }
7274     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
7275     if (rc != 0) {
7276         pr_err("error %d\n", rc);
7277         goto rw_error;
7278     }
7279     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7280     if (rc != 0) {
7281         pr_err("error %d\n", rc);
7282         goto rw_error;
7283     }
7284     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7285     if (rc != 0) {
7286         pr_err("error %d\n", rc);
7287         goto rw_error;
7288     }
7289     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
7290     if (rc != 0) {
7291         pr_err("error %d\n", rc);
7292         goto rw_error;
7293     }
7294     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7295     if (rc != 0) {
7296         pr_err("error %d\n", rc);
7297         goto rw_error;
7298     }
7299     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7300     if (rc != 0) {
7301         pr_err("error %d\n", rc);
7302         goto rw_error;
7303     }
7304     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7305     if (rc != 0) {
7306         pr_err("error %d\n", rc);
7307         goto rw_error;
7308     }
7309     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7310     if (rc != 0) {
7311         pr_err("error %d\n", rc);
7312         goto rw_error;
7313     }
7314     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7315     if (rc != 0) {
7316         pr_err("error %d\n", rc);
7317         goto rw_error;
7318     }
7319     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7320     if (rc != 0) {
7321         pr_err("error %d\n", rc);
7322         goto rw_error;
7323     }
7324     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7325     if (rc != 0) {
7326         pr_err("error %d\n", rc);
7327         goto rw_error;
7328     }
7329     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7330     if (rc != 0) {
7331         pr_err("error %d\n", rc);
7332         goto rw_error;
7333     }
7334     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
7335     if (rc != 0) {
7336         pr_err("error %d\n", rc);
7337         goto rw_error;
7338     }
7339     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
7340     if (rc != 0) {
7341         pr_err("error %d\n", rc);
7342         goto rw_error;
7343     }
7344     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7345     if (rc != 0) {
7346         pr_err("error %d\n", rc);
7347         goto rw_error;
7348     }
7349     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7350     if (rc != 0) {
7351         pr_err("error %d\n", rc);
7352         goto rw_error;
7353     }
7354     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
7355     if (rc != 0) {
7356         pr_err("error %d\n", rc);
7357         goto rw_error;
7358     }
7359 
7360     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
7361     if (rc != 0) {
7362         pr_err("error %d\n", rc);
7363         goto rw_error;
7364     }
7365 
7366     return 0;
7367 rw_error:
7368     return rc;
7369 }
7370 
7371 /*============================================================================*/
7372 
7373 /*
7374 * \fn int set_qam128 ()
7375 * \brief QAM128 specific setup
7376 * \param demod: instance of demod.
7377 * \return int.
7378 */
7379 static int set_qam128(struct drx_demod_instance *demod)
7380 {
7381     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7382     int rc;
7383     static const u8 qam_dq_qual_fun[] = {
7384         DRXJ_16TO8(6),  /* fun0  */
7385         DRXJ_16TO8(6),  /* fun1  */
7386         DRXJ_16TO8(6),  /* fun2  */
7387         DRXJ_16TO8(6),  /* fun3  */
7388         DRXJ_16TO8(9),  /* fun4  */
7389         DRXJ_16TO8(9),  /* fun5  */
7390     };
7391     static const u8 qam_eq_cma_rad[] = {
7392         DRXJ_16TO8(6164),   /* RAD0  */
7393         DRXJ_16TO8(6598),   /* RAD1  */
7394         DRXJ_16TO8(6394),   /* RAD2  */
7395         DRXJ_16TO8(6409),   /* RAD3  */
7396         DRXJ_16TO8(6656),   /* RAD4  */
7397         DRXJ_16TO8(7238),   /* RAD5  */
7398     };
7399 
7400     rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7401     if (rc != 0) {
7402         pr_err("error %d\n", rc);
7403         goto rw_error;
7404     }
7405     rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7406     if (rc != 0) {
7407         pr_err("error %d\n", rc);
7408         goto rw_error;
7409     }
7410 
7411     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
7412     if (rc != 0) {
7413         pr_err("error %d\n", rc);
7414         goto rw_error;
7415     }
7416     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7417     if (rc != 0) {
7418         pr_err("error %d\n", rc);
7419         goto rw_error;
7420     }
7421     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7422     if (rc != 0) {
7423         pr_err("error %d\n", rc);
7424         goto rw_error;
7425     }
7426     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
7427     if (rc != 0) {
7428         pr_err("error %d\n", rc);
7429         goto rw_error;
7430     }
7431     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7432     if (rc != 0) {
7433         pr_err("error %d\n", rc);
7434         goto rw_error;
7435     }
7436     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
7437     if (rc != 0) {
7438         pr_err("error %d\n", rc);
7439         goto rw_error;
7440     }
7441 
7442     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7443     if (rc != 0) {
7444         pr_err("error %d\n", rc);
7445         goto rw_error;
7446     }
7447     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
7448     if (rc != 0) {
7449         pr_err("error %d\n", rc);
7450         goto rw_error;
7451     }
7452     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7453     if (rc != 0) {
7454         pr_err("error %d\n", rc);
7455         goto rw_error;
7456     }
7457 
7458     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
7459     if (rc != 0) {
7460         pr_err("error %d\n", rc);
7461         goto rw_error;
7462     }
7463     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
7464     if (rc != 0) {
7465         pr_err("error %d\n", rc);
7466         goto rw_error;
7467     }
7468     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
7469     if (rc != 0) {
7470         pr_err("error %d\n", rc);
7471         goto rw_error;
7472     }
7473     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
7474     if (rc != 0) {
7475         pr_err("error %d\n", rc);
7476         goto rw_error;
7477     }
7478     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
7479     if (rc != 0) {
7480         pr_err("error %d\n", rc);
7481         goto rw_error;
7482     }
7483     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
7484     if (rc != 0) {
7485         pr_err("error %d\n", rc);
7486         goto rw_error;
7487     }
7488     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
7489     if (rc != 0) {
7490         pr_err("error %d\n", rc);
7491         goto rw_error;
7492     }
7493 
7494     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7495     if (rc != 0) {
7496         pr_err("error %d\n", rc);
7497         goto rw_error;
7498     }
7499     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7500     if (rc != 0) {
7501         pr_err("error %d\n", rc);
7502         goto rw_error;
7503     }
7504     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7505     if (rc != 0) {
7506         pr_err("error %d\n", rc);
7507         goto rw_error;
7508     }
7509     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
7510     if (rc != 0) {
7511         pr_err("error %d\n", rc);
7512         goto rw_error;
7513     }
7514     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7515     if (rc != 0) {
7516         pr_err("error %d\n", rc);
7517         goto rw_error;
7518     }
7519     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7520     if (rc != 0) {
7521         pr_err("error %d\n", rc);
7522         goto rw_error;
7523     }
7524     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
7525     if (rc != 0) {
7526         pr_err("error %d\n", rc);
7527         goto rw_error;
7528     }
7529     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7530     if (rc != 0) {
7531         pr_err("error %d\n", rc);
7532         goto rw_error;
7533     }
7534     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7535     if (rc != 0) {
7536         pr_err("error %d\n", rc);
7537         goto rw_error;
7538     }
7539     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7540     if (rc != 0) {
7541         pr_err("error %d\n", rc);
7542         goto rw_error;
7543     }
7544     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7545     if (rc != 0) {
7546         pr_err("error %d\n", rc);
7547         goto rw_error;
7548     }
7549     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7550     if (rc != 0) {
7551         pr_err("error %d\n", rc);
7552         goto rw_error;
7553     }
7554     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7555     if (rc != 0) {
7556         pr_err("error %d\n", rc);
7557         goto rw_error;
7558     }
7559     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7560     if (rc != 0) {
7561         pr_err("error %d\n", rc);
7562         goto rw_error;
7563     }
7564     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7565     if (rc != 0) {
7566         pr_err("error %d\n", rc);
7567         goto rw_error;
7568     }
7569     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
7570     if (rc != 0) {
7571         pr_err("error %d\n", rc);
7572         goto rw_error;
7573     }
7574     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
7575     if (rc != 0) {
7576         pr_err("error %d\n", rc);
7577         goto rw_error;
7578     }
7579     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7580     if (rc != 0) {
7581         pr_err("error %d\n", rc);
7582         goto rw_error;
7583     }
7584     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7585     if (rc != 0) {
7586         pr_err("error %d\n", rc);
7587         goto rw_error;
7588     }
7589     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
7590     if (rc != 0) {
7591         pr_err("error %d\n", rc);
7592         goto rw_error;
7593     }
7594 
7595     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
7596     if (rc != 0) {
7597         pr_err("error %d\n", rc);
7598         goto rw_error;
7599     }
7600 
7601     return 0;
7602 rw_error:
7603     return rc;
7604 }
7605 
7606 /*============================================================================*/
7607 
7608 /*
7609 * \fn int set_qam256 ()
7610 * \brief QAM256 specific setup
7611 * \param demod: instance of demod.
7612 * \return int.
7613 */
7614 static int set_qam256(struct drx_demod_instance *demod)
7615 {
7616     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7617     int rc;
7618     static const u8 qam_dq_qual_fun[] = {
7619         DRXJ_16TO8(8),  /* fun0  */
7620         DRXJ_16TO8(8),  /* fun1  */
7621         DRXJ_16TO8(8),  /* fun2  */
7622         DRXJ_16TO8(8),  /* fun3  */
7623         DRXJ_16TO8(12), /* fun4  */
7624         DRXJ_16TO8(12), /* fun5  */
7625     };
7626     static const u8 qam_eq_cma_rad[] = {
7627         DRXJ_16TO8(12345),  /* RAD0  */
7628         DRXJ_16TO8(12345),  /* RAD1  */
7629         DRXJ_16TO8(13626),  /* RAD2  */
7630         DRXJ_16TO8(12931),  /* RAD3  */
7631         DRXJ_16TO8(14719),  /* RAD4  */
7632         DRXJ_16TO8(15356),  /* RAD5  */
7633     };
7634 
7635     rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7636     if (rc != 0) {
7637         pr_err("error %d\n", rc);
7638         goto rw_error;
7639     }
7640     rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7641     if (rc != 0) {
7642         pr_err("error %d\n", rc);
7643         goto rw_error;
7644     }
7645 
7646     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
7647     if (rc != 0) {
7648         pr_err("error %d\n", rc);
7649         goto rw_error;
7650     }
7651     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7652     if (rc != 0) {
7653         pr_err("error %d\n", rc);
7654         goto rw_error;
7655     }
7656     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7657     if (rc != 0) {
7658         pr_err("error %d\n", rc);
7659         goto rw_error;
7660     }
7661     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
7662     if (rc != 0) {
7663         pr_err("error %d\n", rc);
7664         goto rw_error;
7665     }
7666     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7667     if (rc != 0) {
7668         pr_err("error %d\n", rc);
7669         goto rw_error;
7670     }
7671     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
7672     if (rc != 0) {
7673         pr_err("error %d\n", rc);
7674         goto rw_error;
7675     }
7676 
7677     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7678     if (rc != 0) {
7679         pr_err("error %d\n", rc);
7680         goto rw_error;
7681     }
7682     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
7683     if (rc != 0) {
7684         pr_err("error %d\n", rc);
7685         goto rw_error;
7686     }
7687     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7688     if (rc != 0) {
7689         pr_err("error %d\n", rc);
7690         goto rw_error;
7691     }
7692 
7693     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
7694     if (rc != 0) {
7695         pr_err("error %d\n", rc);
7696         goto rw_error;
7697     }
7698     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
7699     if (rc != 0) {
7700         pr_err("error %d\n", rc);
7701         goto rw_error;
7702     }
7703     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
7704     if (rc != 0) {
7705         pr_err("error %d\n", rc);
7706         goto rw_error;
7707     }
7708     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
7709     if (rc != 0) {
7710         pr_err("error %d\n", rc);
7711         goto rw_error;
7712     }
7713     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
7714     if (rc != 0) {
7715         pr_err("error %d\n", rc);
7716         goto rw_error;
7717     }
7718     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
7719     if (rc != 0) {
7720         pr_err("error %d\n", rc);
7721         goto rw_error;
7722     }
7723     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
7724     if (rc != 0) {
7725         pr_err("error %d\n", rc);
7726         goto rw_error;
7727     }
7728 
7729     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7730     if (rc != 0) {
7731         pr_err("error %d\n", rc);
7732         goto rw_error;
7733     }
7734     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7735     if (rc != 0) {
7736         pr_err("error %d\n", rc);
7737         goto rw_error;
7738     }
7739     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7740     if (rc != 0) {
7741         pr_err("error %d\n", rc);
7742         goto rw_error;
7743     }
7744     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
7745     if (rc != 0) {
7746         pr_err("error %d\n", rc);
7747         goto rw_error;
7748     }
7749     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7750     if (rc != 0) {
7751         pr_err("error %d\n", rc);
7752         goto rw_error;
7753     }
7754     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7755     if (rc != 0) {
7756         pr_err("error %d\n", rc);
7757         goto rw_error;
7758     }
7759     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
7760     if (rc != 0) {
7761         pr_err("error %d\n", rc);
7762         goto rw_error;
7763     }
7764     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7765     if (rc != 0) {
7766         pr_err("error %d\n", rc);
7767         goto rw_error;
7768     }
7769     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7770     if (rc != 0) {
7771         pr_err("error %d\n", rc);
7772         goto rw_error;
7773     }
7774     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7775     if (rc != 0) {
7776         pr_err("error %d\n", rc);
7777         goto rw_error;
7778     }
7779     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7780     if (rc != 0) {
7781         pr_err("error %d\n", rc);
7782         goto rw_error;
7783     }
7784     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7785     if (rc != 0) {
7786         pr_err("error %d\n", rc);
7787         goto rw_error;
7788     }
7789     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7790     if (rc != 0) {
7791         pr_err("error %d\n", rc);
7792         goto rw_error;
7793     }
7794     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7795     if (rc != 0) {
7796         pr_err("error %d\n", rc);
7797         goto rw_error;
7798     }
7799     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7800     if (rc != 0) {
7801         pr_err("error %d\n", rc);
7802         goto rw_error;
7803     }
7804     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
7805     if (rc != 0) {
7806         pr_err("error %d\n", rc);
7807         goto rw_error;
7808     }
7809     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
7810     if (rc != 0) {
7811         pr_err("error %d\n", rc);
7812         goto rw_error;
7813     }
7814     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7815     if (rc != 0) {
7816         pr_err("error %d\n", rc);
7817         goto rw_error;
7818     }
7819     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7820     if (rc != 0) {
7821         pr_err("error %d\n", rc);
7822         goto rw_error;
7823     }
7824     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
7825     if (rc != 0) {
7826         pr_err("error %d\n", rc);
7827         goto rw_error;
7828     }
7829 
7830     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
7831     if (rc != 0) {
7832         pr_err("error %d\n", rc);
7833         goto rw_error;
7834     }
7835 
7836     return 0;
7837 rw_error:
7838     return rc;
7839 }
7840 
7841 /*============================================================================*/
7842 #define QAM_SET_OP_ALL 0x1
7843 #define QAM_SET_OP_CONSTELLATION 0x2
7844 #define QAM_SET_OP_SPECTRUM 0X4
7845 
7846 /*
7847 * \fn int set_qam ()
7848 * \brief Set QAM demod.
7849 * \param demod:   instance of demod.
7850 * \param channel: pointer to channel data.
7851 * \return int.
7852 */
7853 static int
7854 set_qam(struct drx_demod_instance *demod,
7855     struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
7856 {
7857     struct i2c_device_addr *dev_addr = NULL;
7858     struct drxj_data *ext_attr = NULL;
7859     struct drx_common_attr *common_attr = NULL;
7860     int rc;
7861     u32 adc_frequency = 0;
7862     u32 iqm_rc_rate = 0;
7863     u16 cmd_result = 0;
7864     u16 lc_symbol_freq = 0;
7865     u16 iqm_rc_stretch = 0;
7866     u16 set_env_parameters = 0;
7867     u16 set_param_parameters[2] = { 0 };
7868     struct drxjscu_cmd cmd_scu = { /* command      */ 0,
7869         /* parameter_len */ 0,
7870         /* result_len    */ 0,
7871         /* parameter    */ NULL,
7872         /* result       */ NULL
7873     };
7874     static const u8 qam_a_taps[] = {
7875         DRXJ_16TO8(-1), /* re0  */
7876         DRXJ_16TO8(1),  /* re1  */
7877         DRXJ_16TO8(1),  /* re2  */
7878         DRXJ_16TO8(-1), /* re3  */
7879         DRXJ_16TO8(-1), /* re4  */
7880         DRXJ_16TO8(2),  /* re5  */
7881         DRXJ_16TO8(1),  /* re6  */
7882         DRXJ_16TO8(-2), /* re7  */
7883         DRXJ_16TO8(0),  /* re8  */
7884         DRXJ_16TO8(3),  /* re9  */
7885         DRXJ_16TO8(-1), /* re10 */
7886         DRXJ_16TO8(-3), /* re11 */
7887         DRXJ_16TO8(4),  /* re12 */
7888         DRXJ_16TO8(1),  /* re13 */
7889         DRXJ_16TO8(-8), /* re14 */
7890         DRXJ_16TO8(4),  /* re15 */
7891         DRXJ_16TO8(13), /* re16 */
7892         DRXJ_16TO8(-13),    /* re17 */
7893         DRXJ_16TO8(-19),    /* re18 */
7894         DRXJ_16TO8(28), /* re19 */
7895         DRXJ_16TO8(25), /* re20 */
7896         DRXJ_16TO8(-53),    /* re21 */
7897         DRXJ_16TO8(-31),    /* re22 */
7898         DRXJ_16TO8(96), /* re23 */
7899         DRXJ_16TO8(37), /* re24 */
7900         DRXJ_16TO8(-190),   /* re25 */
7901         DRXJ_16TO8(-40),    /* re26 */
7902         DRXJ_16TO8(619) /* re27 */
7903     };
7904     static const u8 qam_b64_taps[] = {
7905         DRXJ_16TO8(0),  /* re0  */
7906         DRXJ_16TO8(-2), /* re1  */
7907         DRXJ_16TO8(1),  /* re2  */
7908         DRXJ_16TO8(2),  /* re3  */
7909         DRXJ_16TO8(-2), /* re4  */
7910         DRXJ_16TO8(0),  /* re5  */
7911         DRXJ_16TO8(4),  /* re6  */
7912         DRXJ_16TO8(-2), /* re7  */
7913         DRXJ_16TO8(-4), /* re8  */
7914         DRXJ_16TO8(4),  /* re9  */
7915         DRXJ_16TO8(3),  /* re10 */
7916         DRXJ_16TO8(-6), /* re11 */
7917         DRXJ_16TO8(0),  /* re12 */
7918         DRXJ_16TO8(6),  /* re13 */
7919         DRXJ_16TO8(-5), /* re14 */
7920         DRXJ_16TO8(-3), /* re15 */
7921         DRXJ_16TO8(11), /* re16 */
7922         DRXJ_16TO8(-4), /* re17 */
7923         DRXJ_16TO8(-19),    /* re18 */
7924         DRXJ_16TO8(19), /* re19 */
7925         DRXJ_16TO8(28), /* re20 */
7926         DRXJ_16TO8(-45),    /* re21 */
7927         DRXJ_16TO8(-36),    /* re22 */
7928         DRXJ_16TO8(90), /* re23 */
7929         DRXJ_16TO8(42), /* re24 */
7930         DRXJ_16TO8(-185),   /* re25 */
7931         DRXJ_16TO8(-46),    /* re26 */
7932         DRXJ_16TO8(614) /* re27 */
7933     };
7934     static const u8 qam_b256_taps[] = {
7935         DRXJ_16TO8(-2), /* re0  */
7936         DRXJ_16TO8(4),  /* re1  */
7937         DRXJ_16TO8(1),  /* re2  */
7938         DRXJ_16TO8(-4), /* re3  */
7939         DRXJ_16TO8(0),  /* re4  */
7940         DRXJ_16TO8(4),  /* re5  */
7941         DRXJ_16TO8(-2), /* re6  */
7942         DRXJ_16TO8(-4), /* re7  */
7943         DRXJ_16TO8(5),  /* re8  */
7944         DRXJ_16TO8(2),  /* re9  */
7945         DRXJ_16TO8(-8), /* re10 */
7946         DRXJ_16TO8(2),  /* re11 */
7947         DRXJ_16TO8(11), /* re12 */
7948         DRXJ_16TO8(-8), /* re13 */
7949         DRXJ_16TO8(-15),    /* re14 */
7950         DRXJ_16TO8(16), /* re15 */
7951         DRXJ_16TO8(19), /* re16 */
7952         DRXJ_16TO8(-27),    /* re17 */
7953         DRXJ_16TO8(-22),    /* re18 */
7954         DRXJ_16TO8(44), /* re19 */
7955         DRXJ_16TO8(26), /* re20 */
7956         DRXJ_16TO8(-69),    /* re21 */
7957         DRXJ_16TO8(-28),    /* re22 */
7958         DRXJ_16TO8(110),    /* re23 */
7959         DRXJ_16TO8(31), /* re24 */
7960         DRXJ_16TO8(-201),   /* re25 */
7961         DRXJ_16TO8(-32),    /* re26 */
7962         DRXJ_16TO8(628) /* re27 */
7963     };
7964     static const u8 qam_c_taps[] = {
7965         DRXJ_16TO8(-3), /* re0  */
7966         DRXJ_16TO8(3),  /* re1  */
7967         DRXJ_16TO8(2),  /* re2  */
7968         DRXJ_16TO8(-4), /* re3  */
7969         DRXJ_16TO8(0),  /* re4  */
7970         DRXJ_16TO8(4),  /* re5  */
7971         DRXJ_16TO8(-1), /* re6  */
7972         DRXJ_16TO8(-4), /* re7  */
7973         DRXJ_16TO8(3),  /* re8  */
7974         DRXJ_16TO8(3),  /* re9  */
7975         DRXJ_16TO8(-5), /* re10 */
7976         DRXJ_16TO8(0),  /* re11 */
7977         DRXJ_16TO8(9),  /* re12 */
7978         DRXJ_16TO8(-4), /* re13 */
7979         DRXJ_16TO8(-12),    /* re14 */
7980         DRXJ_16TO8(10), /* re15 */
7981         DRXJ_16TO8(16), /* re16 */
7982         DRXJ_16TO8(-21),    /* re17 */
7983         DRXJ_16TO8(-20),    /* re18 */
7984         DRXJ_16TO8(37), /* re19 */
7985         DRXJ_16TO8(25), /* re20 */
7986         DRXJ_16TO8(-62),    /* re21 */
7987         DRXJ_16TO8(-28),    /* re22 */
7988         DRXJ_16TO8(105),    /* re23 */
7989         DRXJ_16TO8(31), /* re24 */
7990         DRXJ_16TO8(-197),   /* re25 */
7991         DRXJ_16TO8(-33),    /* re26 */
7992         DRXJ_16TO8(626) /* re27 */
7993     };
7994 
7995     dev_addr = demod->my_i2c_dev_addr;
7996     ext_attr = (struct drxj_data *) demod->my_ext_attr;
7997     common_attr = (struct drx_common_attr *) demod->my_common_attr;
7998 
7999     if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8000         if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8001             switch (channel->constellation) {
8002             case DRX_CONSTELLATION_QAM256:
8003                 iqm_rc_rate = 0x00AE3562;
8004                 lc_symbol_freq =
8005                     QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
8006                 channel->symbolrate = 5360537;
8007                 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
8008                 break;
8009             case DRX_CONSTELLATION_QAM64:
8010                 iqm_rc_rate = 0x00C05A0E;
8011                 lc_symbol_freq = 409;
8012                 channel->symbolrate = 5056941;
8013                 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
8014                 break;
8015             default:
8016                 return -EINVAL;
8017             }
8018         } else {
8019             adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
8020             if (channel->symbolrate == 0) {
8021                 pr_err("error: channel symbolrate is zero!\n");
8022                 return -EIO;
8023             }
8024             iqm_rc_rate =
8025                 (adc_frequency / channel->symbolrate) * (1 << 21) +
8026                 (frac28
8027                  ((adc_frequency % channel->symbolrate),
8028                   channel->symbolrate) >> 7) - (1 << 23);
8029             lc_symbol_freq =
8030                 (u16) (frac28
8031                      (channel->symbolrate +
8032                       (adc_frequency >> 13),
8033                       adc_frequency) >> 16);
8034             if (lc_symbol_freq > 511)
8035                 lc_symbol_freq = 511;
8036 
8037             iqm_rc_stretch = 21;
8038         }
8039 
8040         if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8041             set_env_parameters = QAM_TOP_ANNEX_A;   /* annex             */
8042             set_param_parameters[0] = channel->constellation;   /* constellation     */
8043             set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
8044         } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8045             set_env_parameters = QAM_TOP_ANNEX_B;   /* annex             */
8046             set_param_parameters[0] = channel->constellation;   /* constellation     */
8047             set_param_parameters[1] = channel->interleavemode;  /* interleave mode   */
8048         } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8049             set_env_parameters = QAM_TOP_ANNEX_C;   /* annex             */
8050             set_param_parameters[0] = channel->constellation;   /* constellation     */
8051             set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
8052         } else {
8053             return -EINVAL;
8054         }
8055     }
8056 
8057     if (op & QAM_SET_OP_ALL) {
8058         /*
8059            STEP 1: reset demodulator
8060            resets IQM, QAM and FEC HW blocks
8061            resets SCU variables
8062          */
8063         /* stop all comm_exec */
8064         rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
8065         if (rc != 0) {
8066             pr_err("error %d\n", rc);
8067             goto rw_error;
8068         }
8069         rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
8070         if (rc != 0) {
8071             pr_err("error %d\n", rc);
8072             goto rw_error;
8073         }
8074         rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
8075         if (rc != 0) {
8076             pr_err("error %d\n", rc);
8077             goto rw_error;
8078         }
8079         rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
8080         if (rc != 0) {
8081             pr_err("error %d\n", rc);
8082             goto rw_error;
8083         }
8084         rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
8085         if (rc != 0) {
8086             pr_err("error %d\n", rc);
8087             goto rw_error;
8088         }
8089         rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
8090         if (rc != 0) {
8091             pr_err("error %d\n", rc);
8092             goto rw_error;
8093         }
8094         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
8095         if (rc != 0) {
8096             pr_err("error %d\n", rc);
8097             goto rw_error;
8098         }
8099 
8100         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8101             SCU_RAM_COMMAND_CMD_DEMOD_RESET;
8102         cmd_scu.parameter_len = 0;
8103         cmd_scu.result_len = 1;
8104         cmd_scu.parameter = NULL;
8105         cmd_scu.result = &cmd_result;
8106         rc = scu_command(dev_addr, &cmd_scu);
8107         if (rc != 0) {
8108             pr_err("error %d\n", rc);
8109             goto rw_error;
8110         }
8111     }
8112 
8113     if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8114         /*
8115            STEP 2: configure demodulator
8116            -set env
8117            -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
8118          */
8119         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8120             SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
8121         cmd_scu.parameter_len = 1;
8122         cmd_scu.result_len = 1;
8123         cmd_scu.parameter = &set_env_parameters;
8124         cmd_scu.result = &cmd_result;
8125         rc = scu_command(dev_addr, &cmd_scu);
8126         if (rc != 0) {
8127             pr_err("error %d\n", rc);
8128             goto rw_error;
8129         }
8130 
8131         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8132             SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
8133         cmd_scu.parameter_len = 2;
8134         cmd_scu.result_len = 1;
8135         cmd_scu.parameter = set_param_parameters;
8136         cmd_scu.result = &cmd_result;
8137         rc = scu_command(dev_addr, &cmd_scu);
8138         if (rc != 0) {
8139             pr_err("error %d\n", rc);
8140             goto rw_error;
8141         }
8142         /* set symbol rate */
8143         rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
8144         if (rc != 0) {
8145             pr_err("error %d\n", rc);
8146             goto rw_error;
8147         }
8148         ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
8149         rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
8150         if (rc != 0) {
8151             pr_err("error %d\n", rc);
8152             goto rw_error;
8153         }
8154     }
8155     /* STEP 3: enable the system in a mode where the ADC provides valid signal
8156        setup constellation independent registers */
8157     /* from qam_cmd.py script (qam_driver_b) */
8158     /* TODO: remove re-writes of HW reset values */
8159     if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
8160         rc = set_frequency(demod, channel, tuner_freq_offset);
8161         if (rc != 0) {
8162             pr_err("error %d\n", rc);
8163             goto rw_error;
8164         }
8165     }
8166 
8167     if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8168 
8169         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
8170         if (rc != 0) {
8171             pr_err("error %d\n", rc);
8172             goto rw_error;
8173         }
8174         rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
8175         if (rc != 0) {
8176             pr_err("error %d\n", rc);
8177             goto rw_error;
8178         }
8179     }
8180 
8181     if (op & QAM_SET_OP_ALL) {
8182         if (!ext_attr->has_lna) {
8183             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
8184             if (rc != 0) {
8185                 pr_err("error %d\n", rc);
8186                 goto rw_error;
8187             }
8188         }
8189         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
8190         if (rc != 0) {
8191             pr_err("error %d\n", rc);
8192             goto rw_error;
8193         }
8194         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
8195         if (rc != 0) {
8196             pr_err("error %d\n", rc);
8197             goto rw_error;
8198         }
8199         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
8200         if (rc != 0) {
8201             pr_err("error %d\n", rc);
8202             goto rw_error;
8203         }
8204 
8205         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
8206         if (rc != 0) {
8207             pr_err("error %d\n", rc);
8208             goto rw_error;
8209         }   /* scu temporary shut down agc */
8210 
8211         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
8212         if (rc != 0) {
8213             pr_err("error %d\n", rc);
8214             goto rw_error;
8215         }
8216         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
8217         if (rc != 0) {
8218             pr_err("error %d\n", rc);
8219             goto rw_error;
8220         }
8221         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
8222         if (rc != 0) {
8223             pr_err("error %d\n", rc);
8224             goto rw_error;
8225         }
8226         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
8227         if (rc != 0) {
8228             pr_err("error %d\n", rc);
8229             goto rw_error;
8230         }
8231         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);
8232         if (rc != 0) {
8233             pr_err("error %d\n", rc);
8234             goto rw_error;
8235         }
8236         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
8237         if (rc != 0) {
8238             pr_err("error %d\n", rc);
8239             goto rw_error;
8240         }
8241         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
8242         if (rc != 0) {
8243             pr_err("error %d\n", rc);
8244             goto rw_error;
8245         }
8246 
8247         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
8248         if (rc != 0) {
8249             pr_err("error %d\n", rc);
8250             goto rw_error;
8251         }
8252         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
8253         if (rc != 0) {
8254             pr_err("error %d\n", rc);
8255             goto rw_error;
8256         }   /*! reset default val ! */
8257 
8258         rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
8259         if (rc != 0) {
8260             pr_err("error %d\n", rc);
8261             goto rw_error;
8262         }   /*! reset default val ! */
8263         if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8264             rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
8265             if (rc != 0) {
8266                 pr_err("error %d\n", rc);
8267                 goto rw_error;
8268             }   /*! reset default val ! */
8269             rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
8270             if (rc != 0) {
8271                 pr_err("error %d\n", rc);
8272                 goto rw_error;
8273             }   /*! reset default val ! */
8274             rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
8275             if (rc != 0) {
8276                 pr_err("error %d\n", rc);
8277                 goto rw_error;
8278             }   /*! reset default val ! */
8279         } else {
8280             switch (channel->constellation) {
8281             case DRX_CONSTELLATION_QAM16:
8282             case DRX_CONSTELLATION_QAM64:
8283             case DRX_CONSTELLATION_QAM256:
8284                 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
8285                 if (rc != 0) {
8286                     pr_err("error %d\n", rc);
8287                     goto rw_error;
8288                 }
8289                 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
8290                 if (rc != 0) {
8291                     pr_err("error %d\n", rc);
8292                     goto rw_error;
8293                 }
8294                 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
8295                 if (rc != 0) {
8296                     pr_err("error %d\n", rc);
8297                     goto rw_error;
8298                 }   /*! reset default val ! */
8299                 break;
8300             case DRX_CONSTELLATION_QAM32:
8301             case DRX_CONSTELLATION_QAM128:
8302                 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
8303                 if (rc != 0) {
8304                     pr_err("error %d\n", rc);
8305                     goto rw_error;
8306                 }
8307                 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
8308                 if (rc != 0) {
8309                     pr_err("error %d\n", rc);
8310                     goto rw_error;
8311                 }
8312                 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
8313                 if (rc != 0) {
8314                     pr_err("error %d\n", rc);
8315                     goto rw_error;
8316                 }
8317                 break;
8318             default:
8319                 return -EIO;
8320             }   /* switch */
8321         }
8322 
8323         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
8324         if (rc != 0) {
8325             pr_err("error %d\n", rc);
8326             goto rw_error;
8327         }   /*! reset default val ! */
8328         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
8329         if (rc != 0) {
8330             pr_err("error %d\n", rc);
8331             goto rw_error;
8332         }
8333         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
8334         if (rc != 0) {
8335             pr_err("error %d\n", rc);
8336             goto rw_error;
8337         }
8338         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
8339         if (rc != 0) {
8340             pr_err("error %d\n", rc);
8341             goto rw_error;
8342         }
8343         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);
8344         if (rc != 0) {
8345             pr_err("error %d\n", rc);
8346             goto rw_error;
8347         }
8348         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
8349         if (rc != 0) {
8350             pr_err("error %d\n", rc);
8351             goto rw_error;
8352         }
8353         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
8354         if (rc != 0) {
8355             pr_err("error %d\n", rc);
8356             goto rw_error;
8357         }
8358         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
8359         if (rc != 0) {
8360             pr_err("error %d\n", rc);
8361             goto rw_error;
8362         }
8363         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
8364         if (rc != 0) {
8365             pr_err("error %d\n", rc);
8366             goto rw_error;
8367         }
8368         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
8369         if (rc != 0) {
8370             pr_err("error %d\n", rc);
8371             goto rw_error;
8372         }
8373         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
8374         if (rc != 0) {
8375             pr_err("error %d\n", rc);
8376             goto rw_error;
8377         }
8378         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
8379         if (rc != 0) {
8380             pr_err("error %d\n", rc);
8381             goto rw_error;
8382         }
8383         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
8384         if (rc != 0) {
8385             pr_err("error %d\n", rc);
8386             goto rw_error;
8387         }
8388         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
8389         if (rc != 0) {
8390             pr_err("error %d\n", rc);
8391             goto rw_error;
8392         }
8393         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
8394         if (rc != 0) {
8395             pr_err("error %d\n", rc);
8396             goto rw_error;
8397         }
8398         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
8399         if (rc != 0) {
8400             pr_err("error %d\n", rc);
8401             goto rw_error;
8402         }
8403         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
8404         if (rc != 0) {
8405             pr_err("error %d\n", rc);
8406             goto rw_error;
8407         }
8408         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
8409         if (rc != 0) {
8410             pr_err("error %d\n", rc);
8411             goto rw_error;
8412         }
8413         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
8414         if (rc != 0) {
8415             pr_err("error %d\n", rc);
8416             goto rw_error;
8417         }
8418         rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
8419         if (rc != 0) {
8420             pr_err("error %d\n", rc);
8421             goto rw_error;
8422         }
8423 
8424         rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
8425         if (rc != 0) {
8426             pr_err("error %d\n", rc);
8427             goto rw_error;
8428         }
8429         rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
8430         if (rc != 0) {
8431             pr_err("error %d\n", rc);
8432             goto rw_error;
8433         }
8434         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
8435         if (rc != 0) {
8436             pr_err("error %d\n", rc);
8437             goto rw_error;
8438         }
8439         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
8440         if (rc != 0) {
8441             pr_err("error %d\n", rc);
8442             goto rw_error;
8443         }
8444         rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
8445         if (rc != 0) {
8446             pr_err("error %d\n", rc);
8447             goto rw_error;
8448         }
8449 
8450         /* No more resets of the IQM, current standard correctly set =>
8451            now AGCs can be configured. */
8452         /* turn on IQMAF. It has to be in front of setAgc**() */
8453         rc = set_iqm_af(demod, true);
8454         if (rc != 0) {
8455             pr_err("error %d\n", rc);
8456             goto rw_error;
8457         }
8458         rc = adc_synchronization(demod);
8459         if (rc != 0) {
8460             pr_err("error %d\n", rc);
8461             goto rw_error;
8462         }
8463 
8464         rc = init_agc(demod);
8465         if (rc != 0) {
8466             pr_err("error %d\n", rc);
8467             goto rw_error;
8468         }
8469         rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
8470         if (rc != 0) {
8471             pr_err("error %d\n", rc);
8472             goto rw_error;
8473         }
8474         rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
8475         if (rc != 0) {
8476             pr_err("error %d\n", rc);
8477             goto rw_error;
8478         }
8479         {
8480             /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
8481                of only the gain */
8482             struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
8483 
8484             qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
8485             rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
8486             if (rc != 0) {
8487                 pr_err("error %d\n", rc);
8488                 goto rw_error;
8489             }
8490         }
8491         rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
8492         if (rc != 0) {
8493             pr_err("error %d\n", rc);
8494             goto rw_error;
8495         }
8496     }
8497 
8498     if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8499         if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8500             rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
8501             if (rc != 0) {
8502                 pr_err("error %d\n", rc);
8503                 goto rw_error;
8504             }
8505             rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
8506             if (rc != 0) {
8507                 pr_err("error %d\n", rc);
8508                 goto rw_error;
8509             }
8510         } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8511             switch (channel->constellation) {
8512             case DRX_CONSTELLATION_QAM64:
8513                 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
8514                 if (rc != 0) {
8515                     pr_err("error %d\n", rc);
8516                     goto rw_error;
8517                 }
8518                 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
8519                 if (rc != 0) {
8520                     pr_err("error %d\n", rc);
8521                     goto rw_error;
8522                 }
8523                 break;
8524             case DRX_CONSTELLATION_QAM256:
8525                 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
8526                 if (rc != 0) {
8527                     pr_err("error %d\n", rc);
8528                     goto rw_error;
8529                 }
8530                 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
8531                 if (rc != 0) {
8532                     pr_err("error %d\n", rc);
8533                     goto rw_error;
8534                 }
8535                 break;
8536             default:
8537                 return -EIO;
8538             }
8539         } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8540             rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
8541             if (rc != 0) {
8542                 pr_err("error %d\n", rc);
8543                 goto rw_error;
8544             }
8545             rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
8546             if (rc != 0) {
8547                 pr_err("error %d\n", rc);
8548                 goto rw_error;
8549             }
8550         }
8551 
8552         /* SETP 4: constellation specific setup */
8553         switch (channel->constellation) {
8554         case DRX_CONSTELLATION_QAM16:
8555             rc = set_qam16(demod);
8556             if (rc != 0) {
8557                 pr_err("error %d\n", rc);
8558                 goto rw_error;
8559             }
8560             break;
8561         case DRX_CONSTELLATION_QAM32:
8562             rc = set_qam32(demod);
8563             if (rc != 0) {
8564                 pr_err("error %d\n", rc);
8565                 goto rw_error;
8566             }
8567             break;
8568         case DRX_CONSTELLATION_QAM64:
8569             rc = set_qam64(demod);
8570             if (rc != 0) {
8571                 pr_err("error %d\n", rc);
8572                 goto rw_error;
8573             }
8574             break;
8575         case DRX_CONSTELLATION_QAM128:
8576             rc = set_qam128(demod);
8577             if (rc != 0) {
8578                 pr_err("error %d\n", rc);
8579                 goto rw_error;
8580             }
8581             break;
8582         case DRX_CONSTELLATION_QAM256:
8583             rc = set_qam256(demod);
8584             if (rc != 0) {
8585                 pr_err("error %d\n", rc);
8586                 goto rw_error;
8587             }
8588             break;
8589         default:
8590             return -EIO;
8591         }       /* switch */
8592     }
8593 
8594     if ((op & QAM_SET_OP_ALL)) {
8595         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
8596         if (rc != 0) {
8597             pr_err("error %d\n", rc);
8598             goto rw_error;
8599         }
8600 
8601         /* Mpeg output has to be in front of FEC active */
8602         rc = set_mpegtei_handling(demod);
8603         if (rc != 0) {
8604             pr_err("error %d\n", rc);
8605             goto rw_error;
8606         }
8607         rc = bit_reverse_mpeg_output(demod);
8608         if (rc != 0) {
8609             pr_err("error %d\n", rc);
8610             goto rw_error;
8611         }
8612         rc = set_mpeg_start_width(demod);
8613         if (rc != 0) {
8614             pr_err("error %d\n", rc);
8615             goto rw_error;
8616         }
8617         {
8618             /* TODO: move to set_standard after hardware reset value problem is solved */
8619             /* Configure initial MPEG output */
8620             struct drx_cfg_mpeg_output cfg_mpeg_output;
8621 
8622             memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
8623             cfg_mpeg_output.enable_mpeg_output = true;
8624 
8625             rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
8626             if (rc != 0) {
8627                 pr_err("error %d\n", rc);
8628                 goto rw_error;
8629             }
8630         }
8631     }
8632 
8633     if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8634 
8635         /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
8636         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8637             SCU_RAM_COMMAND_CMD_DEMOD_START;
8638         cmd_scu.parameter_len = 0;
8639         cmd_scu.result_len = 1;
8640         cmd_scu.parameter = NULL;
8641         cmd_scu.result = &cmd_result;
8642         rc = scu_command(dev_addr, &cmd_scu);
8643         if (rc != 0) {
8644             pr_err("error %d\n", rc);
8645             goto rw_error;
8646         }
8647     }
8648 
8649     rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
8650     if (rc != 0) {
8651         pr_err("error %d\n", rc);
8652         goto rw_error;
8653     }
8654     rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
8655     if (rc != 0) {
8656         pr_err("error %d\n", rc);
8657         goto rw_error;
8658     }
8659     rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
8660     if (rc != 0) {
8661         pr_err("error %d\n", rc);
8662         goto rw_error;
8663     }
8664 
8665     return 0;
8666 rw_error:
8667     return rc;
8668 }
8669 
8670 /*============================================================================*/
8671 static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
8672 
8673 static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
8674 {
8675     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8676     struct drxj_data *ext_attr = demod->my_ext_attr;
8677     int rc;
8678     u32 iqm_fs_rate_ofs = 0;
8679     u32 iqm_fs_rate_lo = 0;
8680     u16 qam_ctl_ena = 0;
8681     u16 data = 0;
8682     u16 equ_mode = 0;
8683     u16 fsm_state = 0;
8684     int i = 0;
8685     int ofsofs = 0;
8686 
8687     /* Silence the controlling of lc, equ, and the acquisition state machine */
8688     rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
8689     if (rc != 0) {
8690         pr_err("error %d\n", rc);
8691         goto rw_error;
8692     }
8693     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), 0);
8694     if (rc != 0) {
8695         pr_err("error %d\n", rc);
8696         goto rw_error;
8697     }
8698 
8699     /* freeze the frequency control loop */
8700     rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);
8701     if (rc != 0) {
8702         pr_err("error %d\n", rc);
8703         goto rw_error;
8704     }
8705     rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);
8706     if (rc != 0) {
8707         pr_err("error %d\n", rc);
8708         goto rw_error;
8709     }
8710 
8711     rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
8712     if (rc != 0) {
8713         pr_err("error %d\n", rc);
8714         goto rw_error;
8715     }
8716     rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
8717     if (rc != 0) {
8718         pr_err("error %d\n", rc);
8719         goto rw_error;
8720     }
8721     ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
8722     iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
8723     iqm_fs_rate_ofs -= 2 * ofsofs;
8724 
8725     /* freeze dq/fq updating */
8726     rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
8727     if (rc != 0) {
8728         pr_err("error %d\n", rc);
8729         goto rw_error;
8730     }
8731     data = (data & 0xfff9);
8732     rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8733     if (rc != 0) {
8734         pr_err("error %d\n", rc);
8735         goto rw_error;
8736     }
8737     rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8738     if (rc != 0) {
8739         pr_err("error %d\n", rc);
8740         goto rw_error;
8741     }
8742 
8743     /* lc_cp / _ci / _ca */
8744     rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);
8745     if (rc != 0) {
8746         pr_err("error %d\n", rc);
8747         goto rw_error;
8748     }
8749     rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);
8750     if (rc != 0) {
8751         pr_err("error %d\n", rc);
8752         goto rw_error;
8753     }
8754     rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
8755     if (rc != 0) {
8756         pr_err("error %d\n", rc);
8757         goto rw_error;
8758     }
8759 
8760     /* flip the spec */
8761     rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
8762     if (rc != 0) {
8763         pr_err("error %d\n", rc);
8764         goto rw_error;
8765     }
8766     ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
8767     ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
8768 
8769     /* freeze dq/fq updating */
8770     rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
8771     if (rc != 0) {
8772         pr_err("error %d\n", rc);
8773         goto rw_error;
8774     }
8775     equ_mode = data;
8776     data = (data & 0xfff9);
8777     rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8778     if (rc != 0) {
8779         pr_err("error %d\n", rc);
8780         goto rw_error;
8781     }
8782     rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8783     if (rc != 0) {
8784         pr_err("error %d\n", rc);
8785         goto rw_error;
8786     }
8787 
8788     for (i = 0; i < 28; i++) {
8789         rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
8790         if (rc != 0) {
8791             pr_err("error %d\n", rc);
8792             goto rw_error;
8793         }
8794         rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
8795         if (rc != 0) {
8796             pr_err("error %d\n", rc);
8797             goto rw_error;
8798         }
8799     }
8800 
8801     for (i = 0; i < 24; i++) {
8802         rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
8803         if (rc != 0) {
8804             pr_err("error %d\n", rc);
8805             goto rw_error;
8806         }
8807         rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
8808         if (rc != 0) {
8809             pr_err("error %d\n", rc);
8810             goto rw_error;
8811         }
8812     }
8813 
8814     data = equ_mode;
8815     rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8816     if (rc != 0) {
8817         pr_err("error %d\n", rc);
8818         goto rw_error;
8819     }
8820     rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8821     if (rc != 0) {
8822         pr_err("error %d\n", rc);
8823         goto rw_error;
8824     }
8825 
8826     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
8827     if (rc != 0) {
8828         pr_err("error %d\n", rc);
8829         goto rw_error;
8830     }
8831 
8832     i = 0;
8833     while ((fsm_state != 4) && (i++ < 100)) {
8834         rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
8835         if (rc != 0) {
8836             pr_err("error %d\n", rc);
8837             goto rw_error;
8838         }
8839     }
8840     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
8841     if (rc != 0) {
8842         pr_err("error %d\n", rc);
8843         goto rw_error;
8844     }
8845 
8846     return 0;
8847 rw_error:
8848     return rc;
8849 
8850 }
8851 
8852 #define  NO_LOCK        0x0
8853 #define  DEMOD_LOCKED   0x1
8854 #define  SYNC_FLIPPED   0x2
8855 #define  SPEC_MIRRORED  0x4
8856 /*
8857 * \fn int qam64auto ()
8858 * \brief auto do sync pattern switching and mirroring.
8859 * \param demod:   instance of demod.
8860 * \param channel: pointer to channel data.
8861 * \param tuner_freq_offset: tuner frequency offset.
8862 * \param lock_status: pointer to lock status.
8863 * \return int.
8864 */
8865 static int
8866 qam64auto(struct drx_demod_instance *demod,
8867       struct drx_channel *channel,
8868       s32 tuner_freq_offset, enum drx_lock_status *lock_status)
8869 {
8870     struct drxj_data *ext_attr = demod->my_ext_attr;
8871     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8872     struct drx39xxj_state *state = dev_addr->user_data;
8873     struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
8874     int rc;
8875     u32 lck_state = NO_LOCK;
8876     u32 start_time = 0;
8877     u32 d_locked_time = 0;
8878     u32 timeout_ofs = 0;
8879     u16 data = 0;
8880 
8881     /* external attributes for storing acquired channel constellation */
8882     *lock_status = DRX_NOT_LOCKED;
8883     start_time = jiffies_to_msecs(jiffies);
8884     lck_state = NO_LOCK;
8885     do {
8886         rc = ctrl_lock_status(demod, lock_status);
8887         if (rc != 0) {
8888             pr_err("error %d\n", rc);
8889             goto rw_error;
8890         }
8891 
8892         switch (lck_state) {
8893         case NO_LOCK:
8894             if (*lock_status == DRXJ_DEMOD_LOCK) {
8895                 rc = ctrl_get_qam_sig_quality(demod);
8896                 if (rc != 0) {
8897                     pr_err("error %d\n", rc);
8898                     goto rw_error;
8899                 }
8900                 if (p->cnr.stat[0].svalue > 20800) {
8901                     lck_state = DEMOD_LOCKED;
8902                     /* some delay to see if fec_lock possible TODO find the right value */
8903                     timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;    /* see something, waiting longer */
8904                     d_locked_time = jiffies_to_msecs(jiffies);
8905                 }
8906             }
8907             break;
8908         case DEMOD_LOCKED:
8909             if ((*lock_status == DRXJ_DEMOD_LOCK) &&    /* still demod_lock in 150ms */
8910                 ((jiffies_to_msecs(jiffies) - d_locked_time) >
8911                  DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8912                 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8913                 if (rc != 0) {
8914                     pr_err("error %d\n", rc);
8915                     goto rw_error;
8916                 }
8917                 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
8918                 if (rc != 0) {
8919                     pr_err("error %d\n", rc);
8920                     goto rw_error;
8921                 }
8922                 lck_state = SYNC_FLIPPED;
8923                 msleep(10);
8924             }
8925             break;
8926         case SYNC_FLIPPED:
8927             if (*lock_status == DRXJ_DEMOD_LOCK) {
8928                 if (channel->mirror == DRX_MIRROR_AUTO) {
8929                     /* flip sync pattern back */
8930                     rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8931                     if (rc != 0) {
8932                         pr_err("error %d\n", rc);
8933                         goto rw_error;
8934                     }
8935                     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
8936                     if (rc != 0) {
8937                         pr_err("error %d\n", rc);
8938                         goto rw_error;
8939                     }
8940                     /* flip spectrum */
8941                     ext_attr->mirror = DRX_MIRROR_YES;
8942                     rc = qam_flip_spec(demod, channel);
8943                     if (rc != 0) {
8944                         pr_err("error %d\n", rc);
8945                         goto rw_error;
8946                     }
8947                     lck_state = SPEC_MIRRORED;
8948                     /* reset timer TODO: still need 500ms? */
8949                     start_time = d_locked_time =
8950                         jiffies_to_msecs(jiffies);
8951                     timeout_ofs = 0;
8952                 } else {    /* no need to wait lock */
8953 
8954                     start_time =
8955                         jiffies_to_msecs(jiffies) -
8956                         DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8957                 }
8958             }
8959             break;
8960         case SPEC_MIRRORED:
8961             if ((*lock_status == DRXJ_DEMOD_LOCK) &&    /* still demod_lock in 150ms */
8962                 ((jiffies_to_msecs(jiffies) - d_locked_time) >
8963                  DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8964                 rc = ctrl_get_qam_sig_quality(demod);
8965                 if (rc != 0) {
8966                     pr_err("error %d\n", rc);
8967                     goto rw_error;
8968                 }
8969                 if (p->cnr.stat[0].svalue > 20800) {
8970                     rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8971                     if (rc != 0) {
8972                         pr_err("error %d\n", rc);
8973                         goto rw_error;
8974                     }
8975                     rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
8976                     if (rc != 0) {
8977                         pr_err("error %d\n", rc);
8978                         goto rw_error;
8979                     }
8980                     /* no need to wait lock */
8981                     start_time =
8982                         jiffies_to_msecs(jiffies) -
8983                         DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8984                 }
8985             }
8986             break;
8987         default:
8988             break;
8989         }
8990         msleep(10);
8991     } while
8992         ((*lock_status != DRX_LOCKED) &&
8993          (*lock_status != DRX_NEVER_LOCK) &&
8994          ((jiffies_to_msecs(jiffies) - start_time) <
8995           (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
8996         );
8997     /* Returning control to application ... */
8998 
8999     return 0;
9000 rw_error:
9001     return rc;
9002 }
9003 
9004 /*
9005 * \fn int qam256auto ()
9006 * \brief auto do sync pattern switching and mirroring.
9007 * \param demod:   instance of demod.
9008 * \param channel: pointer to channel data.
9009 * \param tuner_freq_offset: tuner frequency offset.
9010 * \param lock_status: pointer to lock status.
9011 * \return int.
9012 */
9013 static int
9014 qam256auto(struct drx_demod_instance *demod,
9015        struct drx_channel *channel,
9016        s32 tuner_freq_offset, enum drx_lock_status *lock_status)
9017 {
9018     struct drxj_data *ext_attr = demod->my_ext_attr;
9019     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9020     struct drx39xxj_state *state = dev_addr->user_data;
9021     struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9022     int rc;
9023     u32 lck_state = NO_LOCK;
9024     u32 start_time = 0;
9025     u32 d_locked_time = 0;
9026     u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
9027 
9028     /* external attributes for storing acquired channel constellation */
9029     *lock_status = DRX_NOT_LOCKED;
9030     start_time = jiffies_to_msecs(jiffies);
9031     lck_state = NO_LOCK;
9032     do {
9033         rc = ctrl_lock_status(demod, lock_status);
9034         if (rc != 0) {
9035             pr_err("error %d\n", rc);
9036             goto rw_error;
9037         }
9038         switch (lck_state) {
9039         case NO_LOCK:
9040             if (*lock_status == DRXJ_DEMOD_LOCK) {
9041                 rc = ctrl_get_qam_sig_quality(demod);
9042                 if (rc != 0) {
9043                     pr_err("error %d\n", rc);
9044                     goto rw_error;
9045                 }
9046                 if (p->cnr.stat[0].svalue > 26800) {
9047                     lck_state = DEMOD_LOCKED;
9048                     timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;    /* see something, wait longer */
9049                     d_locked_time = jiffies_to_msecs(jiffies);
9050                 }
9051             }
9052             break;
9053         case DEMOD_LOCKED:
9054             if (*lock_status == DRXJ_DEMOD_LOCK) {
9055                 if ((channel->mirror == DRX_MIRROR_AUTO) &&
9056                     ((jiffies_to_msecs(jiffies) - d_locked_time) >
9057                      DRXJ_QAM_FEC_LOCK_WAITTIME)) {
9058                     ext_attr->mirror = DRX_MIRROR_YES;
9059                     rc = qam_flip_spec(demod, channel);
9060                     if (rc != 0) {
9061                         pr_err("error %d\n", rc);
9062                         goto rw_error;
9063                     }
9064                     lck_state = SPEC_MIRRORED;
9065                     /* reset timer TODO: still need 300ms? */
9066                     start_time = jiffies_to_msecs(jiffies);
9067                     timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
9068                 }
9069             }
9070             break;
9071         case SPEC_MIRRORED:
9072             break;
9073         default:
9074             break;
9075         }
9076         msleep(10);
9077     } while
9078         ((*lock_status < DRX_LOCKED) &&
9079          (*lock_status != DRX_NEVER_LOCK) &&
9080          ((jiffies_to_msecs(jiffies) - start_time) <
9081           (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
9082 
9083     return 0;
9084 rw_error:
9085     return rc;
9086 }
9087 
9088 /*
9089 * \fn int set_qam_channel ()
9090 * \brief Set QAM channel according to the requested constellation.
9091 * \param demod:   instance of demod.
9092 * \param channel: pointer to channel data.
9093 * \return int.
9094 */
9095 static int
9096 set_qam_channel(struct drx_demod_instance *demod,
9097            struct drx_channel *channel, s32 tuner_freq_offset)
9098 {
9099     struct drxj_data *ext_attr = NULL;
9100     int rc;
9101     enum drx_lock_status lock_status = DRX_NOT_LOCKED;
9102     bool auto_flag = false;
9103 
9104     /* external attributes for storing acquired channel constellation */
9105     ext_attr = (struct drxj_data *) demod->my_ext_attr;
9106 
9107     /* set QAM channel constellation */
9108     switch (channel->constellation) {
9109     case DRX_CONSTELLATION_QAM16:
9110     case DRX_CONSTELLATION_QAM32:
9111     case DRX_CONSTELLATION_QAM128:
9112         return -EINVAL;
9113     case DRX_CONSTELLATION_QAM64:
9114     case DRX_CONSTELLATION_QAM256:
9115         if (ext_attr->standard != DRX_STANDARD_ITU_B)
9116             return -EINVAL;
9117 
9118         ext_attr->constellation = channel->constellation;
9119         if (channel->mirror == DRX_MIRROR_AUTO)
9120             ext_attr->mirror = DRX_MIRROR_NO;
9121         else
9122             ext_attr->mirror = channel->mirror;
9123 
9124         rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
9125         if (rc != 0) {
9126             pr_err("error %d\n", rc);
9127             goto rw_error;
9128         }
9129 
9130         if (channel->constellation == DRX_CONSTELLATION_QAM64)
9131             rc = qam64auto(demod, channel, tuner_freq_offset,
9132                        &lock_status);
9133         else
9134             rc = qam256auto(demod, channel, tuner_freq_offset,
9135                     &lock_status);
9136         if (rc != 0) {
9137             pr_err("error %d\n", rc);
9138             goto rw_error;
9139         }
9140         break;
9141     case DRX_CONSTELLATION_AUTO:    /* for channel scan */
9142         if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9143             u16 qam_ctl_ena = 0;
9144 
9145             auto_flag = true;
9146 
9147             /* try to lock default QAM constellation: QAM256 */
9148             channel->constellation = DRX_CONSTELLATION_QAM256;
9149             ext_attr->constellation = DRX_CONSTELLATION_QAM256;
9150             if (channel->mirror == DRX_MIRROR_AUTO)
9151                 ext_attr->mirror = DRX_MIRROR_NO;
9152             else
9153                 ext_attr->mirror = channel->mirror;
9154             rc = set_qam(demod, channel, tuner_freq_offset,
9155                      QAM_SET_OP_ALL);
9156             if (rc != 0) {
9157                 pr_err("error %d\n", rc);
9158                 goto rw_error;
9159             }
9160             rc = qam256auto(demod, channel, tuner_freq_offset,
9161                     &lock_status);
9162             if (rc != 0) {
9163                 pr_err("error %d\n", rc);
9164                 goto rw_error;
9165             }
9166 
9167             if (lock_status >= DRX_LOCKED) {
9168                 channel->constellation = DRX_CONSTELLATION_AUTO;
9169                 break;
9170             }
9171 
9172             /* QAM254 not locked. Try QAM64 constellation */
9173             channel->constellation = DRX_CONSTELLATION_QAM64;
9174             ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9175             if (channel->mirror == DRX_MIRROR_AUTO)
9176                 ext_attr->mirror = DRX_MIRROR_NO;
9177             else
9178                 ext_attr->mirror = channel->mirror;
9179 
9180             rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
9181                              SCU_RAM_QAM_CTL_ENA__A,
9182                              &qam_ctl_ena, 0);
9183             if (rc != 0) {
9184                 pr_err("error %d\n", rc);
9185                 goto rw_error;
9186             }
9187             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9188                               SCU_RAM_QAM_CTL_ENA__A,
9189                               qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9190             if (rc != 0) {
9191                 pr_err("error %d\n", rc);
9192                 goto rw_error;
9193             }
9194             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9195                               SCU_RAM_QAM_FSM_STATE_TGT__A,
9196                               0x2, 0);
9197             if (rc != 0) {
9198                 pr_err("error %d\n", rc);
9199                 goto rw_error;
9200             }   /* force to rate hunting */
9201 
9202             rc = set_qam(demod, channel, tuner_freq_offset,
9203                      QAM_SET_OP_CONSTELLATION);
9204             if (rc != 0) {
9205                 pr_err("error %d\n", rc);
9206                 goto rw_error;
9207             }
9208             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9209                               SCU_RAM_QAM_CTL_ENA__A,
9210                               qam_ctl_ena, 0);
9211             if (rc != 0) {
9212                 pr_err("error %d\n", rc);
9213                 goto rw_error;
9214             }
9215 
9216             rc = qam64auto(demod, channel, tuner_freq_offset,
9217                        &lock_status);
9218             if (rc != 0) {
9219                 pr_err("error %d\n", rc);
9220                 goto rw_error;
9221             }
9222 
9223             channel->constellation = DRX_CONSTELLATION_AUTO;
9224         } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9225             u16 qam_ctl_ena = 0;
9226 
9227             channel->constellation = DRX_CONSTELLATION_QAM64;
9228             ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9229             auto_flag = true;
9230 
9231             if (channel->mirror == DRX_MIRROR_AUTO)
9232                 ext_attr->mirror = DRX_MIRROR_NO;
9233             else
9234                 ext_attr->mirror = channel->mirror;
9235             rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
9236                              SCU_RAM_QAM_CTL_ENA__A,
9237                              &qam_ctl_ena, 0);
9238             if (rc != 0) {
9239                 pr_err("error %d\n", rc);
9240                 goto rw_error;
9241             }
9242             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9243                               SCU_RAM_QAM_CTL_ENA__A,
9244                               qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9245             if (rc != 0) {
9246                 pr_err("error %d\n", rc);
9247                 goto rw_error;
9248             }
9249             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9250                               SCU_RAM_QAM_FSM_STATE_TGT__A,
9251                               0x2, 0);
9252             if (rc != 0) {
9253                 pr_err("error %d\n", rc);
9254                 goto rw_error;
9255             }   /* force to rate hunting */
9256 
9257             rc = set_qam(demod, channel, tuner_freq_offset,
9258                      QAM_SET_OP_CONSTELLATION);
9259             if (rc != 0) {
9260                 pr_err("error %d\n", rc);
9261                 goto rw_error;
9262             }
9263             rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9264                               SCU_RAM_QAM_CTL_ENA__A,
9265                               qam_ctl_ena, 0);
9266             if (rc != 0) {
9267                 pr_err("error %d\n", rc);
9268                 goto rw_error;
9269             }
9270             rc = qam64auto(demod, channel, tuner_freq_offset,
9271                        &lock_status);
9272             if (rc != 0) {
9273                 pr_err("error %d\n", rc);
9274                 goto rw_error;
9275             }
9276             channel->constellation = DRX_CONSTELLATION_AUTO;
9277         } else {
9278             return -EINVAL;
9279         }
9280         break;
9281     default:
9282         return -EINVAL;
9283     }
9284 
9285     return 0;
9286 rw_error:
9287     /* restore starting value */
9288     if (auto_flag)
9289         channel->constellation = DRX_CONSTELLATION_AUTO;
9290     return rc;
9291 }
9292 
9293 /*============================================================================*/
9294 
9295 /*
9296 * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
9297 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
9298 * \return Error code
9299 *
9300 * precondition: measurement period & measurement prescale must be set
9301 *
9302 */
9303 static int
9304 get_qamrs_err_count(struct i2c_device_addr *dev_addr,
9305             struct drxjrs_errors *rs_errors)
9306 {
9307     int rc;
9308     u16 nr_bit_errors = 0,
9309         nr_symbol_errors = 0,
9310         nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
9311 
9312     /* check arguments */
9313     if (dev_addr == NULL)
9314         return -EINVAL;
9315 
9316     /* all reported errors are received in the  */
9317     /* most recently finished measurement period */
9318     /*   no of pre RS bit errors */
9319     rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
9320     if (rc != 0) {
9321         pr_err("error %d\n", rc);
9322         goto rw_error;
9323     }
9324     /*   no of symbol errors      */
9325     rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
9326     if (rc != 0) {
9327         pr_err("error %d\n", rc);
9328         goto rw_error;
9329     }
9330     /*   no of packet errors      */
9331     rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
9332     if (rc != 0) {
9333         pr_err("error %d\n", rc);
9334         goto rw_error;
9335     }
9336     /*   no of failures to decode */
9337     rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
9338     if (rc != 0) {
9339         pr_err("error %d\n", rc);
9340         goto rw_error;
9341     }
9342     /*   no of post RS bit erros  */
9343     rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
9344     if (rc != 0) {
9345         pr_err("error %d\n", rc);
9346         goto rw_error;
9347     }
9348     /* TODO: NOTE */
9349     /* These register values are fetched in non-atomic fashion           */
9350     /* It is possible that the read values contain unrelated information */
9351 
9352     rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
9353     rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
9354     rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
9355     rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
9356     rs_errors->nr_snc_par_fail_count =
9357         nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
9358 
9359     return 0;
9360 rw_error:
9361     return rc;
9362 }
9363 
9364 /*============================================================================*/
9365 
9366 /*
9367  * \fn int get_sig_strength()
9368  * \brief Retrieve signal strength for VSB and QAM.
9369  * \param demod Pointer to demod instance
9370  * \param u16-t Pointer to signal strength data; range 0, .. , 100.
9371  * \return int.
9372  * \retval 0 sig_strength contains valid data.
9373  * \retval -EINVAL sig_strength is NULL.
9374  * \retval -EIO Erroneous data, sig_strength contains invalid data.
9375  */
9376 #define DRXJ_AGC_TOP    0x2800
9377 #define DRXJ_AGC_SNS    0x1600
9378 #define DRXJ_RFAGC_MAX  0x3fff
9379 #define DRXJ_RFAGC_MIN  0x800
9380 
9381 static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
9382 {
9383     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9384     int rc;
9385     u16 rf_gain = 0;
9386     u16 if_gain = 0;
9387     u16 if_agc_sns = 0;
9388     u16 if_agc_top = 0;
9389     u16 rf_agc_max = 0;
9390     u16 rf_agc_min = 0;
9391 
9392     rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
9393     if (rc != 0) {
9394         pr_err("error %d\n", rc);
9395         goto rw_error;
9396     }
9397     if_gain &= IQM_AF_AGC_IF__M;
9398     rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
9399     if (rc != 0) {
9400         pr_err("error %d\n", rc);
9401         goto rw_error;
9402     }
9403     rf_gain &= IQM_AF_AGC_RF__M;
9404 
9405     if_agc_sns = DRXJ_AGC_SNS;
9406     if_agc_top = DRXJ_AGC_TOP;
9407     rf_agc_max = DRXJ_RFAGC_MAX;
9408     rf_agc_min = DRXJ_RFAGC_MIN;
9409 
9410     if (if_gain > if_agc_top) {
9411         if (rf_gain > rf_agc_max)
9412             *sig_strength = 100;
9413         else if (rf_gain > rf_agc_min) {
9414             if (rf_agc_max == rf_agc_min) {
9415                 pr_err("error: rf_agc_max == rf_agc_min\n");
9416                 return -EIO;
9417             }
9418             *sig_strength =
9419             75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
9420                                 rf_agc_min);
9421         } else
9422             *sig_strength = 75;
9423     } else if (if_gain > if_agc_sns) {
9424         if (if_agc_top == if_agc_sns) {
9425             pr_err("error: if_agc_top == if_agc_sns\n");
9426             return -EIO;
9427         }
9428         *sig_strength =
9429         20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
9430     } else {
9431         if (!if_agc_sns) {
9432             pr_err("error: if_agc_sns is zero!\n");
9433             return -EIO;
9434         }
9435         *sig_strength = (20 * if_gain / if_agc_sns);
9436     }
9437 
9438     if (*sig_strength <= 7)
9439         *sig_strength = 0;
9440 
9441     return 0;
9442 rw_error:
9443     return rc;
9444 }
9445 
9446 /*
9447 * \fn int ctrl_get_qam_sig_quality()
9448 * \brief Retrieve QAM signal quality from device.
9449 * \param devmod Pointer to demodulator instance.
9450 * \param sig_quality Pointer to signal quality data.
9451 * \return int.
9452 * \retval 0 sig_quality contains valid data.
9453 * \retval -EINVAL sig_quality is NULL.
9454 * \retval -EIO Erroneous data, sig_quality contains invalid data.
9455 
9456 *  Pre-condition: Device must be started and in lock.
9457 */
9458 static int
9459 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9460 {
9461     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9462     struct drxj_data *ext_attr = demod->my_ext_attr;
9463     struct drx39xxj_state *state = dev_addr->user_data;
9464     struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9465     struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
9466     enum drx_modulation constellation = ext_attr->constellation;
9467     int rc;
9468 
9469     u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
9470     u32 post_bit_err_rs = 0;    /* post RedSolomon Bit Error Rate */
9471     u32 pkt_errs = 0;   /* no of packet errors in RS */
9472     u16 qam_sl_err_power = 0;   /* accumulated error between raw and sliced symbols */
9473     u16 qsym_err_vd = 0;    /* quadrature symbol errors in QAM_VD */
9474     u16 fec_oc_period = 0;  /* SNC sync failure measurement period */
9475     u16 fec_rs_prescale = 0;    /* ReedSolomon Measurement Prescale */
9476     u16 fec_rs_period = 0;  /* Value for corresponding I2C register */
9477     /* calculation constants */
9478     u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
9479     u32 qam_sl_sig_power = 0;   /* used for MER, depends of QAM constellation */
9480     /* intermediate results */
9481     u32 e = 0;      /* exponent value used for QAM BER/SER */
9482     u32 m = 0;      /* mantisa value used for QAM BER/SER */
9483     u32 ber_cnt = 0;    /* BER count */
9484     /* signal quality info */
9485     u32 qam_sl_mer = 0; /* QAM MER */
9486     u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
9487     u32 qam_post_rs_ber = 0;    /* Post RedSolomon BER */
9488     u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
9489     u16 qam_vd_prescale = 0;    /* Viterbi Measurement Prescale */
9490     u16 qam_vd_period = 0;  /* Viterbi Measurement period */
9491     u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
9492 
9493     p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9494 
9495     /* read the physical registers */
9496     /*   Get the RS error data */
9497     rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
9498     if (rc != 0) {
9499         pr_err("error %d\n", rc);
9500         goto rw_error;
9501     }
9502     /* get the register value needed for MER */
9503     rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
9504     if (rc != 0) {
9505         pr_err("error %d\n", rc);
9506         goto rw_error;
9507     }
9508     /* get the register value needed for post RS BER */
9509     rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
9510     if (rc != 0) {
9511         pr_err("error %d\n", rc);
9512         goto rw_error;
9513     }
9514 
9515     /* get constants needed for signal quality calculation */
9516     fec_rs_period = ext_attr->fec_rs_period;
9517     fec_rs_prescale = ext_attr->fec_rs_prescale;
9518     rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
9519     qam_vd_period = ext_attr->qam_vd_period;
9520     qam_vd_prescale = ext_attr->qam_vd_prescale;
9521     vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
9522 
9523     /* DRXJ_QAM_SL_SIG_POWER_QAMxxx  * 4     */
9524     switch (constellation) {
9525     case DRX_CONSTELLATION_QAM16:
9526         qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
9527         break;
9528     case DRX_CONSTELLATION_QAM32:
9529         qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
9530         break;
9531     case DRX_CONSTELLATION_QAM64:
9532         qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
9533         break;
9534     case DRX_CONSTELLATION_QAM128:
9535         qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
9536         break;
9537     case DRX_CONSTELLATION_QAM256:
9538         qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
9539         break;
9540     default:
9541         return -EIO;
9542     }
9543 
9544     /* ------------------------------ */
9545     /* MER Calculation                */
9546     /* ------------------------------ */
9547     /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
9548 
9549     /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
9550     if (qam_sl_err_power == 0)
9551         qam_sl_mer = 0;
9552     else
9553         qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
9554 
9555     /* ----------------------------------------- */
9556     /* Pre Viterbi Symbol Error Rate Calculation */
9557     /* ----------------------------------------- */
9558     /* pre viterbi SER is good if it is below 0.025 */
9559 
9560     /* get the register value */
9561     /*   no of quadrature symbol errors */
9562     rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
9563     if (rc != 0) {
9564         pr_err("error %d\n", rc);
9565         goto rw_error;
9566     }
9567     /* Extract the Exponent and the Mantisa  */
9568     /* of number of quadrature symbol errors */
9569     e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
9570         QAM_VD_NR_QSYM_ERRORS_EXP__B;
9571     m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
9572         QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
9573 
9574     if ((m << e) >> 3 > 549752)
9575         qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9576     else
9577         qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
9578 
9579     /* --------------------------------------- */
9580     /* pre and post RedSolomon BER Calculation */
9581     /* --------------------------------------- */
9582     /* pre RS BER is good if it is below 3.5e-4 */
9583 
9584     /* get the register values */
9585     pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
9586     pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
9587 
9588     /* Extract the Exponent and the Mantisa of the */
9589     /* pre Reed-Solomon bit error count            */
9590     e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
9591         FEC_RS_NR_BIT_ERRORS_EXP__B;
9592     m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
9593         FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
9594 
9595     ber_cnt = m << e;
9596 
9597     /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
9598     if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
9599         qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
9600     else
9601         qam_pre_rs_ber = ber_cnt;
9602 
9603     /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) /  */
9604     /*               (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A)  */
9605     /*
9606        => c = (1000000*100*11.17)/1504 =
9607        post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
9608        (100 * FEC_OC_SNC_FAIL_PERIOD__A)
9609        *100 and /100 is for more precision.
9610        => (20 bits * 12 bits) /(16 bits * 7 bits)  => safe in 32 bits computation
9611 
9612        Precision errors still possible.
9613      */
9614     if (!fec_oc_period) {
9615         qam_post_rs_ber = 0xFFFFFFFF;
9616     } else {
9617         e = post_bit_err_rs * 742686;
9618         m = fec_oc_period * 100;
9619         qam_post_rs_ber = e / m;
9620     }
9621 
9622     /* fill signal quality data structure */
9623     p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9624     p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9625     p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9626     p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9627     p->block_error.stat[0].scale = FE_SCALE_COUNTER;
9628     p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9629 
9630     p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
9631     if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9632         p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
9633         p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9634     } else {
9635         p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
9636         p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9637     }
9638 
9639     p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
9640     p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9641 
9642     p->block_error.stat[0].uvalue += pkt_errs;
9643 
9644 #ifdef DRXJ_SIGNAL_ACCUM_ERR
9645     rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
9646     if (rc != 0) {
9647         pr_err("error %d\n", rc);
9648         goto rw_error;
9649     }
9650 #endif
9651 
9652     return 0;
9653 rw_error:
9654     p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9655     p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9656     p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9657     p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9658     p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9659     p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9660 
9661     return rc;
9662 }
9663 
9664 #endif /* #ifndef DRXJ_VSB_ONLY */
9665 
9666 /*============================================================================*/
9667 /*==                     END QAM DATAPATH FUNCTIONS                         ==*/
9668 /*============================================================================*/
9669 
9670 /*============================================================================*/
9671 /*============================================================================*/
9672 /*==                       ATV DATAPATH FUNCTIONS                           ==*/
9673 /*============================================================================*/
9674 /*============================================================================*/
9675 
9676 /*
9677    Implementation notes.
9678 
9679    NTSC/FM AGCs
9680 
9681       Four AGCs are used for NTSC:
9682       (1) RF (used to attenuate the input signal in case of to much power)
9683       (2) IF (used to attenuate the input signal in case of to much power)
9684       (3) Video AGC (used to amplify the output signal in case input to low)
9685       (4) SIF AGC (used to amplify the output signal in case input to low)
9686 
9687       Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
9688       that the coupling between Video AGC and the RF and IF AGCs also works in
9689       favor of the SIF AGC.
9690 
9691       Three AGCs are used for FM:
9692       (1) RF (used to attenuate the input signal in case of to much power)
9693       (2) IF (used to attenuate the input signal in case of to much power)
9694       (3) SIF AGC (used to amplify the output signal in case input to low)
9695 
9696       The SIF AGC is now coupled to the RF/IF AGCs.
9697       The SIF AGC is needed for both SIF output and the internal SIF signal to
9698       the AUD block.
9699 
9700       RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
9701       the ATV block. The AGC control algorithms are all implemented in
9702       microcode.
9703 
9704    ATV SETTINGS
9705 
9706       (Shadow settings will not be used for now, they will be implemented
9707        later on because of the schedule)
9708 
9709       Several HW/SCU "settings" can be used for ATV. The standard selection
9710       will reset most of these settings. To avoid that the end user application
9711       has to perform these settings each time the ATV or FM standards is
9712       selected the driver will shadow these settings. This enables the end user
9713       to perform the settings only once after a drx_open(). The driver must
9714       write the shadow settings to HW/SCU in case:
9715      ( setstandard FM/ATV) ||
9716      ( settings have changed && FM/ATV standard is active)
9717       The shadow settings will be stored in the device specific data container.
9718       A set of flags will be defined to flag changes in shadow settings.
9719       A routine will be implemented to write all changed shadow settings to
9720       HW/SCU.
9721 
9722       The "settings" will consist of: AGC settings, filter settings etc.
9723 
9724       Disadvantage of use of shadow settings:
9725       Direct changes in HW/SCU registers will not be reflected in the
9726       shadow settings and these changes will be overwritten during a next
9727       update. This can happen during evaluation. This will not be a problem
9728       for normal customer usage.
9729 */
9730 /* -------------------------------------------------------------------------- */
9731 
9732 /*
9733 * \fn int power_down_atv ()
9734 * \brief Power down ATV.
9735 * \param demod instance of demodulator
9736 * \param standard either NTSC or FM (sub strandard for ATV )
9737 * \return int.
9738 *
9739 *  Stops and thus resets ATV and IQM block
9740 *  SIF and CVBS ADC are powered down
9741 *  Calls audio power down
9742 */
9743 static int
9744 power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
9745 {
9746     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9747     struct drxjscu_cmd cmd_scu = { /* command      */ 0,
9748         /* parameter_len */ 0,
9749         /* result_len    */ 0,
9750         /* *parameter   */ NULL,
9751         /* *result      */ NULL
9752     };
9753     int rc;
9754     u16 cmd_result = 0;
9755 
9756     /* ATV NTSC */
9757 
9758     /* Stop ATV SCU (will reset ATV and IQM hardware */
9759     cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
9760         SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9761     cmd_scu.parameter_len = 0;
9762     cmd_scu.result_len = 1;
9763     cmd_scu.parameter = NULL;
9764     cmd_scu.result = &cmd_result;
9765     rc = scu_command(dev_addr, &cmd_scu);
9766     if (rc != 0) {
9767         pr_err("error %d\n", rc);
9768         goto rw_error;
9769     }
9770     /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
9771     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);
9772     if (rc != 0) {
9773         pr_err("error %d\n", rc);
9774         goto rw_error;
9775     }
9776 
9777     rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
9778     if (rc != 0) {
9779         pr_err("error %d\n", rc);
9780         goto rw_error;
9781     }
9782     if (primary) {
9783         rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9784         if (rc != 0) {
9785             pr_err("error %d\n", rc);
9786             goto rw_error;
9787         }
9788         rc = set_iqm_af(demod, false);
9789         if (rc != 0) {
9790             pr_err("error %d\n", rc);
9791             goto rw_error;
9792         }
9793     } else {
9794         rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9795         if (rc != 0) {
9796             pr_err("error %d\n", rc);
9797             goto rw_error;
9798         }
9799         rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9800         if (rc != 0) {
9801             pr_err("error %d\n", rc);
9802             goto rw_error;
9803         }
9804         rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9805         if (rc != 0) {
9806             pr_err("error %d\n", rc);
9807             goto rw_error;
9808         }
9809         rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9810         if (rc != 0) {
9811             pr_err("error %d\n", rc);
9812             goto rw_error;
9813         }
9814         rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9815         if (rc != 0) {
9816             pr_err("error %d\n", rc);
9817             goto rw_error;
9818         }
9819     }
9820     rc = power_down_aud(demod);
9821     if (rc != 0) {
9822         pr_err("error %d\n", rc);
9823         goto rw_error;
9824     }
9825 
9826     return 0;
9827 rw_error:
9828     return rc;
9829 }
9830 
9831 /*============================================================================*/
9832 
9833 /*
9834 * \brief Power up AUD.
9835 * \param demod instance of demodulator
9836 * \return int.
9837 *
9838 */
9839 static int power_down_aud(struct drx_demod_instance *demod)
9840 {
9841     struct i2c_device_addr *dev_addr = NULL;
9842     struct drxj_data *ext_attr = NULL;
9843     int rc;
9844 
9845     dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
9846     ext_attr = (struct drxj_data *) demod->my_ext_attr;
9847 
9848     rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
9849     if (rc != 0) {
9850         pr_err("error %d\n", rc);
9851         goto rw_error;
9852     }
9853 
9854     ext_attr->aud_data.audio_is_active = false;
9855 
9856     return 0;
9857 rw_error:
9858     return rc;
9859 }
9860 
9861 /*
9862 * \fn int set_orx_nsu_aox()
9863 * \brief Configure OrxNsuAox for OOB
9864 * \param demod instance of demodulator.
9865 * \param active
9866 * \return int.
9867 */
9868 static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
9869 {
9870     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9871     int rc;
9872     u16 data = 0;
9873 
9874     /* Configure NSU_AOX */
9875     rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
9876     if (rc != 0) {
9877         pr_err("error %d\n", rc);
9878         goto rw_error;
9879     }
9880     if (!active)
9881         data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
9882     else
9883         data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
9884     rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
9885     if (rc != 0) {
9886         pr_err("error %d\n", rc);
9887         goto rw_error;
9888     }
9889 
9890     return 0;
9891 rw_error:
9892     return rc;
9893 }
9894 
9895 /*
9896 * \fn int ctrl_set_oob()
9897 * \brief Set OOB channel to be used.
9898 * \param demod instance of demodulator
9899 * \param oob_param OOB parameters for channel setting.
9900 * \frequency should be in KHz
9901 * \return int.
9902 *
9903 * Accepts  only. Returns error otherwise.
9904 * Demapper value is written after scu_command START
9905 * because START command causes COMM_EXEC transition
9906 * from 0 to 1 which causes all registers to be
9907 * overwritten with initial value
9908 *
9909 */
9910 
9911 /* Nyquist filter impulse response */
9912 #define IMPULSE_COSINE_ALPHA_0_3    {-3, -4, -1, 6, 10, 7, -5, -20, -25, -10, 29, 79, 123, 140} /*sqrt raised-cosine filter with alpha=0.3 */
9913 #define IMPULSE_COSINE_ALPHA_0_5    { 2, 0, -2, -2, 2, 5, 2, -10, -20, -14, 20, 74, 125, 145}   /*sqrt raised-cosine filter with alpha=0.5 */
9914 #define IMPULSE_COSINE_ALPHA_RO_0_5 { 0, 0, 1, 2, 3, 0, -7, -15, -16,  0, 34, 77, 114, 128} /*full raised-cosine filter with alpha=0.5 (receiver only) */
9915 
9916 /* Coefficients for the nyquist filter (total: 27 taps) */
9917 #define NYQFILTERLEN 27
9918 
9919 static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
9920 {
9921     int rc;
9922     s32 freq = 0;   /* KHz */
9923     struct i2c_device_addr *dev_addr = NULL;
9924     struct drxj_data *ext_attr = NULL;
9925     u16 i = 0;
9926     bool mirror_freq_spect_oob = false;
9927     u16 trk_filter_value = 0;
9928     struct drxjscu_cmd scu_cmd;
9929     u16 set_param_parameters[3];
9930     u16 cmd_result[2] = { 0, 0 };
9931     s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
9932         IMPULSE_COSINE_ALPHA_0_3,   /* Target Mode 0 */
9933         IMPULSE_COSINE_ALPHA_0_3,   /* Target Mode 1 */
9934         IMPULSE_COSINE_ALPHA_0_5,   /* Target Mode 2 */
9935         IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
9936     };
9937     u8 mode_val[4] = { 2, 2, 0, 1 };
9938     u8 pfi_coeffs[4][6] = {
9939         {DRXJ_16TO8(-92), DRXJ_16TO8(-108), DRXJ_16TO8(100)},   /* TARGET_MODE = 0:     PFI_A = -23/32; PFI_B = -54/32;  PFI_C = 25/32; fg = 0.5 MHz (Att=26dB) */
9940         {DRXJ_16TO8(-64), DRXJ_16TO8(-80), DRXJ_16TO8(80)}, /* TARGET_MODE = 1:     PFI_A = -16/32; PFI_B = -40/32;  PFI_C = 20/32; fg = 1.0 MHz (Att=28dB) */
9941         {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}, /* TARGET_MODE = 2, 3:  PFI_A = -20/32; PFI_B = -49/32;  PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
9942         {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}  /* TARGET_MODE = 2, 3:  PFI_A = -20/32; PFI_B = -49/32;  PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
9943     };
9944     u16 mode_index;
9945 
9946     dev_addr = demod->my_i2c_dev_addr;
9947     ext_attr = (struct drxj_data *) demod->my_ext_attr;
9948     mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
9949 
9950     /* Check parameters */
9951     if (oob_param == NULL) {
9952         /* power off oob module  */
9953         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
9954             | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9955         scu_cmd.parameter_len = 0;
9956         scu_cmd.result_len = 1;
9957         scu_cmd.result = cmd_result;
9958         rc = scu_command(dev_addr, &scu_cmd);
9959         if (rc != 0) {
9960             pr_err("error %d\n", rc);
9961             goto rw_error;
9962         }
9963         rc = set_orx_nsu_aox(demod, false);
9964         if (rc != 0) {
9965             pr_err("error %d\n", rc);
9966             goto rw_error;
9967         }
9968         rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
9969         if (rc != 0) {
9970             pr_err("error %d\n", rc);
9971             goto rw_error;
9972         }
9973 
9974         ext_attr->oob_power_on = false;
9975         return 0;
9976     }
9977 
9978     freq = oob_param->frequency;
9979     if ((freq < 70000) || (freq > 130000))
9980         return -EIO;
9981     freq = (freq - 50000) / 50;
9982 
9983     {
9984         u16 index = 0;
9985         u16 remainder = 0;
9986         u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
9987 
9988         index = (u16) ((freq - 400) / 200);
9989         remainder = (u16) ((freq - 400) % 200);
9990         trk_filter_value =
9991             trk_filtercfg[index] - (trk_filtercfg[index] -
9992                        trk_filtercfg[index +
9993                             1]) / 10 * remainder /
9994             20;
9995     }
9996 
9997    /********/
9998     /* Stop  */
9999    /********/
10000     rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
10001     if (rc != 0) {
10002         pr_err("error %d\n", rc);
10003         goto rw_error;
10004     }
10005     scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10006         | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
10007     scu_cmd.parameter_len = 0;
10008     scu_cmd.result_len = 1;
10009     scu_cmd.result = cmd_result;
10010     rc = scu_command(dev_addr, &scu_cmd);
10011     if (rc != 0) {
10012         pr_err("error %d\n", rc);
10013         goto rw_error;
10014     }
10015    /********/
10016     /* Reset */
10017    /********/
10018     scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10019         | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
10020     scu_cmd.parameter_len = 0;
10021     scu_cmd.result_len = 1;
10022     scu_cmd.result = cmd_result;
10023     rc = scu_command(dev_addr, &scu_cmd);
10024     if (rc != 0) {
10025         pr_err("error %d\n", rc);
10026         goto rw_error;
10027     }
10028    /**********/
10029     /* SET_ENV */
10030    /**********/
10031     /* set frequency, spectrum inversion and data rate */
10032     scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10033         | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
10034     scu_cmd.parameter_len = 3;
10035     /* 1-data rate;2-frequency */
10036     switch (oob_param->standard) {
10037     case DRX_OOB_MODE_A:
10038         if (
10039                /* signal is transmitted inverted */
10040                ((oob_param->spectrum_inverted == true) &&
10041                 /* and tuner is not mirroring the signal */
10042                 (!mirror_freq_spect_oob)) |
10043                /* or */
10044                /* signal is transmitted noninverted */
10045                ((oob_param->spectrum_inverted == false) &&
10046                 /* and tuner is mirroring the signal */
10047                 (mirror_freq_spect_oob))
10048             )
10049             set_param_parameters[0] =
10050                 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
10051         else
10052             set_param_parameters[0] =
10053                 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
10054         break;
10055     case DRX_OOB_MODE_B_GRADE_A:
10056         if (
10057                /* signal is transmitted inverted */
10058                ((oob_param->spectrum_inverted == true) &&
10059                 /* and tuner is not mirroring the signal */
10060                 (!mirror_freq_spect_oob)) |
10061                /* or */
10062                /* signal is transmitted noninverted */
10063                ((oob_param->spectrum_inverted == false) &&
10064                 /* and tuner is mirroring the signal */
10065                 (mirror_freq_spect_oob))
10066             )
10067             set_param_parameters[0] =
10068                 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
10069         else
10070             set_param_parameters[0] =
10071                 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
10072         break;
10073     case DRX_OOB_MODE_B_GRADE_B:
10074     default:
10075         if (
10076                /* signal is transmitted inverted */
10077                ((oob_param->spectrum_inverted == true) &&
10078                 /* and tuner is not mirroring the signal */
10079                 (!mirror_freq_spect_oob)) |
10080                /* or */
10081                /* signal is transmitted noninverted */
10082                ((oob_param->spectrum_inverted == false) &&
10083                 /* and tuner is mirroring the signal */
10084                 (mirror_freq_spect_oob))
10085             )
10086             set_param_parameters[0] =
10087                 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
10088         else
10089             set_param_parameters[0] =
10090                 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
10091         break;
10092     }
10093     set_param_parameters[1] = (u16) (freq & 0xFFFF);
10094     set_param_parameters[2] = trk_filter_value;
10095     scu_cmd.parameter = set_param_parameters;
10096     scu_cmd.result_len = 1;
10097     scu_cmd.result = cmd_result;
10098     mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
10099     rc = scu_command(dev_addr, &scu_cmd);
10100     if (rc != 0) {
10101         pr_err("error %d\n", rc);
10102         goto rw_error;
10103     }
10104 
10105     rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
10106     if (rc != 0) {
10107         pr_err("error %d\n", rc);
10108         goto rw_error;
10109     }   /*  Write magic word to enable pdr reg write  */
10110     rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
10111     if (rc != 0) {
10112         pr_err("error %d\n", rc);
10113         goto rw_error;
10114     }
10115     rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
10116     if (rc != 0) {
10117         pr_err("error %d\n", rc);
10118         goto rw_error;
10119     }
10120     rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
10121     if (rc != 0) {
10122         pr_err("error %d\n", rc);
10123         goto rw_error;
10124     }   /*  Write magic word to disable pdr reg write */
10125 
10126     rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
10127     if (rc != 0) {
10128         pr_err("error %d\n", rc);
10129         goto rw_error;
10130     }
10131     rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
10132     if (rc != 0) {
10133         pr_err("error %d\n", rc);
10134         goto rw_error;
10135     }
10136     rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
10137     if (rc != 0) {
10138         pr_err("error %d\n", rc);
10139         goto rw_error;
10140     }
10141 
10142     /* ddc */
10143     rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
10144     if (rc != 0) {
10145         pr_err("error %d\n", rc);
10146         goto rw_error;
10147     }
10148 
10149     /* nsu */
10150     rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
10151     if (rc != 0) {
10152         pr_err("error %d\n", rc);
10153         goto rw_error;
10154     }
10155 
10156     /* initialization for target mode */
10157     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
10158     if (rc != 0) {
10159         pr_err("error %d\n", rc);
10160         goto rw_error;
10161     }
10162     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
10163     if (rc != 0) {
10164         pr_err("error %d\n", rc);
10165         goto rw_error;
10166     }
10167 
10168     /* Reset bits for timing and freq. recovery */
10169     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
10170     if (rc != 0) {
10171         pr_err("error %d\n", rc);
10172         goto rw_error;
10173     }
10174     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
10175     if (rc != 0) {
10176         pr_err("error %d\n", rc);
10177         goto rw_error;
10178     }
10179     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
10180     if (rc != 0) {
10181         pr_err("error %d\n", rc);
10182         goto rw_error;
10183     }
10184     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
10185     if (rc != 0) {
10186         pr_err("error %d\n", rc);
10187         goto rw_error;
10188     }
10189 
10190     /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
10191     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
10192     if (rc != 0) {
10193         pr_err("error %d\n", rc);
10194         goto rw_error;
10195     }
10196     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
10197     if (rc != 0) {
10198         pr_err("error %d\n", rc);
10199         goto rw_error;
10200     }
10201     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
10202     if (rc != 0) {
10203         pr_err("error %d\n", rc);
10204         goto rw_error;
10205     }
10206     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
10207     if (rc != 0) {
10208         pr_err("error %d\n", rc);
10209         goto rw_error;
10210     }
10211     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
10212     if (rc != 0) {
10213         pr_err("error %d\n", rc);
10214         goto rw_error;
10215     }
10216 
10217     /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
10218     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
10219     if (rc != 0) {
10220         pr_err("error %d\n", rc);
10221         goto rw_error;
10222     }
10223     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
10224     if (rc != 0) {
10225         pr_err("error %d\n", rc);
10226         goto rw_error;
10227     }
10228     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
10229     if (rc != 0) {
10230         pr_err("error %d\n", rc);
10231         goto rw_error;
10232     }
10233     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
10234     if (rc != 0) {
10235         pr_err("error %d\n", rc);
10236         goto rw_error;
10237     }
10238     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
10239     if (rc != 0) {
10240         pr_err("error %d\n", rc);
10241         goto rw_error;
10242     }
10243 
10244     /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
10245     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
10246     if (rc != 0) {
10247         pr_err("error %d\n", rc);
10248         goto rw_error;
10249     }
10250     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
10251     if (rc != 0) {
10252         pr_err("error %d\n", rc);
10253         goto rw_error;
10254     }
10255     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
10256     if (rc != 0) {
10257         pr_err("error %d\n", rc);
10258         goto rw_error;
10259     }
10260     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
10261     if (rc != 0) {
10262         pr_err("error %d\n", rc);
10263         goto rw_error;
10264     }
10265     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
10266     if (rc != 0) {
10267         pr_err("error %d\n", rc);
10268         goto rw_error;
10269     }
10270 
10271     /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
10272     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
10273     if (rc != 0) {
10274         pr_err("error %d\n", rc);
10275         goto rw_error;
10276     }
10277     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
10278     if (rc != 0) {
10279         pr_err("error %d\n", rc);
10280         goto rw_error;
10281     }
10282     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
10283     if (rc != 0) {
10284         pr_err("error %d\n", rc);
10285         goto rw_error;
10286     }
10287     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
10288     if (rc != 0) {
10289         pr_err("error %d\n", rc);
10290         goto rw_error;
10291     }
10292     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
10293     if (rc != 0) {
10294         pr_err("error %d\n", rc);
10295         goto rw_error;
10296     }
10297 
10298     /* TIM_LOCK = {300,      -2048, 8, -8, 0, 1<<4}; */
10299     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
10300     if (rc != 0) {
10301         pr_err("error %d\n", rc);
10302         goto rw_error;
10303     }
10304     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
10305     if (rc != 0) {
10306         pr_err("error %d\n", rc);
10307         goto rw_error;
10308     }
10309     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
10310     if (rc != 0) {
10311         pr_err("error %d\n", rc);
10312         goto rw_error;
10313     }
10314     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
10315     if (rc != 0) {
10316         pr_err("error %d\n", rc);
10317         goto rw_error;
10318     }
10319     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
10320     if (rc != 0) {
10321         pr_err("error %d\n", rc);
10322         goto rw_error;
10323     }
10324 
10325     /* EQU_LOCK = {20,      -2048, 8, -8, 0, 1<<5}; */
10326     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
10327     if (rc != 0) {
10328         pr_err("error %d\n", rc);
10329         goto rw_error;
10330     }
10331     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
10332     if (rc != 0) {
10333         pr_err("error %d\n", rc);
10334         goto rw_error;
10335     }
10336     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
10337     if (rc != 0) {
10338         pr_err("error %d\n", rc);
10339         goto rw_error;
10340     }
10341     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
10342     if (rc != 0) {
10343         pr_err("error %d\n", rc);
10344         goto rw_error;
10345     }
10346     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
10347     if (rc != 0) {
10348         pr_err("error %d\n", rc);
10349         goto rw_error;
10350     }
10351 
10352     /* PRE-Filter coefficients (PFI) */
10353     rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
10354     if (rc != 0) {
10355         pr_err("error %d\n", rc);
10356         goto rw_error;
10357     }
10358     rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
10359     if (rc != 0) {
10360         pr_err("error %d\n", rc);
10361         goto rw_error;
10362     }
10363 
10364     /* NYQUIST-Filter coefficients (NYQ) */
10365     for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
10366         rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
10367         if (rc != 0) {
10368             pr_err("error %d\n", rc);
10369             goto rw_error;
10370         }
10371         rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
10372         if (rc != 0) {
10373             pr_err("error %d\n", rc);
10374             goto rw_error;
10375         }
10376     }
10377     rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
10378     if (rc != 0) {
10379         pr_err("error %d\n", rc);
10380         goto rw_error;
10381     }
10382     rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
10383     if (rc != 0) {
10384         pr_err("error %d\n", rc);
10385         goto rw_error;
10386     }
10387     /********/
10388     /* Start */
10389     /********/
10390     scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10391         | SCU_RAM_COMMAND_CMD_DEMOD_START;
10392     scu_cmd.parameter_len = 0;
10393     scu_cmd.result_len = 1;
10394     scu_cmd.result = cmd_result;
10395     rc = scu_command(dev_addr, &scu_cmd);
10396     if (rc != 0) {
10397         pr_err("error %d\n", rc);
10398         goto rw_error;
10399     }
10400 
10401     rc = set_orx_nsu_aox(demod, true);
10402     if (rc != 0) {
10403         pr_err("error %d\n", rc);
10404         goto rw_error;
10405     }
10406     rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
10407     if (rc != 0) {
10408         pr_err("error %d\n", rc);
10409         goto rw_error;
10410     }
10411 
10412     ext_attr->oob_power_on = true;
10413 
10414     return 0;
10415 rw_error:
10416     return rc;
10417 }
10418 
10419 /*============================================================================*/
10420 /*==                     END OOB DATAPATH FUNCTIONS                         ==*/
10421 /*============================================================================*/
10422 
10423 /*=============================================================================
10424   ===== MC command related functions ==========================================
10425   ===========================================================================*/
10426 
10427 /*=============================================================================
10428   ===== ctrl_set_channel() ==========================================================
10429   ===========================================================================*/
10430 /*
10431 * \fn int ctrl_set_channel()
10432 * \brief Select a new transmission channel.
10433 * \param demod instance of demod.
10434 * \param channel Pointer to channel data.
10435 * \return int.
10436 *
10437 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
10438 * must tune the tuner to the centre frequency of the NTSC/FM channel.
10439 *
10440 */
10441 static int
10442 ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
10443 {
10444     int rc;
10445     s32 tuner_freq_offset = 0;
10446     struct drxj_data *ext_attr = NULL;
10447     struct i2c_device_addr *dev_addr = NULL;
10448     enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10449 #ifndef DRXJ_VSB_ONLY
10450     u32 min_symbol_rate = 0;
10451     u32 max_symbol_rate = 0;
10452     int bandwidth_temp = 0;
10453     int bandwidth = 0;
10454 #endif
10455    /*== check arguments ======================================================*/
10456     if ((demod == NULL) || (channel == NULL))
10457         return -EINVAL;
10458 
10459     dev_addr = demod->my_i2c_dev_addr;
10460     ext_attr = (struct drxj_data *) demod->my_ext_attr;
10461     standard = ext_attr->standard;
10462 
10463     /* check valid standards */
10464     switch (standard) {
10465     case DRX_STANDARD_8VSB:
10466 #ifndef DRXJ_VSB_ONLY
10467     case DRX_STANDARD_ITU_A:
10468     case DRX_STANDARD_ITU_B:
10469     case DRX_STANDARD_ITU_C:
10470 #endif /* DRXJ_VSB_ONLY */
10471         break;
10472     case DRX_STANDARD_UNKNOWN:
10473     default:
10474         return -EINVAL;
10475     }
10476 
10477     /* check bandwidth QAM annex B, NTSC and 8VSB */
10478     if ((standard == DRX_STANDARD_ITU_B) ||
10479         (standard == DRX_STANDARD_8VSB) ||
10480         (standard == DRX_STANDARD_NTSC)) {
10481         switch (channel->bandwidth) {
10482         case DRX_BANDWIDTH_6MHZ:
10483         case DRX_BANDWIDTH_UNKNOWN:
10484             channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10485             break;
10486         case DRX_BANDWIDTH_8MHZ:
10487         case DRX_BANDWIDTH_7MHZ:
10488         default:
10489             return -EINVAL;
10490         }
10491     }
10492 
10493     /* For QAM annex A and annex C:
10494        -check symbolrate and constellation
10495        -derive bandwidth from symbolrate (input bandwidth is ignored)
10496      */
10497 #ifndef DRXJ_VSB_ONLY
10498     if ((standard == DRX_STANDARD_ITU_A) ||
10499         (standard == DRX_STANDARD_ITU_C)) {
10500         struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
10501         int bw_rolloff_factor = 0;
10502 
10503         bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
10504         min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
10505         max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
10506         /* config SMA_TX pin to SAW switch mode */
10507         rc = ctrl_set_uio_cfg(demod, &uio_cfg);
10508         if (rc != 0) {
10509             pr_err("error %d\n", rc);
10510             goto rw_error;
10511         }
10512 
10513         if (channel->symbolrate < min_symbol_rate ||
10514             channel->symbolrate > max_symbol_rate) {
10515             return -EINVAL;
10516         }
10517 
10518         switch (channel->constellation) {
10519         case DRX_CONSTELLATION_QAM16:
10520         case DRX_CONSTELLATION_QAM32:
10521         case DRX_CONSTELLATION_QAM64:
10522         case DRX_CONSTELLATION_QAM128:
10523         case DRX_CONSTELLATION_QAM256:
10524             bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
10525             bandwidth = bandwidth_temp / 100;
10526 
10527             if ((bandwidth_temp % 100) >= 50)
10528                 bandwidth++;
10529 
10530             if (bandwidth <= 6100000) {
10531                 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10532             } else if ((bandwidth > 6100000)
10533                    && (bandwidth <= 7100000)) {
10534                 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
10535             } else if (bandwidth > 7100000) {
10536                 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
10537             }
10538             break;
10539         default:
10540             return -EINVAL;
10541         }
10542     }
10543 
10544     /* For QAM annex B:
10545        -check constellation
10546      */
10547     if (standard == DRX_STANDARD_ITU_B) {
10548         switch (channel->constellation) {
10549         case DRX_CONSTELLATION_AUTO:
10550         case DRX_CONSTELLATION_QAM256:
10551         case DRX_CONSTELLATION_QAM64:
10552             break;
10553         default:
10554             return -EINVAL;
10555         }
10556 
10557         switch (channel->interleavemode) {
10558         case DRX_INTERLEAVEMODE_I128_J1:
10559         case DRX_INTERLEAVEMODE_I128_J1_V2:
10560         case DRX_INTERLEAVEMODE_I128_J2:
10561         case DRX_INTERLEAVEMODE_I64_J2:
10562         case DRX_INTERLEAVEMODE_I128_J3:
10563         case DRX_INTERLEAVEMODE_I32_J4:
10564         case DRX_INTERLEAVEMODE_I128_J4:
10565         case DRX_INTERLEAVEMODE_I16_J8:
10566         case DRX_INTERLEAVEMODE_I128_J5:
10567         case DRX_INTERLEAVEMODE_I8_J16:
10568         case DRX_INTERLEAVEMODE_I128_J6:
10569         case DRX_INTERLEAVEMODE_I128_J7:
10570         case DRX_INTERLEAVEMODE_I128_J8:
10571         case DRX_INTERLEAVEMODE_I12_J17:
10572         case DRX_INTERLEAVEMODE_I5_J4:
10573         case DRX_INTERLEAVEMODE_B52_M240:
10574         case DRX_INTERLEAVEMODE_B52_M720:
10575         case DRX_INTERLEAVEMODE_UNKNOWN:
10576         case DRX_INTERLEAVEMODE_AUTO:
10577             break;
10578         default:
10579             return -EINVAL;
10580         }
10581     }
10582 
10583     if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
10584         /* SAW SW, user UIO is used for switchable SAW */
10585         struct drxuio_data uio1 = { DRX_UIO1, false };
10586 
10587         switch (channel->bandwidth) {
10588         case DRX_BANDWIDTH_8MHZ:
10589             uio1.value = true;
10590             break;
10591         case DRX_BANDWIDTH_7MHZ:
10592             uio1.value = false;
10593             break;
10594         case DRX_BANDWIDTH_6MHZ:
10595             uio1.value = false;
10596             break;
10597         case DRX_BANDWIDTH_UNKNOWN:
10598         default:
10599             return -EINVAL;
10600         }
10601 
10602         rc = ctrl_uio_write(demod, &uio1);
10603         if (rc != 0) {
10604             pr_err("error %d\n", rc);
10605             goto rw_error;
10606         }
10607     }
10608 #endif /* DRXJ_VSB_ONLY */
10609     rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
10610     if (rc != 0) {
10611         pr_err("error %d\n", rc);
10612         goto rw_error;
10613     }
10614 
10615     tuner_freq_offset = 0;
10616 
10617    /*== Setup demod for specific standard ====================================*/
10618     switch (standard) {
10619     case DRX_STANDARD_8VSB:
10620         if (channel->mirror == DRX_MIRROR_AUTO)
10621             ext_attr->mirror = DRX_MIRROR_NO;
10622         else
10623             ext_attr->mirror = channel->mirror;
10624         rc = set_vsb(demod);
10625         if (rc != 0) {
10626             pr_err("error %d\n", rc);
10627             goto rw_error;
10628         }
10629         rc = set_frequency(demod, channel, tuner_freq_offset);
10630         if (rc != 0) {
10631             pr_err("error %d\n", rc);
10632             goto rw_error;
10633         }
10634         break;
10635 #ifndef DRXJ_VSB_ONLY
10636     case DRX_STANDARD_ITU_A:
10637     case DRX_STANDARD_ITU_B:
10638     case DRX_STANDARD_ITU_C:
10639         rc = set_qam_channel(demod, channel, tuner_freq_offset);
10640         if (rc != 0) {
10641             pr_err("error %d\n", rc);
10642             goto rw_error;
10643         }
10644         break;
10645 #endif
10646     case DRX_STANDARD_UNKNOWN:
10647     default:
10648         return -EIO;
10649     }
10650 
10651     /* flag the packet error counter reset */
10652     ext_attr->reset_pkt_err_acc = true;
10653 
10654     return 0;
10655 rw_error:
10656     return rc;
10657 }
10658 
10659 /*=============================================================================
10660   ===== SigQuality() ==========================================================
10661   ===========================================================================*/
10662 
10663 /*
10664 * \fn int ctrl_sig_quality()
10665 * \brief Retrieve signal quality form device.
10666 * \param devmod Pointer to demodulator instance.
10667 * \param sig_quality Pointer to signal quality data.
10668 * \return int.
10669 * \retval 0 sig_quality contains valid data.
10670 * \retval -EINVAL sig_quality is NULL.
10671 * \retval -EIO Erroneous data, sig_quality contains invalid data.
10672 
10673 */
10674 static int
10675 ctrl_sig_quality(struct drx_demod_instance *demod,
10676          enum drx_lock_status lock_status)
10677 {
10678     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
10679     struct drxj_data *ext_attr = demod->my_ext_attr;
10680     struct drx39xxj_state *state = dev_addr->user_data;
10681     struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10682     enum drx_standard standard = ext_attr->standard;
10683     int rc;
10684     u32 ber, cnt, err, pkt;
10685     u16 mer, strength = 0;
10686 
10687     rc = get_sig_strength(demod, &strength);
10688     if (rc < 0) {
10689         pr_err("error getting signal strength %d\n", rc);
10690         p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10691     } else {
10692         p->strength.stat[0].scale = FE_SCALE_RELATIVE;
10693         p->strength.stat[0].uvalue = 65535UL *  strength/ 100;
10694     }
10695 
10696     switch (standard) {
10697     case DRX_STANDARD_8VSB:
10698 #ifdef DRXJ_SIGNAL_ACCUM_ERR
10699         rc = get_acc_pkt_err(demod, &pkt);
10700         if (rc != 0) {
10701             pr_err("error %d\n", rc);
10702             goto rw_error;
10703         }
10704 #endif
10705         if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
10706             p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10707             p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10708             p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10709             p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10710             p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10711             p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10712             p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10713         } else {
10714             rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
10715             if (rc != 0) {
10716                 pr_err("error %d getting UCB\n", rc);
10717                 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10718             } else {
10719                 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
10720                 p->block_error.stat[0].uvalue += err;
10721                 p->block_count.stat[0].scale = FE_SCALE_COUNTER;
10722                 p->block_count.stat[0].uvalue += pkt;
10723             }
10724 
10725             /* PostViterbi is compute in steps of 10^(-6) */
10726             rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
10727             if (rc != 0) {
10728                 pr_err("error %d getting pre-ber\n", rc);
10729                 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10730             } else {
10731                 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10732                 p->pre_bit_error.stat[0].uvalue += ber;
10733                 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10734                 p->pre_bit_count.stat[0].uvalue += cnt;
10735             }
10736 
10737             rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
10738             if (rc != 0) {
10739                 pr_err("error %d getting post-ber\n", rc);
10740                 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10741             } else {
10742                 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10743                 p->post_bit_error.stat[0].uvalue += ber;
10744                 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10745                 p->post_bit_count.stat[0].uvalue += cnt;
10746             }
10747             rc = get_vsbmer(dev_addr, &mer);
10748             if (rc != 0) {
10749                 pr_err("error %d getting MER\n", rc);
10750                 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10751             } else {
10752                 p->cnr.stat[0].svalue = mer * 100;
10753                 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
10754             }
10755         }
10756         break;
10757 #ifndef DRXJ_VSB_ONLY
10758     case DRX_STANDARD_ITU_A:
10759     case DRX_STANDARD_ITU_B:
10760     case DRX_STANDARD_ITU_C:
10761         rc = ctrl_get_qam_sig_quality(demod);
10762         if (rc != 0) {
10763             pr_err("error %d\n", rc);
10764             goto rw_error;
10765         }
10766         break;
10767 #endif
10768     default:
10769         return -EIO;
10770     }
10771 
10772     return 0;
10773 rw_error:
10774     return rc;
10775 }
10776 
10777 /*============================================================================*/
10778 
10779 /*
10780 * \fn int ctrl_lock_status()
10781 * \brief Retrieve lock status .
10782 * \param dev_addr Pointer to demodulator device address.
10783 * \param lock_stat Pointer to lock status structure.
10784 * \return int.
10785 *
10786 */
10787 static int
10788 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
10789 {
10790     enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10791     struct drxj_data *ext_attr = NULL;
10792     struct i2c_device_addr *dev_addr = NULL;
10793     struct drxjscu_cmd cmd_scu = { /* command      */ 0,
10794         /* parameter_len */ 0,
10795         /* result_len    */ 0,
10796         /* *parameter   */ NULL,
10797         /* *result      */ NULL
10798     };
10799     int rc;
10800     u16 cmd_result[2] = { 0, 0 };
10801     u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
10802 
10803     /* check arguments */
10804     if ((demod == NULL) || (lock_stat == NULL))
10805         return -EINVAL;
10806 
10807     dev_addr = demod->my_i2c_dev_addr;
10808     ext_attr = (struct drxj_data *) demod->my_ext_attr;
10809     standard = ext_attr->standard;
10810 
10811     *lock_stat = DRX_NOT_LOCKED;
10812 
10813     /* define the SCU command code */
10814     switch (standard) {
10815     case DRX_STANDARD_8VSB:
10816         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
10817             SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10818         demod_lock |= 0x6;
10819         break;
10820 #ifndef DRXJ_VSB_ONLY
10821     case DRX_STANDARD_ITU_A:
10822     case DRX_STANDARD_ITU_B:
10823     case DRX_STANDARD_ITU_C:
10824         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10825             SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10826         break;
10827 #endif
10828     case DRX_STANDARD_UNKNOWN:
10829     default:
10830         return -EIO;
10831     }
10832 
10833     /* define the SCU command parameters and execute the command */
10834     cmd_scu.parameter_len = 0;
10835     cmd_scu.result_len = 2;
10836     cmd_scu.parameter = NULL;
10837     cmd_scu.result = cmd_result;
10838     rc = scu_command(dev_addr, &cmd_scu);
10839     if (rc != 0) {
10840         pr_err("error %d\n", rc);
10841         goto rw_error;
10842     }
10843 
10844     /* set the lock status */
10845     if (cmd_scu.result[1] < demod_lock) {
10846         /* 0x0000 NOT LOCKED */
10847         *lock_stat = DRX_NOT_LOCKED;
10848     } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
10849         *lock_stat = DRXJ_DEMOD_LOCK;
10850     } else if (cmd_scu.result[1] <
10851            SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
10852         /* 0x8000 DEMOD + FEC LOCKED (system lock) */
10853         *lock_stat = DRX_LOCKED;
10854     } else {
10855         /* 0xC000 NEVER LOCKED */
10856         /* (system will never be able to lock to the signal) */
10857         *lock_stat = DRX_NEVER_LOCK;
10858     }
10859 
10860     return 0;
10861 rw_error:
10862     return rc;
10863 }
10864 
10865 /*============================================================================*/
10866 
10867 /*
10868 * \fn int ctrl_set_standard()
10869 * \brief Set modulation standard to be used.
10870 * \param standard Modulation standard.
10871 * \return int.
10872 *
10873 * Setup stuff for the desired demodulation standard.
10874 * Disable and power down the previous selected demodulation standard
10875 *
10876 */
10877 static int
10878 ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
10879 {
10880     struct drxj_data *ext_attr = NULL;
10881     int rc;
10882     enum drx_standard prev_standard;
10883 
10884     /* check arguments */
10885     if ((standard == NULL) || (demod == NULL))
10886         return -EINVAL;
10887 
10888     ext_attr = (struct drxj_data *) demod->my_ext_attr;
10889     prev_standard = ext_attr->standard;
10890 
10891     /*
10892        Stop and power down previous standard
10893      */
10894     switch (prev_standard) {
10895 #ifndef DRXJ_VSB_ONLY
10896     case DRX_STANDARD_ITU_A:
10897     case DRX_STANDARD_ITU_B:
10898     case DRX_STANDARD_ITU_C:
10899         rc = power_down_qam(demod, false);
10900         if (rc != 0) {
10901             pr_err("error %d\n", rc);
10902             goto rw_error;
10903         }
10904         break;
10905 #endif
10906     case DRX_STANDARD_8VSB:
10907         rc = power_down_vsb(demod, false);
10908         if (rc != 0) {
10909             pr_err("error %d\n", rc);
10910             goto rw_error;
10911         }
10912         break;
10913     case DRX_STANDARD_UNKNOWN:
10914         /* Do nothing */
10915         break;
10916     case DRX_STANDARD_AUTO:
10917     default:
10918         return -EINVAL;
10919     }
10920 
10921     /*
10922        Initialize channel independent registers
10923        Power up new standard
10924      */
10925     ext_attr->standard = *standard;
10926 
10927     switch (*standard) {
10928 #ifndef DRXJ_VSB_ONLY
10929     case DRX_STANDARD_ITU_A:
10930     case DRX_STANDARD_ITU_B:
10931     case DRX_STANDARD_ITU_C:
10932         do {
10933             u16 dummy;
10934             rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
10935             if (rc != 0) {
10936                 pr_err("error %d\n", rc);
10937                 goto rw_error;
10938             }
10939         } while (0);
10940         break;
10941 #endif
10942     case DRX_STANDARD_8VSB:
10943         rc = set_vsb_leak_n_gain(demod);
10944         if (rc != 0) {
10945             pr_err("error %d\n", rc);
10946             goto rw_error;
10947         }
10948         break;
10949     default:
10950         ext_attr->standard = DRX_STANDARD_UNKNOWN;
10951         return -EINVAL;
10952     }
10953 
10954     return 0;
10955 rw_error:
10956     /* Don't know what the standard is now ... try again */
10957     ext_attr->standard = DRX_STANDARD_UNKNOWN;
10958     return rc;
10959 }
10960 
10961 /*============================================================================*/
10962 
10963 static void drxj_reset_mode(struct drxj_data *ext_attr)
10964 {
10965     /* Initialize default AFE configuration for QAM */
10966     if (ext_attr->has_lna) {
10967         /* IF AGC off, PGA active */
10968 #ifndef DRXJ_VSB_ONLY
10969         ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10970         ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10971         ext_attr->qam_pga_cfg = 140 + (11 * 13);
10972 #endif
10973         ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10974         ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10975         ext_attr->vsb_pga_cfg = 140 + (11 * 13);
10976     } else {
10977         /* IF AGC on, PGA not active */
10978 #ifndef DRXJ_VSB_ONLY
10979         ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10980         ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10981         ext_attr->qam_if_agc_cfg.min_output_level = 0;
10982         ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
10983         ext_attr->qam_if_agc_cfg.speed = 3;
10984         ext_attr->qam_if_agc_cfg.top = 1297;
10985         ext_attr->qam_pga_cfg = 140;
10986 #endif
10987         ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10988         ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10989         ext_attr->vsb_if_agc_cfg.min_output_level = 0;
10990         ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
10991         ext_attr->vsb_if_agc_cfg.speed = 3;
10992         ext_attr->vsb_if_agc_cfg.top = 1024;
10993         ext_attr->vsb_pga_cfg = 140;
10994     }
10995     /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
10996     /* mc has not used them */
10997 #ifndef DRXJ_VSB_ONLY
10998     ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
10999     ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11000     ext_attr->qam_rf_agc_cfg.min_output_level = 0;
11001     ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
11002     ext_attr->qam_rf_agc_cfg.speed = 3;
11003     ext_attr->qam_rf_agc_cfg.top = 9500;
11004     ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
11005     ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
11006     ext_attr->qam_pre_saw_cfg.reference = 0x07;
11007     ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
11008 #endif
11009     /* Initialize default AFE configuration for VSB */
11010     ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
11011     ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11012     ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
11013     ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
11014     ext_attr->vsb_rf_agc_cfg.speed = 3;
11015     ext_attr->vsb_rf_agc_cfg.top = 9500;
11016     ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
11017     ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
11018     ext_attr->vsb_pre_saw_cfg.reference = 0x07;
11019     ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
11020 }
11021 
11022 /*
11023 * \fn int ctrl_power_mode()
11024 * \brief Set the power mode of the device to the specified power mode
11025 * \param demod Pointer to demodulator instance.
11026 * \param mode  Pointer to new power mode.
11027 * \return int.
11028 * \retval 0          Success
11029 * \retval -EIO       I2C error or other failure
11030 * \retval -EINVAL Invalid mode argument.
11031 *
11032 *
11033 */
11034 static int
11035 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
11036 {
11037     struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
11038     struct drxj_data *ext_attr = (struct drxj_data *) NULL;
11039     struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
11040     int rc;
11041     u16 sio_cc_pwd_mode = 0;
11042 
11043     common_attr = (struct drx_common_attr *) demod->my_common_attr;
11044     ext_attr = (struct drxj_data *) demod->my_ext_attr;
11045     dev_addr = demod->my_i2c_dev_addr;
11046 
11047     /* Check arguments */
11048     if (mode == NULL)
11049         return -EINVAL;
11050 
11051     /* If already in requested power mode, do nothing */
11052     if (common_attr->current_power_mode == *mode)
11053         return 0;
11054 
11055     switch (*mode) {
11056     case DRX_POWER_UP:
11057     case DRXJ_POWER_DOWN_MAIN_PATH:
11058         sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
11059         break;
11060     case DRXJ_POWER_DOWN_CORE:
11061         sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
11062         break;
11063     case DRXJ_POWER_DOWN_PLL:
11064         sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
11065         break;
11066     case DRX_POWER_DOWN:
11067         sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
11068         break;
11069     default:
11070         /* Unknow sleep mode */
11071         return -EINVAL;
11072     }
11073 
11074     /* Check if device needs to be powered up */
11075     if ((common_attr->current_power_mode != DRX_POWER_UP)) {
11076         rc = power_up_device(demod);
11077         if (rc != 0) {
11078             pr_err("error %d\n", rc);
11079             goto rw_error;
11080         }
11081     }
11082 
11083     if (*mode == DRX_POWER_UP) {
11084         /* Restore analog & pin configuration */
11085 
11086         /* Initialize default AFE configuration for VSB */
11087         drxj_reset_mode(ext_attr);
11088     } else {
11089         /* Power down to requested mode */
11090         /* Backup some register settings */
11091         /* Set pins with possible pull-ups connected to them in input mode */
11092         /* Analog power down */
11093         /* ADC power down */
11094         /* Power down device */
11095         /* stop all comm_exec */
11096         /*
11097            Stop and power down previous standard
11098          */
11099 
11100         switch (ext_attr->standard) {
11101         case DRX_STANDARD_ITU_A:
11102         case DRX_STANDARD_ITU_B:
11103         case DRX_STANDARD_ITU_C:
11104             rc = power_down_qam(demod, true);
11105             if (rc != 0) {
11106                 pr_err("error %d\n", rc);
11107                 goto rw_error;
11108             }
11109             break;
11110         case DRX_STANDARD_8VSB:
11111             rc = power_down_vsb(demod, true);
11112             if (rc != 0) {
11113                 pr_err("error %d\n", rc);
11114                 goto rw_error;
11115             }
11116             break;
11117         case DRX_STANDARD_PAL_SECAM_BG:
11118         case DRX_STANDARD_PAL_SECAM_DK:
11119         case DRX_STANDARD_PAL_SECAM_I:
11120         case DRX_STANDARD_PAL_SECAM_L:
11121         case DRX_STANDARD_PAL_SECAM_LP:
11122         case DRX_STANDARD_NTSC:
11123         case DRX_STANDARD_FM:
11124             rc = power_down_atv(demod, ext_attr->standard, true);
11125             if (rc != 0) {
11126                 pr_err("error %d\n", rc);
11127                 goto rw_error;
11128             }
11129             break;
11130         case DRX_STANDARD_UNKNOWN:
11131             /* Do nothing */
11132             break;
11133         case DRX_STANDARD_AUTO:
11134         default:
11135             return -EIO;
11136         }
11137         ext_attr->standard = DRX_STANDARD_UNKNOWN;
11138     }
11139 
11140     if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
11141         rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
11142         if (rc != 0) {
11143             pr_err("error %d\n", rc);
11144             goto rw_error;
11145         }
11146         rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11147         if (rc != 0) {
11148             pr_err("error %d\n", rc);
11149             goto rw_error;
11150         }
11151 
11152         if ((*mode != DRX_POWER_UP)) {
11153             /* Initialize HI, wakeup key especially before put IC to sleep */
11154             rc = init_hi(demod);
11155             if (rc != 0) {
11156                 pr_err("error %d\n", rc);
11157                 goto rw_error;
11158             }
11159 
11160             ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
11161             rc = hi_cfg_command(demod);
11162             if (rc != 0) {
11163                 pr_err("error %d\n", rc);
11164                 goto rw_error;
11165             }
11166         }
11167     }
11168 
11169     common_attr->current_power_mode = *mode;
11170 
11171     return 0;
11172 rw_error:
11173     return rc;
11174 }
11175 
11176 /*============================================================================*/
11177 /*== CTRL Set/Get Config related functions ===================================*/
11178 /*============================================================================*/
11179 
11180 /*
11181 * \fn int ctrl_set_cfg_pre_saw()
11182 * \brief Set Pre-saw reference.
11183 * \param demod demod instance
11184 * \param u16 *
11185 * \return int.
11186 *
11187 * Check arguments
11188 * Dispatch handling to standard specific function.
11189 *
11190 */
11191 static int
11192 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
11193 {
11194     struct i2c_device_addr *dev_addr = NULL;
11195     struct drxj_data *ext_attr = NULL;
11196     int rc;
11197 
11198     dev_addr = demod->my_i2c_dev_addr;
11199     ext_attr = (struct drxj_data *) demod->my_ext_attr;
11200 
11201     /* check arguments */
11202     if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
11203         ) {
11204         return -EINVAL;
11205     }
11206 
11207     /* Only if standard is currently active */
11208     if ((ext_attr->standard == pre_saw->standard) ||
11209         (DRXJ_ISQAMSTD(ext_attr->standard) &&
11210          DRXJ_ISQAMSTD(pre_saw->standard)) ||
11211         (DRXJ_ISATVSTD(ext_attr->standard) &&
11212          DRXJ_ISATVSTD(pre_saw->standard))) {
11213         rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
11214         if (rc != 0) {
11215             pr_err("error %d\n", rc);
11216             goto rw_error;
11217         }
11218     }
11219 
11220     /* Store pre-saw settings */
11221     switch (pre_saw->standard) {
11222     case DRX_STANDARD_8VSB:
11223         ext_attr->vsb_pre_saw_cfg = *pre_saw;
11224         break;
11225 #ifndef DRXJ_VSB_ONLY
11226     case DRX_STANDARD_ITU_A:
11227     case DRX_STANDARD_ITU_B:
11228     case DRX_STANDARD_ITU_C:
11229         ext_attr->qam_pre_saw_cfg = *pre_saw;
11230         break;
11231 #endif
11232     default:
11233         return -EINVAL;
11234     }
11235 
11236     return 0;
11237 rw_error:
11238     return rc;
11239 }
11240 
11241 /*============================================================================*/
11242 
11243 /*
11244 * \fn int ctrl_set_cfg_afe_gain()
11245 * \brief Set AFE Gain.
11246 * \param demod demod instance
11247 * \param u16 *
11248 * \return int.
11249 *
11250 * Check arguments
11251 * Dispatch handling to standard specific function.
11252 *
11253 */
11254 static int
11255 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
11256 {
11257     struct i2c_device_addr *dev_addr = NULL;
11258     struct drxj_data *ext_attr = NULL;
11259     int rc;
11260     u8 gain = 0;
11261 
11262     /* check arguments */
11263     if (afe_gain == NULL)
11264         return -EINVAL;
11265 
11266     dev_addr = demod->my_i2c_dev_addr;
11267     ext_attr = (struct drxj_data *) demod->my_ext_attr;
11268 
11269     switch (afe_gain->standard) {
11270     case DRX_STANDARD_8VSB: fallthrough;
11271 #ifndef DRXJ_VSB_ONLY
11272     case DRX_STANDARD_ITU_A:
11273     case DRX_STANDARD_ITU_B:
11274     case DRX_STANDARD_ITU_C:
11275 #endif
11276         /* Do nothing */
11277         break;
11278     default:
11279         return -EINVAL;
11280     }
11281 
11282     /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
11283        So I (PJ) think interface requires choice between auto, user mode */
11284 
11285     if (afe_gain->gain >= 329)
11286         gain = 15;
11287     else if (afe_gain->gain <= 147)
11288         gain = 0;
11289     else
11290         gain = (afe_gain->gain - 140 + 6) / 13;
11291 
11292     /* Only if standard is currently active */
11293     if (ext_attr->standard == afe_gain->standard) {
11294             rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
11295             if (rc != 0) {
11296                 pr_err("error %d\n", rc);
11297                 goto rw_error;
11298             }
11299         }
11300 
11301     /* Store AFE Gain settings */
11302     switch (afe_gain->standard) {
11303     case DRX_STANDARD_8VSB:
11304         ext_attr->vsb_pga_cfg = gain * 13 + 140;
11305         break;
11306 #ifndef DRXJ_VSB_ONLY
11307     case DRX_STANDARD_ITU_A:
11308     case DRX_STANDARD_ITU_B:
11309     case DRX_STANDARD_ITU_C:
11310         ext_attr->qam_pga_cfg = gain * 13 + 140;
11311         break;
11312 #endif
11313     default:
11314         return -EIO;
11315     }
11316 
11317     return 0;
11318 rw_error:
11319     return rc;
11320 }
11321 
11322 /*============================================================================*/
11323 
11324 
11325 /*=============================================================================
11326 ===== EXPORTED FUNCTIONS ====================================================*/
11327 
11328 static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11329                struct drxu_code_info *mc_info,
11330                enum drxu_code_action action);
11331 static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
11332 
11333 /*
11334 * \fn drxj_open()
11335 * \brief Open the demod instance, configure device, configure drxdriver
11336 * \return Status_t Return status.
11337 *
11338 * drxj_open() can be called with a NULL ucode image => no ucode upload.
11339 * This means that drxj_open() must NOT contain SCU commands or, in general,
11340 * rely on SCU or AUD ucode to be present.
11341 *
11342 */
11343 
11344 static int drxj_open(struct drx_demod_instance *demod)
11345 {
11346     struct i2c_device_addr *dev_addr = NULL;
11347     struct drxj_data *ext_attr = NULL;
11348     struct drx_common_attr *common_attr = NULL;
11349     u32 driver_version = 0;
11350     struct drxu_code_info ucode_info;
11351     struct drx_cfg_mpeg_output cfg_mpeg_output;
11352     int rc;
11353     enum drx_power_mode power_mode = DRX_POWER_UP;
11354 
11355     if ((demod == NULL) ||
11356         (demod->my_common_attr == NULL) ||
11357         (demod->my_ext_attr == NULL) ||
11358         (demod->my_i2c_dev_addr == NULL) ||
11359         (demod->my_common_attr->is_opened)) {
11360         return -EINVAL;
11361     }
11362 
11363     /* Check arguments */
11364     if (demod->my_ext_attr == NULL)
11365         return -EINVAL;
11366 
11367     dev_addr = demod->my_i2c_dev_addr;
11368     ext_attr = (struct drxj_data *) demod->my_ext_attr;
11369     common_attr = (struct drx_common_attr *) demod->my_common_attr;
11370 
11371     rc = ctrl_power_mode(demod, &power_mode);
11372     if (rc != 0) {
11373         pr_err("error %d\n", rc);
11374         goto rw_error;
11375     }
11376     if (power_mode != DRX_POWER_UP) {
11377         rc = -EINVAL;
11378         pr_err("failed to powerup device\n");
11379         goto rw_error;
11380     }
11381 
11382     /* has to be in front of setIqmAf and setOrxNsuAox */
11383     rc = get_device_capabilities(demod);
11384     if (rc != 0) {
11385         pr_err("error %d\n", rc);
11386         goto rw_error;
11387     }
11388 
11389     /*
11390      * Soft reset of sys- and osc-clockdomain
11391      *
11392      * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
11393      * As we didn't load the firmware here yet, we should do the same.
11394      * Btw, this is coherent with DRX-K, where we send reset codes
11395      * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
11396      */
11397     rc = drxj_dap_write_reg16(dev_addr, SIO_CC_SOFT_RST__A, (0x04 | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
11398     if (rc != 0) {
11399         pr_err("error %d\n", rc);
11400         goto rw_error;
11401     }
11402     rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11403     if (rc != 0) {
11404         pr_err("error %d\n", rc);
11405         goto rw_error;
11406     }
11407     msleep(1);
11408 
11409     /* TODO first make sure that everything keeps working before enabling this */
11410     /* PowerDownAnalogBlocks() */
11411     rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
11412     if (rc != 0) {
11413         pr_err("error %d\n", rc);
11414         goto rw_error;
11415     }
11416 
11417     rc = set_iqm_af(demod, false);
11418     if (rc != 0) {
11419         pr_err("error %d\n", rc);
11420         goto rw_error;
11421     }
11422     rc = set_orx_nsu_aox(demod, false);
11423     if (rc != 0) {
11424         pr_err("error %d\n", rc);
11425         goto rw_error;
11426     }
11427 
11428     rc = init_hi(demod);
11429     if (rc != 0) {
11430         pr_err("error %d\n", rc);
11431         goto rw_error;
11432     }
11433 
11434     /* disable mpegoutput pins */
11435     memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
11436     cfg_mpeg_output.enable_mpeg_output = false;
11437 
11438     rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
11439     if (rc != 0) {
11440         pr_err("error %d\n", rc);
11441         goto rw_error;
11442     }
11443     /* Stop AUD Inform SetAudio it will need to do all setting */
11444     rc = power_down_aud(demod);
11445     if (rc != 0) {
11446         pr_err("error %d\n", rc);
11447         goto rw_error;
11448     }
11449     /* Stop SCU */
11450     rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
11451     if (rc != 0) {
11452         pr_err("error %d\n", rc);
11453         goto rw_error;
11454     }
11455 
11456     /* Upload microcode */
11457     if (common_attr->microcode_file != NULL) {
11458         /* Dirty trick to use common ucode upload & verify,
11459            pretend device is already open */
11460         common_attr->is_opened = true;
11461         ucode_info.mc_file = common_attr->microcode_file;
11462 
11463         if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
11464             pr_err("Should powerup before loading the firmware.");
11465             return -EINVAL;
11466         }
11467 
11468         rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
11469         if (rc != 0) {
11470             pr_err("error %d while uploading the firmware\n", rc);
11471             goto rw_error;
11472         }
11473         if (common_attr->verify_microcode == true) {
11474             rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);
11475             if (rc != 0) {
11476                 pr_err("error %d while verifying the firmware\n",
11477                        rc);
11478                 goto rw_error;
11479             }
11480         }
11481         common_attr->is_opened = false;
11482     }
11483 
11484     /* Run SCU for a little while to initialize microcode version numbers */
11485     rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
11486     if (rc != 0) {
11487         pr_err("error %d\n", rc);
11488         goto rw_error;
11489     }
11490 
11491     /* Initialize scan timeout */
11492     common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
11493     common_attr->scan_desired_lock = DRX_LOCKED;
11494 
11495     drxj_reset_mode(ext_attr);
11496     ext_attr->standard = DRX_STANDARD_UNKNOWN;
11497 
11498     rc = smart_ant_init(demod);
11499     if (rc != 0) {
11500         pr_err("error %d\n", rc);
11501         goto rw_error;
11502     }
11503 
11504     /* Stamp driver version number in SCU data RAM in BCD code
11505        Done to enable field application engineers to retrieve drxdriver version
11506        via I2C from SCU RAM
11507      */
11508     driver_version = (VERSION_MAJOR / 100) % 10;
11509     driver_version <<= 4;
11510     driver_version += (VERSION_MAJOR / 10) % 10;
11511     driver_version <<= 4;
11512     driver_version += (VERSION_MAJOR % 10);
11513     driver_version <<= 4;
11514     driver_version += (VERSION_MINOR % 10);
11515     driver_version <<= 4;
11516     driver_version += (VERSION_PATCH / 1000) % 10;
11517     driver_version <<= 4;
11518     driver_version += (VERSION_PATCH / 100) % 10;
11519     driver_version <<= 4;
11520     driver_version += (VERSION_PATCH / 10) % 10;
11521     driver_version <<= 4;
11522     driver_version += (VERSION_PATCH % 10);
11523     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
11524     if (rc != 0) {
11525         pr_err("error %d\n", rc);
11526         goto rw_error;
11527     }
11528     rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
11529     if (rc != 0) {
11530         pr_err("error %d\n", rc);
11531         goto rw_error;
11532     }
11533 
11534     rc = ctrl_set_oob(demod, NULL);
11535     if (rc != 0) {
11536         pr_err("error %d\n", rc);
11537         goto rw_error;
11538     }
11539 
11540     /* refresh the audio data structure with default */
11541     ext_attr->aud_data = drxj_default_aud_data_g;
11542 
11543     demod->my_common_attr->is_opened = true;
11544     drxj_set_lna_state(demod, false);
11545     return 0;
11546 rw_error:
11547     common_attr->is_opened = false;
11548     return rc;
11549 }
11550 
11551 /*============================================================================*/
11552 /*
11553 * \fn drxj_close()
11554 * \brief Close the demod instance, power down the device
11555 * \return Status_t Return status.
11556 *
11557 */
11558 static int drxj_close(struct drx_demod_instance *demod)
11559 {
11560     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11561     int rc;
11562     enum drx_power_mode power_mode = DRX_POWER_UP;
11563 
11564     if ((demod->my_common_attr == NULL) ||
11565         (demod->my_ext_attr == NULL) ||
11566         (demod->my_i2c_dev_addr == NULL) ||
11567         (!demod->my_common_attr->is_opened)) {
11568         return -EINVAL;
11569     }
11570 
11571     /* power up */
11572     rc = ctrl_power_mode(demod, &power_mode);
11573     if (rc != 0) {
11574         pr_err("error %d\n", rc);
11575         goto rw_error;
11576     }
11577 
11578     rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
11579     if (rc != 0) {
11580         pr_err("error %d\n", rc);
11581         goto rw_error;
11582     }
11583     power_mode = DRX_POWER_DOWN;
11584     rc = ctrl_power_mode(demod, &power_mode);
11585     if (rc != 0) {
11586         pr_err("error %d\n", rc);
11587         goto rw_error;
11588     }
11589 
11590     DRX_ATTR_ISOPENED(demod) = false;
11591 
11592     return 0;
11593 rw_error:
11594     DRX_ATTR_ISOPENED(demod) = false;
11595 
11596     return rc;
11597 }
11598 
11599 /*
11600  * Microcode related functions
11601  */
11602 
11603 /*
11604  * drx_u_code_compute_crc   - Compute CRC of block of microcode data.
11605  * @block_data: Pointer to microcode data.
11606  * @nr_words:   Size of microcode block (number of 16 bits words).
11607  *
11608  * returns The computed CRC residue.
11609  */
11610 static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
11611 {
11612     u16 i = 0;
11613     u16 j = 0;
11614     u32 crc_word = 0;
11615     u32 carry = 0;
11616 
11617     while (i < nr_words) {
11618         crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
11619         for (j = 0; j < 16; j++) {
11620             crc_word <<= 1;
11621             if (carry != 0)
11622                 crc_word ^= 0x80050000UL;
11623             carry = crc_word & 0x80000000UL;
11624         }
11625         i++;
11626         block_data += (sizeof(u16));
11627     }
11628     return (u16)(crc_word >> 16);
11629 }
11630 
11631 /*
11632  * drx_check_firmware - checks if the loaded firmware is valid
11633  *
11634  * @demod:  demod structure
11635  * @mc_data:    pointer to the start of the firmware
11636  * @size:   firmware size
11637  */
11638 static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
11639               unsigned size)
11640 {
11641     struct drxu_code_block_hdr block_hdr;
11642     int i;
11643     unsigned count = 2 * sizeof(u16);
11644     u32 mc_dev_type, mc_version, mc_base_version;
11645     u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
11646 
11647     /*
11648      * Scan microcode blocks first for version info
11649      * and firmware check
11650      */
11651 
11652     /* Clear version block */
11653     DRX_ATTR_MCRECORD(demod).aux_type = 0;
11654     DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
11655     DRX_ATTR_MCRECORD(demod).mc_version = 0;
11656     DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
11657 
11658     for (i = 0; i < mc_nr_of_blks; i++) {
11659         if (count + 3 * sizeof(u16) + sizeof(u32) > size)
11660             goto eof;
11661 
11662         /* Process block header */
11663         block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
11664         count += sizeof(u32);
11665         block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
11666         count += sizeof(u16);
11667         block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
11668         count += sizeof(u16);
11669         block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
11670         count += sizeof(u16);
11671 
11672         pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11673             count, block_hdr.addr, block_hdr.size, block_hdr.flags,
11674             block_hdr.CRC);
11675 
11676         if (block_hdr.flags & 0x8) {
11677             u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
11678             u16 auxtype;
11679 
11680             if (block_hdr.addr + sizeof(u16) > size)
11681                 goto eof;
11682 
11683             auxtype = be16_to_cpu(*(__be16 *)(auxblk));
11684 
11685             /* Aux block. Check type */
11686             if (DRX_ISMCVERTYPE(auxtype)) {
11687                 if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
11688                     goto eof;
11689 
11690                 auxblk += sizeof(u16);
11691                 mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
11692                 auxblk += sizeof(u32);
11693                 mc_version = be32_to_cpu(*(__be32 *)(auxblk));
11694                 auxblk += sizeof(u32);
11695                 mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
11696 
11697                 DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
11698                 DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
11699                 DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
11700                 DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
11701 
11702                 pr_info("Firmware dev %x, ver %x, base ver %x\n",
11703                     mc_dev_type, mc_version, mc_base_version);
11704 
11705             }
11706         } else if (count + block_hdr.size * sizeof(u16) > size)
11707             goto eof;
11708 
11709         count += block_hdr.size * sizeof(u16);
11710     }
11711     return 0;
11712 eof:
11713     pr_err("Firmware is truncated at pos %u/%u\n", count, size);
11714     return -EINVAL;
11715 }
11716 
11717 /*
11718  * drx_ctrl_u_code - Handle microcode upload or verify.
11719  * @dev_addr: Address of device.
11720  * @mc_info:  Pointer to information about microcode data.
11721  * @action:  Either UCODE_UPLOAD or UCODE_VERIFY
11722  *
11723  * This function returns:
11724  *  0:
11725  *      - In case of UCODE_UPLOAD: code is successfully uploaded.
11726  *               - In case of UCODE_VERIFY: image on device is equal to
11727  *        image provided to this control function.
11728  *  -EIO:
11729  *      - In case of UCODE_UPLOAD: I2C error.
11730  *      - In case of UCODE_VERIFY: I2C error or image on device
11731  *        is not equal to image provided to this control function.
11732  *  -EINVAL:
11733  *      - Invalid arguments.
11734  *      - Provided image is corrupt
11735  */
11736 static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11737                struct drxu_code_info *mc_info,
11738                enum drxu_code_action action)
11739 {
11740     struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11741     int rc;
11742     u16 i = 0;
11743     u16 mc_nr_of_blks = 0;
11744     u16 mc_magic_word = 0;
11745     const u8 *mc_data_init = NULL;
11746     u8 *mc_data = NULL;
11747     unsigned size;
11748     char *mc_file;
11749 
11750     /* Check arguments */
11751     if (!mc_info || !mc_info->mc_file)
11752         return -EINVAL;
11753 
11754     mc_file = mc_info->mc_file;
11755 
11756     if (!demod->firmware) {
11757         const struct firmware *fw = NULL;
11758 
11759         rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
11760         if (rc < 0) {
11761             pr_err("Couldn't read firmware %s\n", mc_file);
11762             return rc;
11763         }
11764         demod->firmware = fw;
11765 
11766         if (demod->firmware->size < 2 * sizeof(u16)) {
11767             rc = -EINVAL;
11768             pr_err("Firmware is too short!\n");
11769             goto release;
11770         }
11771 
11772         pr_info("Firmware %s, size %zu\n",
11773             mc_file, demod->firmware->size);
11774     }
11775 
11776     mc_data_init = demod->firmware->data;
11777     size = demod->firmware->size;
11778 
11779     mc_data = (void *)mc_data_init;
11780     /* Check data */
11781     mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
11782     mc_data += sizeof(u16);
11783     mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
11784     mc_data += sizeof(u16);
11785 
11786     if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
11787         rc = -EINVAL;
11788         pr_err("Firmware magic word doesn't match\n");
11789         goto release;
11790     }
11791 
11792     if (action == UCODE_UPLOAD) {
11793         rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
11794         if (rc)
11795             goto release;
11796         pr_info("Uploading firmware %s\n", mc_file);
11797     } else {
11798         pr_info("Verifying if firmware upload was ok.\n");
11799     }
11800 
11801     /* Process microcode blocks */
11802     for (i = 0; i < mc_nr_of_blks; i++) {
11803         struct drxu_code_block_hdr block_hdr;
11804         u16 mc_block_nr_bytes = 0;
11805 
11806         /* Process block header */
11807         block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
11808         mc_data += sizeof(u32);
11809         block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
11810         mc_data += sizeof(u16);
11811         block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
11812         mc_data += sizeof(u16);
11813         block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
11814         mc_data += sizeof(u16);
11815 
11816         pr_debug("%zd: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11817             (mc_data - mc_data_init), block_hdr.addr,
11818              block_hdr.size, block_hdr.flags, block_hdr.CRC);
11819 
11820         /* Check block header on:
11821            - data larger than 64Kb
11822            - if CRC enabled check CRC
11823          */
11824         if ((block_hdr.size > 0x7FFF) ||
11825             (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
11826              (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
11827             ) {
11828             /* Wrong data ! */
11829             rc = -EINVAL;
11830             pr_err("firmware CRC is wrong\n");
11831             goto release;
11832         }
11833 
11834         if (!block_hdr.size)
11835             continue;
11836 
11837         mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
11838 
11839         /* Perform the desired action */
11840         switch (action) {
11841         case UCODE_UPLOAD:  /* Upload microcode */
11842             if (drxdap_fasi_write_block(dev_addr,
11843                             block_hdr.addr,
11844                             mc_block_nr_bytes,
11845                             mc_data, 0x0000)) {
11846                 rc = -EIO;
11847                 pr_err("error writing firmware at pos %zd\n",
11848                        mc_data - mc_data_init);
11849                 goto release;
11850             }
11851             break;
11852         case UCODE_VERIFY: {    /* Verify uploaded microcode */
11853             int result = 0;
11854             u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
11855             u32 bytes_to_comp = 0;
11856             u32 bytes_left = mc_block_nr_bytes;
11857             u32 curr_addr = block_hdr.addr;
11858             u8 *curr_ptr = mc_data;
11859 
11860             while (bytes_left != 0) {
11861                 if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
11862                     bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
11863                 else
11864                     bytes_to_comp = bytes_left;
11865 
11866                 if (drxdap_fasi_read_block(dev_addr,
11867                             curr_addr,
11868                             (u16)bytes_to_comp,
11869                             (u8 *)mc_data_buffer,
11870                             0x0000)) {
11871                     pr_err("error reading firmware at pos %zd\n",
11872                            mc_data - mc_data_init);
11873                     return -EIO;
11874                 }
11875 
11876                 result = memcmp(curr_ptr, mc_data_buffer,
11877                         bytes_to_comp);
11878 
11879                 if (result) {
11880                     pr_err("error verifying firmware at pos %zd\n",
11881                            mc_data - mc_data_init);
11882                     return -EIO;
11883                 }
11884 
11885                 curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
11886                 curr_ptr =&(curr_ptr[bytes_to_comp]);
11887                 bytes_left -=((u32) bytes_to_comp);
11888             }
11889             break;
11890         }
11891         default:
11892             return -EINVAL;
11893 
11894         }
11895         mc_data += mc_block_nr_bytes;
11896     }
11897 
11898     return 0;
11899 
11900 release:
11901     release_firmware(demod->firmware);
11902     demod->firmware = NULL;
11903 
11904     return rc;
11905 }
11906 
11907 /* caller is expected to check if lna is supported before enabling */
11908 static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
11909 {
11910     struct drxuio_cfg uio_cfg;
11911     struct drxuio_data uio_data;
11912     int result;
11913 
11914     uio_cfg.uio = DRX_UIO1;
11915     uio_cfg.mode = DRX_UIO_MODE_READWRITE;
11916     /* Configure user-I/O #3: enable read/write */
11917     result = ctrl_set_uio_cfg(demod, &uio_cfg);
11918     if (result) {
11919         pr_err("Failed to setup LNA GPIO!\n");
11920         return result;
11921     }
11922 
11923     uio_data.uio = DRX_UIO1;
11924     uio_data.value = state;
11925     result = ctrl_uio_write(demod, &uio_data);
11926     if (result != 0) {
11927         pr_err("Failed to %sable LNA!\n",
11928                state ? "en" : "dis");
11929         return result;
11930     }
11931     return 0;
11932 }
11933 
11934 /*
11935  * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
11936  *
11937  * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
11938  */
11939 
11940 static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
11941 {
11942     struct drx39xxj_state *state = fe->demodulator_priv;
11943     struct drx_demod_instance *demod = state->demod;
11944     int result;
11945     enum drx_power_mode power_mode;
11946 
11947     if (enable)
11948         power_mode = DRX_POWER_UP;
11949     else
11950         power_mode = DRX_POWER_DOWN;
11951 
11952     result = ctrl_power_mode(demod, &power_mode);
11953     if (result != 0) {
11954         pr_err("Power state change failed\n");
11955         return 0;
11956     }
11957 
11958     return 0;
11959 }
11960 
11961 static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
11962 {
11963     struct drx39xxj_state *state = fe->demodulator_priv;
11964     struct drx_demod_instance *demod = state->demod;
11965     int result;
11966     enum drx_lock_status lock_status;
11967 
11968     *status = 0;
11969 
11970     result = ctrl_lock_status(demod, &lock_status);
11971     if (result != 0) {
11972         pr_err("drx39xxj: could not get lock status!\n");
11973         *status = 0;
11974     }
11975 
11976     switch (lock_status) {
11977     case DRX_NEVER_LOCK:
11978         *status = 0;
11979         pr_err("drx says NEVER_LOCK\n");
11980         break;
11981     case DRX_NOT_LOCKED:
11982         *status = 0;
11983         break;
11984     case DRX_LOCK_STATE_1:
11985     case DRX_LOCK_STATE_2:
11986     case DRX_LOCK_STATE_3:
11987     case DRX_LOCK_STATE_4:
11988     case DRX_LOCK_STATE_5:
11989     case DRX_LOCK_STATE_6:
11990     case DRX_LOCK_STATE_7:
11991     case DRX_LOCK_STATE_8:
11992     case DRX_LOCK_STATE_9:
11993         *status = FE_HAS_SIGNAL
11994             | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
11995         break;
11996     case DRX_LOCKED:
11997         *status = FE_HAS_SIGNAL
11998             | FE_HAS_CARRIER
11999             | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
12000         break;
12001     default:
12002         pr_err("Lock state unknown %d\n", lock_status);
12003     }
12004     ctrl_sig_quality(demod, lock_status);
12005 
12006     return 0;
12007 }
12008 
12009 static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
12010 {
12011     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12012 
12013     if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12014         *ber = 0;
12015         return 0;
12016     }
12017 
12018     if (!p->pre_bit_count.stat[0].uvalue) {
12019         if (!p->pre_bit_error.stat[0].uvalue)
12020             *ber = 0;
12021         else
12022             *ber = 1000000;
12023     } else {
12024         *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
12025                      p->pre_bit_count.stat[0].uvalue);
12026     }
12027     return 0;
12028 }
12029 
12030 static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
12031                      u16 *strength)
12032 {
12033     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12034 
12035     if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12036         *strength = 0;
12037         return 0;
12038     }
12039 
12040     *strength = p->strength.stat[0].uvalue;
12041     return 0;
12042 }
12043 
12044 static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
12045 {
12046     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12047     u64 tmp64;
12048 
12049     if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12050         *snr = 0;
12051         return 0;
12052     }
12053 
12054     tmp64 = p->cnr.stat[0].svalue;
12055     do_div(tmp64, 10);
12056     *snr = tmp64;
12057     return 0;
12058 }
12059 
12060 static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
12061 {
12062     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12063 
12064     if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12065         *ucb = 0;
12066         return 0;
12067     }
12068 
12069     *ucb = p->block_error.stat[0].uvalue;
12070     return 0;
12071 }
12072 
12073 static int drx39xxj_set_frontend(struct dvb_frontend *fe)
12074 {
12075 #ifdef DJH_DEBUG
12076     int i;
12077 #endif
12078     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12079     struct drx39xxj_state *state = fe->demodulator_priv;
12080     struct drx_demod_instance *demod = state->demod;
12081     enum drx_standard standard = DRX_STANDARD_8VSB;
12082     struct drx_channel channel;
12083     int result;
12084     static const struct drx_channel def_channel = {
12085         /* frequency      */ 0,
12086         /* bandwidth      */ DRX_BANDWIDTH_6MHZ,
12087         /* mirror         */ DRX_MIRROR_NO,
12088         /* constellation  */ DRX_CONSTELLATION_AUTO,
12089         /* hierarchy      */ DRX_HIERARCHY_UNKNOWN,
12090         /* priority       */ DRX_PRIORITY_UNKNOWN,
12091         /* coderate       */ DRX_CODERATE_UNKNOWN,
12092         /* guard          */ DRX_GUARD_UNKNOWN,
12093         /* fftmode        */ DRX_FFTMODE_UNKNOWN,
12094         /* classification */ DRX_CLASSIFICATION_AUTO,
12095         /* symbolrate     */ 5057000,
12096         /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
12097         /* ldpc           */ DRX_LDPC_UNKNOWN,
12098         /* carrier        */ DRX_CARRIER_UNKNOWN,
12099         /* frame mode     */ DRX_FRAMEMODE_UNKNOWN
12100     };
12101     u32 constellation = DRX_CONSTELLATION_AUTO;
12102 
12103     /* Bring the demod out of sleep */
12104     drx39xxj_set_powerstate(fe, 1);
12105 
12106     if (fe->ops.tuner_ops.set_params) {
12107         u32 int_freq;
12108 
12109         if (fe->ops.i2c_gate_ctrl)
12110             fe->ops.i2c_gate_ctrl(fe, 1);
12111 
12112         /* Set tuner to desired frequency and standard */
12113         fe->ops.tuner_ops.set_params(fe);
12114 
12115         /* Use the tuner's IF */
12116         if (fe->ops.tuner_ops.get_if_frequency) {
12117             fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
12118             demod->my_common_attr->intermediate_freq = int_freq / 1000;
12119         }
12120 
12121         if (fe->ops.i2c_gate_ctrl)
12122             fe->ops.i2c_gate_ctrl(fe, 0);
12123     }
12124 
12125     switch (p->delivery_system) {
12126     case SYS_ATSC:
12127         standard = DRX_STANDARD_8VSB;
12128         break;
12129     case SYS_DVBC_ANNEX_B:
12130         standard = DRX_STANDARD_ITU_B;
12131 
12132         switch (p->modulation) {
12133         case QAM_64:
12134             constellation = DRX_CONSTELLATION_QAM64;
12135             break;
12136         case QAM_256:
12137             constellation = DRX_CONSTELLATION_QAM256;
12138             break;
12139         default:
12140             constellation = DRX_CONSTELLATION_AUTO;
12141             break;
12142         }
12143         break;
12144     default:
12145         return -EINVAL;
12146     }
12147     /* Set the standard (will be powered up if necessary */
12148     result = ctrl_set_standard(demod, &standard);
12149     if (result != 0) {
12150         pr_err("Failed to set standard! result=%02x\n",
12151             result);
12152         return -EINVAL;
12153     }
12154 
12155     /* set channel parameters */
12156     channel = def_channel;
12157     channel.frequency = p->frequency / 1000;
12158     channel.bandwidth = DRX_BANDWIDTH_6MHZ;
12159     channel.constellation = constellation;
12160 
12161     /* program channel */
12162     result = ctrl_set_channel(demod, &channel);
12163     if (result != 0) {
12164         pr_err("Failed to set channel!\n");
12165         return -EINVAL;
12166     }
12167     /* Just for giggles, let's shut off the LNA again.... */
12168     drxj_set_lna_state(demod, false);
12169 
12170     /* After set_frontend, except for strength, stats aren't available */
12171     p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12172 
12173     return 0;
12174 }
12175 
12176 static int drx39xxj_sleep(struct dvb_frontend *fe)
12177 {
12178     /* power-down the demodulator */
12179     return drx39xxj_set_powerstate(fe, 0);
12180 }
12181 
12182 static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
12183 {
12184     struct drx39xxj_state *state = fe->demodulator_priv;
12185     struct drx_demod_instance *demod = state->demod;
12186     bool i2c_gate_state;
12187     int result;
12188 
12189 #ifdef DJH_DEBUG
12190     pr_debug("i2c gate call: enable=%d state=%d\n", enable,
12191            state->i2c_gate_open);
12192 #endif
12193 
12194     if (enable)
12195         i2c_gate_state = true;
12196     else
12197         i2c_gate_state = false;
12198 
12199     if (state->i2c_gate_open == enable) {
12200         /* We're already in the desired state */
12201         return 0;
12202     }
12203 
12204     result = ctrl_i2c_bridge(demod, &i2c_gate_state);
12205     if (result != 0) {
12206         pr_err("drx39xxj: could not open i2c gate [%d]\n",
12207                result);
12208         dump_stack();
12209     } else {
12210         state->i2c_gate_open = enable;
12211     }
12212     return 0;
12213 }
12214 
12215 static int drx39xxj_init(struct dvb_frontend *fe)
12216 {
12217     struct drx39xxj_state *state = fe->demodulator_priv;
12218     struct drx_demod_instance *demod = state->demod;
12219     int rc = 0;
12220 
12221     if (fe->exit == DVB_FE_DEVICE_RESUME) {
12222         /* so drxj_open() does what it needs to do */
12223         demod->my_common_attr->is_opened = false;
12224         rc = drxj_open(demod);
12225         if (rc != 0)
12226             pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
12227     } else
12228         drx39xxj_set_powerstate(fe, 1);
12229 
12230     return rc;
12231 }
12232 
12233 static int drx39xxj_set_lna(struct dvb_frontend *fe)
12234 {
12235     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
12236     struct drx39xxj_state *state = fe->demodulator_priv;
12237     struct drx_demod_instance *demod = state->demod;
12238     struct drxj_data *ext_attr = demod->my_ext_attr;
12239 
12240     if (c->lna) {
12241         if (!ext_attr->has_lna) {
12242             pr_err("LNA is not supported on this device!\n");
12243             return -EINVAL;
12244 
12245         }
12246     }
12247 
12248     return drxj_set_lna_state(demod, c->lna);
12249 }
12250 
12251 static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
12252                       struct dvb_frontend_tune_settings *tune)
12253 {
12254     tune->min_delay_ms = 1000;
12255     return 0;
12256 }
12257 
12258 static void drx39xxj_release(struct dvb_frontend *fe)
12259 {
12260     struct drx39xxj_state *state = fe->demodulator_priv;
12261     struct drx_demod_instance *demod = state->demod;
12262 
12263     /* if device is removed don't access it */
12264     if (fe->exit != DVB_FE_DEVICE_REMOVED)
12265         drxj_close(demod);
12266 
12267     kfree(demod->my_ext_attr);
12268     kfree(demod->my_common_attr);
12269     kfree(demod->my_i2c_dev_addr);
12270     release_firmware(demod->firmware);
12271     kfree(demod);
12272     kfree(state);
12273 }
12274 
12275 static const struct dvb_frontend_ops drx39xxj_ops;
12276 
12277 struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
12278 {
12279     struct drx39xxj_state *state = NULL;
12280     struct i2c_device_addr *demod_addr = NULL;
12281     struct drx_common_attr *demod_comm_attr = NULL;
12282     struct drxj_data *demod_ext_attr = NULL;
12283     struct drx_demod_instance *demod = NULL;
12284     struct dtv_frontend_properties *p;
12285     int result;
12286 
12287     /* allocate memory for the internal state */
12288     state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);
12289     if (state == NULL)
12290         goto error;
12291 
12292     demod = kmemdup(&drxj_default_demod_g,
12293             sizeof(struct drx_demod_instance), GFP_KERNEL);
12294     if (demod == NULL)
12295         goto error;
12296 
12297     demod_addr = kmemdup(&drxj_default_addr_g,
12298                  sizeof(struct i2c_device_addr), GFP_KERNEL);
12299     if (demod_addr == NULL)
12300         goto error;
12301 
12302     demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
12303                   sizeof(struct drx_common_attr), GFP_KERNEL);
12304     if (demod_comm_attr == NULL)
12305         goto error;
12306 
12307     demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
12308                  GFP_KERNEL);
12309     if (demod_ext_attr == NULL)
12310         goto error;
12311 
12312     /* setup the state */
12313     state->i2c = i2c;
12314     state->demod = demod;
12315 
12316     /* setup the demod data */
12317     demod->my_i2c_dev_addr = demod_addr;
12318     demod->my_common_attr = demod_comm_attr;
12319     demod->my_i2c_dev_addr->user_data = state;
12320     demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
12321     demod->my_common_attr->verify_microcode = true;
12322     demod->my_common_attr->intermediate_freq = 5000;
12323     demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
12324     demod->my_ext_attr = demod_ext_attr;
12325     ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
12326     demod->i2c = i2c;
12327 
12328     result = drxj_open(demod);
12329     if (result != 0) {
12330         pr_err("DRX open failed!  Aborting\n");
12331         goto error;
12332     }
12333 
12334     /* create dvb_frontend */
12335     memcpy(&state->frontend.ops, &drx39xxj_ops,
12336            sizeof(struct dvb_frontend_ops));
12337 
12338     state->frontend.demodulator_priv = state;
12339 
12340     /* Initialize stats - needed for DVBv5 stats to work */
12341     p = &state->frontend.dtv_property_cache;
12342     p->strength.len = 1;
12343     p->pre_bit_count.len = 1;
12344     p->pre_bit_error.len = 1;
12345     p->post_bit_count.len = 1;
12346     p->post_bit_error.len = 1;
12347     p->block_count.len = 1;
12348     p->block_error.len = 1;
12349     p->cnr.len = 1;
12350 
12351     p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12352     p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12353     p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12354     p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12355     p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12356     p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12357     p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12358     p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12359 
12360     return &state->frontend;
12361 
12362 error:
12363     kfree(demod_ext_attr);
12364     kfree(demod_comm_attr);
12365     kfree(demod_addr);
12366     kfree(demod);
12367     kfree(state);
12368 
12369     return NULL;
12370 }
12371 EXPORT_SYMBOL(drx39xxj_attach);
12372 
12373 static const struct dvb_frontend_ops drx39xxj_ops = {
12374     .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
12375     .info = {
12376          .name = "Micronas DRX39xxj family Frontend",
12377          .frequency_min_hz =  51 * MHz,
12378          .frequency_max_hz = 858 * MHz,
12379          .frequency_stepsize_hz = 62500,
12380          .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
12381     },
12382 
12383     .init = drx39xxj_init,
12384     .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
12385     .sleep = drx39xxj_sleep,
12386     .set_frontend = drx39xxj_set_frontend,
12387     .get_tune_settings = drx39xxj_get_tune_settings,
12388     .read_status = drx39xxj_read_status,
12389     .read_ber = drx39xxj_read_ber,
12390     .read_signal_strength = drx39xxj_read_signal_strength,
12391     .read_snr = drx39xxj_read_snr,
12392     .read_ucblocks = drx39xxj_read_ucblocks,
12393     .release = drx39xxj_release,
12394     .set_lna = drx39xxj_set_lna,
12395 };
12396 
12397 MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
12398 MODULE_AUTHOR("Devin Heitmueller");
12399 MODULE_LICENSE("GPL");
12400 MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);