brintos

brintos / linux-shallow public Read only

0
0
Text · 349.4 KiB · 779cce9 Raw
12392 lines · c
1/*2  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.3  All rights reserved.4 5  Redistribution and use in source and binary forms, with or without6  modification, are permitted provided that the following conditions are met:7 8  * Redistributions of source code must retain the above copyright notice,9    this list of conditions and the following disclaimer.10  * Redistributions in binary form must reproduce the above copyright notice,11    this list of conditions and the following disclaimer in the documentation12	and/or other materials provided with the distribution.13  * Neither the name of Trident Microsystems nor Hauppauge Computer Works14    nor the names of its contributors may be used to endorse or promote15	products derived from this software without specific prior written16	permission.17 18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE22  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR23  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF24  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS25  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN26  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)27  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE28  POSSIBILITY OF SUCH DAMAGE.29 30  DRXJ specific implementation of DRX driver31  authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen32 33  The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was34  written by Devin Heitmueller <devin.heitmueller@kernellabs.com>35 36  This program is free software; you can redistribute it and/or modify37  it under the terms of the GNU General Public License as published by38  the Free Software Foundation; either version 2 of the License, or39  (at your option) any later version.40 41  This program is distributed in the hope that it will be useful,42  but WITHOUT ANY WARRANTY; without even the implied warranty of43  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the44 45  GNU General Public License for more details.46 47  You should have received a copy of the GNU General Public License48  along with this program; if not, write to the Free Software49  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.50*/51 52/*-----------------------------------------------------------------------------53INCLUDE FILES54----------------------------------------------------------------------------*/55 56#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__57 58#include <linux/module.h>59#include <linux/firmware.h>60#include <linux/init.h>61#include <linux/string.h>62#include <linux/slab.h>63#include <asm/div64.h>64 65#include <media/dvb_frontend.h>66#include "drx39xxj.h"67 68#include "drxj.h"69#include "drxj_map.h"70 71/*============================================================================*/72/*=== DEFINES ================================================================*/73/*============================================================================*/74 75#define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"76 77/*78* \brief Maximum u32 value.79*/80#ifndef MAX_U3281#define MAX_U32  ((u32) (0xFFFFFFFFL))82#endif83 84/* Customer configurable hardware settings, etc */85#ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH86#define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x0287#endif88 89#ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH90#define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x0291#endif92 93#ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH94#define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x0695#endif96 97#ifndef OOB_CRX_DRIVE_STRENGTH98#define OOB_CRX_DRIVE_STRENGTH 0x0299#endif100 101#ifndef OOB_DRX_DRIVE_STRENGTH102#define OOB_DRX_DRIVE_STRENGTH 0x02103#endif104/*** START DJCOMBO patches to DRXJ registermap constants *********************/105/*** registermap 200706071303 from drxj **************************************/106#define   ATV_TOP_CR_AMP_TH_FM                                              0x0107#define   ATV_TOP_CR_AMP_TH_L                                               0xA108#define   ATV_TOP_CR_AMP_TH_LP                                              0xA109#define   ATV_TOP_CR_AMP_TH_BG                                              0x8110#define   ATV_TOP_CR_AMP_TH_DK                                              0x8111#define   ATV_TOP_CR_AMP_TH_I                                               0x8112#define     ATV_TOP_CR_CONT_CR_D_MN                                         0x18113#define     ATV_TOP_CR_CONT_CR_D_FM                                         0x0114#define     ATV_TOP_CR_CONT_CR_D_L                                          0x20115#define     ATV_TOP_CR_CONT_CR_D_LP                                         0x20116#define     ATV_TOP_CR_CONT_CR_D_BG                                         0x18117#define     ATV_TOP_CR_CONT_CR_D_DK                                         0x18118#define     ATV_TOP_CR_CONT_CR_D_I                                          0x18119#define     ATV_TOP_CR_CONT_CR_I_MN                                         0x80120#define     ATV_TOP_CR_CONT_CR_I_FM                                         0x0121#define     ATV_TOP_CR_CONT_CR_I_L                                          0x80122#define     ATV_TOP_CR_CONT_CR_I_LP                                         0x80123#define     ATV_TOP_CR_CONT_CR_I_BG                                         0x80124#define     ATV_TOP_CR_CONT_CR_I_DK                                         0x80125#define     ATV_TOP_CR_CONT_CR_I_I                                          0x80126#define     ATV_TOP_CR_CONT_CR_P_MN                                         0x4127#define     ATV_TOP_CR_CONT_CR_P_FM                                         0x0128#define     ATV_TOP_CR_CONT_CR_P_L                                          0x4129#define     ATV_TOP_CR_CONT_CR_P_LP                                         0x4130#define     ATV_TOP_CR_CONT_CR_P_BG                                         0x4131#define     ATV_TOP_CR_CONT_CR_P_DK                                         0x4132#define     ATV_TOP_CR_CONT_CR_P_I                                          0x4133#define   ATV_TOP_CR_OVM_TH_MN                                              0xA0134#define   ATV_TOP_CR_OVM_TH_FM                                              0x0135#define   ATV_TOP_CR_OVM_TH_L                                               0xA0136#define   ATV_TOP_CR_OVM_TH_LP                                              0xA0137#define   ATV_TOP_CR_OVM_TH_BG                                              0xA0138#define   ATV_TOP_CR_OVM_TH_DK                                              0xA0139#define   ATV_TOP_CR_OVM_TH_I                                               0xA0140#define     ATV_TOP_EQU0_EQU_C0_FM                                          0x0141#define     ATV_TOP_EQU0_EQU_C0_L                                           0x3142#define     ATV_TOP_EQU0_EQU_C0_LP                                          0x3143#define     ATV_TOP_EQU0_EQU_C0_BG                                          0x7144#define     ATV_TOP_EQU0_EQU_C0_DK                                          0x0145#define     ATV_TOP_EQU0_EQU_C0_I                                           0x3146#define     ATV_TOP_EQU1_EQU_C1_FM                                          0x0147#define     ATV_TOP_EQU1_EQU_C1_L                                           0x1F6148#define     ATV_TOP_EQU1_EQU_C1_LP                                          0x1F6149#define     ATV_TOP_EQU1_EQU_C1_BG                                          0x197150#define     ATV_TOP_EQU1_EQU_C1_DK                                          0x198151#define     ATV_TOP_EQU1_EQU_C1_I                                           0x1F6152#define     ATV_TOP_EQU2_EQU_C2_FM                                          0x0153#define     ATV_TOP_EQU2_EQU_C2_L                                           0x28154#define     ATV_TOP_EQU2_EQU_C2_LP                                          0x28155#define     ATV_TOP_EQU2_EQU_C2_BG                                          0xC5156#define     ATV_TOP_EQU2_EQU_C2_DK                                          0xB0157#define     ATV_TOP_EQU2_EQU_C2_I                                           0x28158#define     ATV_TOP_EQU3_EQU_C3_FM                                          0x0159#define     ATV_TOP_EQU3_EQU_C3_L                                           0x192160#define     ATV_TOP_EQU3_EQU_C3_LP                                          0x192161#define     ATV_TOP_EQU3_EQU_C3_BG                                          0x12E162#define     ATV_TOP_EQU3_EQU_C3_DK                                          0x18E163#define     ATV_TOP_EQU3_EQU_C3_I                                           0x192164#define     ATV_TOP_STD_MODE_MN                                             0x0165#define     ATV_TOP_STD_MODE_FM                                             0x1166#define     ATV_TOP_STD_MODE_L                                              0x0167#define     ATV_TOP_STD_MODE_LP                                             0x0168#define     ATV_TOP_STD_MODE_BG                                             0x0169#define     ATV_TOP_STD_MODE_DK                                             0x0170#define     ATV_TOP_STD_MODE_I                                              0x0171#define     ATV_TOP_STD_VID_POL_MN                                          0x0172#define     ATV_TOP_STD_VID_POL_FM                                          0x0173#define     ATV_TOP_STD_VID_POL_L                                           0x2174#define     ATV_TOP_STD_VID_POL_LP                                          0x2175#define     ATV_TOP_STD_VID_POL_BG                                          0x0176#define     ATV_TOP_STD_VID_POL_DK                                          0x0177#define     ATV_TOP_STD_VID_POL_I                                           0x0178#define   ATV_TOP_VID_AMP_MN                                                0x380179#define   ATV_TOP_VID_AMP_FM                                                0x0180#define   ATV_TOP_VID_AMP_L                                                 0xF50181#define   ATV_TOP_VID_AMP_LP                                                0xF50182#define   ATV_TOP_VID_AMP_BG                                                0x380183#define   ATV_TOP_VID_AMP_DK                                                0x394184#define   ATV_TOP_VID_AMP_I                                                 0x3D8185#define   IQM_CF_OUT_ENA_OFDM__M                                            0x4186#define     IQM_FS_ADJ_SEL_B_QAM                                            0x1187#define     IQM_FS_ADJ_SEL_B_OFF                                            0x0188#define     IQM_FS_ADJ_SEL_B_VSB                                            0x2189#define     IQM_RC_ADJ_SEL_B_OFF                                            0x0190#define     IQM_RC_ADJ_SEL_B_QAM                                            0x1191#define     IQM_RC_ADJ_SEL_B_VSB                                            0x2192/*** END DJCOMBO patches to DRXJ registermap *********************************/193 194#include "drx_driver_version.h"195 196/* #define DRX_DEBUG */197#ifdef DRX_DEBUG198#include <stdio.h>199#endif200 201/*-----------------------------------------------------------------------------202ENUMS203----------------------------------------------------------------------------*/204 205/*-----------------------------------------------------------------------------206DEFINES207----------------------------------------------------------------------------*/208#ifndef DRXJ_WAKE_UP_KEY209#define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)210#endif211 212/*213* \def DRXJ_DEF_I2C_ADDR214* \brief Default I2C address of a demodulator instance.215*/216#define DRXJ_DEF_I2C_ADDR (0x52)217 218/*219* \def DRXJ_DEF_DEMOD_DEV_ID220* \brief Default device identifier of a demodultor instance.221*/222#define DRXJ_DEF_DEMOD_DEV_ID      (1)223 224/*225* \def DRXJ_SCAN_TIMEOUT226* \brief Timeout value for waiting on demod lock during channel scan (millisec).227*/228#define DRXJ_SCAN_TIMEOUT    1000229 230/*231* \def HI_I2C_DELAY232* \brief HI timing delay for I2C timing (in nano seconds)233*234*  Used to compute HI_CFG_DIV235*/236#define HI_I2C_DELAY    42237 238/*239* \def HI_I2C_BRIDGE_DELAY240* \brief HI timing delay for I2C timing (in nano seconds)241*242*  Used to compute HI_CFG_BDL243*/244#define HI_I2C_BRIDGE_DELAY   750245 246/*247* \brief Time Window for MER and SER Measurement in Units of Segment duration.248*/249#define VSB_TOP_MEASUREMENT_PERIOD  64250#define SYMBOLS_PER_SEGMENT         832251 252/*253* \brief bit rate and segment rate constants used for SER and BER.254*/255/* values taken from the QAM microcode */256#define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0257#define DRXJ_QAM_SL_SIG_POWER_QPSK        32768258#define DRXJ_QAM_SL_SIG_POWER_QAM8        24576259#define DRXJ_QAM_SL_SIG_POWER_QAM16       40960260#define DRXJ_QAM_SL_SIG_POWER_QAM32       20480261#define DRXJ_QAM_SL_SIG_POWER_QAM64       43008262#define DRXJ_QAM_SL_SIG_POWER_QAM128      20992263#define DRXJ_QAM_SL_SIG_POWER_QAM256      43520264/*265* \brief Min supported symbolrates.266*/267#ifndef DRXJ_QAM_SYMBOLRATE_MIN268#define DRXJ_QAM_SYMBOLRATE_MIN          (520000)269#endif270 271/*272* \brief Max supported symbolrates.273*/274#ifndef DRXJ_QAM_SYMBOLRATE_MAX275#define DRXJ_QAM_SYMBOLRATE_MAX         (7233000)276#endif277 278/*279* \def DRXJ_QAM_MAX_WAITTIME280* \brief Maximal wait time for QAM auto constellation in ms281*/282#ifndef DRXJ_QAM_MAX_WAITTIME283#define DRXJ_QAM_MAX_WAITTIME 900284#endif285 286#ifndef DRXJ_QAM_FEC_LOCK_WAITTIME287#define DRXJ_QAM_FEC_LOCK_WAITTIME 150288#endif289 290#ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME291#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200292#endif293 294/*295* \def SCU status and results296* \brief SCU297*/298#define DRX_SCU_READY               0299#define DRXJ_MAX_WAITTIME           100	/* ms */300#define FEC_RS_MEASUREMENT_PERIOD   12894	/* 1 sec */301#define FEC_RS_MEASUREMENT_PRESCALE 1	/* n sec */302 303/*304* \def DRX_AUD_MAX_DEVIATION305* \brief Needed for calculation of prescale feature in AUD306*/307#ifndef DRXJ_AUD_MAX_FM_DEVIATION308#define DRXJ_AUD_MAX_FM_DEVIATION  100	/* kHz */309#endif310 311/*312* \brief Needed for calculation of NICAM prescale feature in AUD313*/314#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE315#define DRXJ_AUD_MAX_NICAM_PRESCALE  (9)	/* dB */316#endif317 318/*319* \brief Needed for calculation of NICAM prescale feature in AUD320*/321#ifndef DRXJ_AUD_MAX_WAITTIME322#define DRXJ_AUD_MAX_WAITTIME  250	/* ms */323#endif324 325/* ATV config changed flags */326#define DRXJ_ATV_CHANGED_COEF          (0x00000001UL)327#define DRXJ_ATV_CHANGED_PEAK_FLT      (0x00000008UL)328#define DRXJ_ATV_CHANGED_NOISE_FLT     (0x00000010UL)329#define DRXJ_ATV_CHANGED_OUTPUT        (0x00000020UL)330#define DRXJ_ATV_CHANGED_SIF_ATT       (0x00000040UL)331 332/* UIO define */333#define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0334#define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1335 336/*337 * MICROCODE RELATED DEFINES338 */339 340/* Magic word for checking correct Endianness of microcode data */341#define DRX_UCODE_MAGIC_WORD         ((((u16)'H')<<8)+((u16)'L'))342 343/* CRC flag in ucode header, flags field. */344#define DRX_UCODE_CRC_FLAG           (0x0001)345 346/*347 * Maximum size of buffer used to verify the microcode.348 * Must be an even number349 */350#define DRX_UCODE_MAX_BUF_SIZE       (DRXDAP_MAX_RCHUNKSIZE)351 352#if DRX_UCODE_MAX_BUF_SIZE & 1353#error DRX_UCODE_MAX_BUF_SIZE must be an even number354#endif355 356/*357 * Power mode macros358 */359 360#define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \361				       (mode == DRX_POWER_MODE_10) || \362				       (mode == DRX_POWER_MODE_11) || \363				       (mode == DRX_POWER_MODE_12) || \364				       (mode == DRX_POWER_MODE_13) || \365				       (mode == DRX_POWER_MODE_14) || \366				       (mode == DRX_POWER_MODE_15) || \367				       (mode == DRX_POWER_MODE_16) || \368				       (mode == DRX_POWER_DOWN))369 370/* Pin safe mode macro */371#define DRXJ_PIN_SAFE_MODE 0x0000372/*============================================================================*/373/*=== GLOBAL VARIABLEs =======================================================*/374/*============================================================================*/375/*376*/377 378/*379* \brief Temporary register definitions.380*        (register definitions that are not yet available in register master)381*/382 383/*****************************************************************************/384/* Audio block 0x103 is write only. To avoid shadowing in driver accessing   */385/* RAM addresses directly. This must be READ ONLY to avoid problems.         */386/* Writing to the interface addresses are more than only writing the RAM     */387/* locations                                                                 */388/*****************************************************************************/389/*390* \brief RAM location of MODUS registers391*/392#define AUD_DEM_RAM_MODUS_HI__A              0x10204A3393#define AUD_DEM_RAM_MODUS_HI__M              0xF000394 395#define AUD_DEM_RAM_MODUS_LO__A              0x10204A4396#define AUD_DEM_RAM_MODUS_LO__M              0x0FFF397 398/*399* \brief RAM location of I2S config registers400*/401#define AUD_DEM_RAM_I2S_CONFIG1__A           0x10204B1402#define AUD_DEM_RAM_I2S_CONFIG2__A           0x10204B2403 404/*405* \brief RAM location of DCO config registers406*/407#define AUD_DEM_RAM_DCO_B_HI__A              0x1020461408#define AUD_DEM_RAM_DCO_B_LO__A              0x1020462409#define AUD_DEM_RAM_DCO_A_HI__A              0x1020463410#define AUD_DEM_RAM_DCO_A_LO__A              0x1020464411 412/*413* \brief RAM location of Threshold registers414*/415#define AUD_DEM_RAM_NICAM_THRSHLD__A         0x102045A416#define AUD_DEM_RAM_A2_THRSHLD__A            0x10204BB417#define AUD_DEM_RAM_BTSC_THRSHLD__A          0x10204A6418 419/*420* \brief RAM location of Carrier Threshold registers421*/422#define AUD_DEM_RAM_CM_A_THRSHLD__A          0x10204AF423#define AUD_DEM_RAM_CM_B_THRSHLD__A          0x10204B0424 425/*426* \brief FM Matrix register fix427*/428#ifdef AUD_DEM_WR_FM_MATRIX__A429#undef  AUD_DEM_WR_FM_MATRIX__A430#endif431#define AUD_DEM_WR_FM_MATRIX__A              0x105006F432 433/*============================================================================*/434/*435* \brief Defines required for audio436*/437#define AUD_VOLUME_ZERO_DB                      115438#define AUD_VOLUME_DB_MIN                       -60439#define AUD_VOLUME_DB_MAX                       12440#define AUD_CARRIER_STRENGTH_QP_0DB             0x4000441#define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100   421442#define AUD_MAX_AVC_REF_LEVEL                   15443#define AUD_I2S_FREQUENCY_MAX                   48000UL444#define AUD_I2S_FREQUENCY_MIN                   12000UL445#define AUD_RDS_ARRAY_SIZE                      18446 447/*448* \brief Needed for calculation of prescale feature in AUD449*/450#ifndef DRX_AUD_MAX_FM_DEVIATION451#define DRX_AUD_MAX_FM_DEVIATION  (100)	/* kHz */452#endif453 454/*455* \brief Needed for calculation of NICAM prescale feature in AUD456*/457#ifndef DRX_AUD_MAX_NICAM_PRESCALE458#define DRX_AUD_MAX_NICAM_PRESCALE  (9)	/* dB */459#endif460 461/*============================================================================*/462/* Values for I2S Master/Slave pin configurations */463#define SIO_PDR_I2S_CL_CFG_MODE__MASTER      0x0004464#define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER     0x0008465#define SIO_PDR_I2S_CL_CFG_MODE__SLAVE       0x0004466#define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE      0x0000467 468#define SIO_PDR_I2S_DA_CFG_MODE__MASTER      0x0003469#define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER     0x0008470#define SIO_PDR_I2S_DA_CFG_MODE__SLAVE       0x0003471#define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE      0x0008472 473#define SIO_PDR_I2S_WS_CFG_MODE__MASTER      0x0004474#define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER     0x0008475#define SIO_PDR_I2S_WS_CFG_MODE__SLAVE       0x0004476#define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE      0x0000477 478/*============================================================================*/479/*=== REGISTER ACCESS MACROS =================================================*/480/*============================================================================*/481 482/*483* This macro is used to create byte arrays for block writes.484* Block writes speed up I2C traffic between host and demod.485* The macro takes care of the required byte order in a 16 bits word.486* x -> lowbyte(x), highbyte(x)487*/488#define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \489		       ((u8)((((u16)x)>>8)&0xFF))490/*491* This macro is used to convert byte array to 16 bit register value for block read.492* Block read speed up I2C traffic between host and demod.493* The macro takes care of the required byte order in a 16 bits word.494*/495#define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))496 497/*============================================================================*/498/*=== MISC DEFINES ===========================================================*/499/*============================================================================*/500 501/*============================================================================*/502/*=== HI COMMAND RELATED DEFINES =============================================*/503/*============================================================================*/504 505/*506* \brief General maximum number of retries for ucode command interfaces507*/508#define DRXJ_MAX_RETRIES (100)509 510/*============================================================================*/511/*=== STANDARD RELATED MACROS ================================================*/512/*============================================================================*/513 514#define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \515			       (std == DRX_STANDARD_PAL_SECAM_DK) || \516			       (std == DRX_STANDARD_PAL_SECAM_I) || \517			       (std == DRX_STANDARD_PAL_SECAM_L) || \518			       (std == DRX_STANDARD_PAL_SECAM_LP) || \519			       (std == DRX_STANDARD_NTSC) || \520			       (std == DRX_STANDARD_FM))521 522#define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \523			       (std == DRX_STANDARD_ITU_B) || \524			       (std == DRX_STANDARD_ITU_C) || \525			       (std == DRX_STANDARD_ITU_D))526 527/*-----------------------------------------------------------------------------528GLOBAL VARIABLES529----------------------------------------------------------------------------*/530/*531 * DRXJ DAP structures532 */533 534static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,535				      u32 addr,536				      u16 datasize,537				      u8 *data, u32 flags);538 539 540static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,541						 u32 waddr,542						 u32 raddr,543						 u16 wdata, u16 *rdata);544 545static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,546				      u32 addr,547				      u16 *data, u32 flags);548 549static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,550				      u32 addr,551				      u32 *data, u32 flags);552 553static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,554				       u32 addr,555				       u16 datasize,556				       u8 *data, u32 flags);557 558static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,559				       u32 addr,560				       u16 data, u32 flags);561 562static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,563				       u32 addr,564				       u32 data, u32 flags);565 566static struct drxj_data drxj_data_g = {567	false,			/* has_lna : true if LNA (aka PGA) present      */568	false,			/* has_oob : true if OOB supported              */569	false,			/* has_ntsc: true if NTSC supported             */570	false,			/* has_btsc: true if BTSC supported             */571	false,			/* has_smatx: true if SMA_TX pin is available   */572	false,			/* has_smarx: true if SMA_RX pin is available   */573	false,			/* has_gpio : true if GPIO pin is available     */574	false,			/* has_irqn : true if IRQN pin is available     */575	0,			/* mfx A1/A2/A... */576 577	/* tuner settings */578	false,			/* tuner mirrors RF signal    */579	/* standard/channel settings */580	DRX_STANDARD_UNKNOWN,	/* current standard           */581	DRX_CONSTELLATION_AUTO,	/* constellation              */582	0,			/* frequency in KHz           */583	DRX_BANDWIDTH_UNKNOWN,	/* curr_bandwidth              */584	DRX_MIRROR_NO,		/* mirror                     */585 586	/* signal quality information: */587	/* default values taken from the QAM Programming guide */588	/*   fec_bits_desired should not be less than 4000000    */589	4000000,		/* fec_bits_desired    */590	5,			/* fec_vd_plen         */591	4,			/* qam_vd_prescale     */592	0xFFFF,			/* qamVDPeriod       */593	204 * 8,		/* fec_rs_plen annex A */594	1,			/* fec_rs_prescale     */595	FEC_RS_MEASUREMENT_PERIOD,	/* fec_rs_period     */596	true,			/* reset_pkt_err_acc    */597	0,			/* pkt_err_acc_start    */598 599	/* HI configuration */600	0,			/* hi_cfg_timing_div    */601	0,			/* hi_cfg_bridge_delay  */602	0,			/* hi_cfg_wake_up_key    */603	0,			/* hi_cfg_ctrl         */604	0,			/* HICfgTimeout      */605	/* UIO configuration */606	DRX_UIO_MODE_DISABLE,	/* uio_sma_rx_mode      */607	DRX_UIO_MODE_DISABLE,	/* uio_sma_tx_mode      */608	DRX_UIO_MODE_DISABLE,	/* uioASELMode       */609	DRX_UIO_MODE_DISABLE,	/* uio_irqn_mode       */610	/* FS setting */611	0UL,			/* iqm_fs_rate_ofs      */612	false,			/* pos_image          */613	/* RC setting */614	0UL,			/* iqm_rc_rate_ofs      */615	/* AUD information */616/*   false,                  * flagSetAUDdone    */617/*   false,                  * detectedRDS       */618/*   true,                   * flagASDRequest    */619/*   false,                  * flagHDevClear     */620/*   false,                  * flagHDevSet       */621/*   (u16) 0xFFF,          * rdsLastCount      */622 623	/* ATV configuration */624	0UL,			/* flags cfg changes */625	/* shadow of ATV_TOP_EQU0__A */626	{-5,627	 ATV_TOP_EQU0_EQU_C0_FM,628	 ATV_TOP_EQU0_EQU_C0_L,629	 ATV_TOP_EQU0_EQU_C0_LP,630	 ATV_TOP_EQU0_EQU_C0_BG,631	 ATV_TOP_EQU0_EQU_C0_DK,632	 ATV_TOP_EQU0_EQU_C0_I},633	/* shadow of ATV_TOP_EQU1__A */634	{-50,635	 ATV_TOP_EQU1_EQU_C1_FM,636	 ATV_TOP_EQU1_EQU_C1_L,637	 ATV_TOP_EQU1_EQU_C1_LP,638	 ATV_TOP_EQU1_EQU_C1_BG,639	 ATV_TOP_EQU1_EQU_C1_DK,640	 ATV_TOP_EQU1_EQU_C1_I},641	/* shadow of ATV_TOP_EQU2__A */642	{210,643	 ATV_TOP_EQU2_EQU_C2_FM,644	 ATV_TOP_EQU2_EQU_C2_L,645	 ATV_TOP_EQU2_EQU_C2_LP,646	 ATV_TOP_EQU2_EQU_C2_BG,647	 ATV_TOP_EQU2_EQU_C2_DK,648	 ATV_TOP_EQU2_EQU_C2_I},649	/* shadow of ATV_TOP_EQU3__A */650	{-160,651	 ATV_TOP_EQU3_EQU_C3_FM,652	 ATV_TOP_EQU3_EQU_C3_L,653	 ATV_TOP_EQU3_EQU_C3_LP,654	 ATV_TOP_EQU3_EQU_C3_BG,655	 ATV_TOP_EQU3_EQU_C3_DK,656	 ATV_TOP_EQU3_EQU_C3_I},657	false,			/* flag: true=bypass             */658	ATV_TOP_VID_PEAK__PRE,	/* shadow of ATV_TOP_VID_PEAK__A */659	ATV_TOP_NOISE_TH__PRE,	/* shadow of ATV_TOP_NOISE_TH__A */660	true,			/* flag CVBS output enable       */661	false,			/* flag SIF output enable        */662	DRXJ_SIF_ATTENUATION_0DB,	/* current SIF att setting       */663	{			/* qam_rf_agc_cfg */664	 DRX_STANDARD_ITU_B,	/* standard            */665	 DRX_AGC_CTRL_AUTO,	/* ctrl_mode            */666	 0,			/* output_level         */667	 0,			/* min_output_level      */668	 0xFFFF,		/* max_output_level      */669	 0x0000,		/* speed               */670	 0x0000,		/* top                 */671	 0x0000			/* c.o.c.              */672	 },673	{			/* qam_if_agc_cfg */674	 DRX_STANDARD_ITU_B,	/* standard            */675	 DRX_AGC_CTRL_AUTO,	/* ctrl_mode            */676	 0,			/* output_level         */677	 0,			/* min_output_level      */678	 0xFFFF,		/* max_output_level      */679	 0x0000,		/* speed               */680	 0x0000,		/* top    (don't care) */681	 0x0000			/* c.o.c. (don't care) */682	 },683	{			/* vsb_rf_agc_cfg */684	 DRX_STANDARD_8VSB,	/* standard       */685	 DRX_AGC_CTRL_AUTO,	/* ctrl_mode       */686	 0,			/* output_level    */687	 0,			/* min_output_level */688	 0xFFFF,		/* max_output_level */689	 0x0000,		/* speed          */690	 0x0000,		/* top    (don't care) */691	 0x0000			/* c.o.c. (don't care) */692	 },693	{			/* vsb_if_agc_cfg */694	 DRX_STANDARD_8VSB,	/* standard       */695	 DRX_AGC_CTRL_AUTO,	/* ctrl_mode       */696	 0,			/* output_level    */697	 0,			/* min_output_level */698	 0xFFFF,		/* max_output_level */699	 0x0000,		/* speed          */700	 0x0000,		/* top    (don't care) */701	 0x0000			/* c.o.c. (don't care) */702	 },703	0,			/* qam_pga_cfg */704	0,			/* vsb_pga_cfg */705	{			/* qam_pre_saw_cfg */706	 DRX_STANDARD_ITU_B,	/* standard  */707	 0,			/* reference */708	 false			/* use_pre_saw */709	 },710	{			/* vsb_pre_saw_cfg */711	 DRX_STANDARD_8VSB,	/* standard  */712	 0,			/* reference */713	 false			/* use_pre_saw */714	 },715 716	/* Version information */717#ifndef _CH_718	{719	 "01234567890",		/* human readable version microcode             */720	 "01234567890"		/* human readable version device specific code  */721	 },722	{723	 {			/* struct drx_version for microcode                   */724	  DRX_MODULE_UNKNOWN,725	  (char *)(NULL),726	  0,727	  0,728	  0,729	  (char *)(NULL)730	  },731	 {			/* struct drx_version for device specific code */732	  DRX_MODULE_UNKNOWN,733	  (char *)(NULL),734	  0,735	  0,736	  0,737	  (char *)(NULL)738	  }739	 },740	{741	 {			/* struct drx_version_list for microcode */742	  (struct drx_version *) (NULL),743	  (struct drx_version_list *) (NULL)744	  },745	 {			/* struct drx_version_list for device specific code */746	  (struct drx_version *) (NULL),747	  (struct drx_version_list *) (NULL)748	  }749	 },750#endif751	false,			/* smart_ant_inverted */752	/* Tracking filter setting for OOB  */753	{754	 12000,755	 9300,756	 6600,757	 5280,758	 3700,759	 3000,760	 2000,761	 0},762	false,			/* oob_power_on           */763	0,			/* mpeg_ts_static_bitrate  */764	false,			/* disable_te_ihandling   */765	false,			/* bit_reverse_mpeg_outout */766	DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,	/* mpeg_output_clock_rate */767	DRXJ_MPEG_START_WIDTH_1CLKCYC,	/* mpeg_start_width */768 769	/* Pre SAW & Agc configuration for ATV */770	{771	 DRX_STANDARD_NTSC,	/* standard     */772	 7,			/* reference    */773	 true			/* use_pre_saw    */774	 },775	{			/* ATV RF-AGC */776	 DRX_STANDARD_NTSC,	/* standard              */777	 DRX_AGC_CTRL_AUTO,	/* ctrl_mode              */778	 0,			/* output_level           */779	 0,			/* min_output_level (d.c.) */780	 0,			/* max_output_level (d.c.) */781	 3,			/* speed                 */782	 9500,			/* top                   */783	 4000			/* cut-off current       */784	 },785	{			/* ATV IF-AGC */786	 DRX_STANDARD_NTSC,	/* standard              */787	 DRX_AGC_CTRL_AUTO,	/* ctrl_mode              */788	 0,			/* output_level           */789	 0,			/* min_output_level (d.c.) */790	 0,			/* max_output_level (d.c.) */791	 3,			/* speed                 */792	 2400,			/* top                   */793	 0			/* c.o.c.         (d.c.) */794	 },795	140,			/* ATV PGA config */796	0,			/* curr_symbol_rate */797 798	false,			/* pdr_safe_mode     */799	SIO_PDR_GPIO_CFG__PRE,	/* pdr_safe_restore_val_gpio  */800	SIO_PDR_VSYNC_CFG__PRE,	/* pdr_safe_restore_val_v_sync */801	SIO_PDR_SMA_RX_CFG__PRE,	/* pdr_safe_restore_val_sma_rx */802	SIO_PDR_SMA_TX_CFG__PRE,	/* pdr_safe_restore_val_sma_tx */803 804	4,			/* oob_pre_saw            */805	DRXJ_OOB_LO_POW_MINUS10DB,	/* oob_lo_pow             */806	{807	 false			/* aud_data, only first member */808	 },809};810 811/*812* \var drxj_default_addr_g813* \brief Default I2C address and device identifier.814*/815static struct i2c_device_addr drxj_default_addr_g = {816	DRXJ_DEF_I2C_ADDR,	/* i2c address */817	DRXJ_DEF_DEMOD_DEV_ID	/* device id */818};819 820/*821* \var drxj_default_comm_attr_g822* \brief Default common attributes of a drxj demodulator instance.823*/824static struct drx_common_attr drxj_default_comm_attr_g = {825	NULL,			/* ucode file           */826	true,			/* ucode verify switch  */827	{0},			/* version record       */828 829	44000,			/* IF in kHz in case no tuner instance is used  */830	(151875 - 0),		/* system clock frequency in kHz                */831	0,			/* oscillator frequency kHz                     */832	0,			/* oscillator deviation in ppm, signed          */833	false,			/* If true mirror frequency spectrum            */834	{835	 /* MPEG output configuration */836	 true,			/* If true, enable MPEG output   */837	 false,			/* If true, insert RS byte       */838	 false,			/* If true, parallel out otherwise serial */839	 false,			/* If true, invert DATA signals  */840	 false,			/* If true, invert ERR signal    */841	 false,			/* If true, invert STR signals   */842	 false,			/* If true, invert VAL signals   */843	 false,			/* If true, invert CLK signals   */844	 true,			/* If true, static MPEG clockrate will845				   be used, otherwise clockrate will846				   adapt to the bitrate of the TS */847	 19392658UL,		/* Maximum bitrate in b/s in case848				   static clockrate is selected */849	 DRX_MPEG_STR_WIDTH_1	/* MPEG Start width in clock cycles */850	 },851	/* Initilisations below can be omitted, they require no user input and852	   are initially 0, NULL or false. The compiler will initialize them to these853	   values when omitted.  */854	false,			/* is_opened */855 856	/* SCAN */857	NULL,			/* no scan params yet               */858	0,			/* current scan index               */859	0,			/* next scan frequency              */860	false,			/* scan ready flag                  */861	0,			/* max channels to scan             */862	0,			/* nr of channels scanned           */863	NULL,			/* default scan function            */864	NULL,			/* default context pointer          */865	0,			/* millisec to wait for demod lock  */866	DRXJ_DEMOD_LOCK,	/* desired lock               */867	false,868 869	/* Power management */870	DRX_POWER_UP,871 872	/* Tuner */873	1,			/* nr of I2C port to which tuner is    */874	0L,			/* minimum RF input frequency, in kHz  */875	0L,			/* maximum RF input frequency, in kHz  */876	false,			/* Rf Agc Polarity                     */877	false,			/* If Agc Polarity                     */878	false,			/* tuner slow mode                     */879 880	{			/* current channel (all 0)             */881	 0UL			/* channel.frequency */882	 },883	DRX_STANDARD_UNKNOWN,	/* current standard */884	DRX_STANDARD_UNKNOWN,	/* previous standard */885	DRX_STANDARD_UNKNOWN,	/* di_cache_standard   */886	false,			/* use_bootloader */887	0UL,			/* capabilities */888	0			/* mfx */889};890 891/*892* \var drxj_default_demod_g893* \brief Default drxj demodulator instance.894*/895static struct drx_demod_instance drxj_default_demod_g = {896	&drxj_default_addr_g,	/* i2c address & device id */897	&drxj_default_comm_attr_g,	/* demod common attributes */898	&drxj_data_g		/* demod device specific attributes */899};900 901/*902* \brief Default audio data structure for DRK demodulator instance.903*904* This structure is DRXK specific.905*906*/907static struct drx_aud_data drxj_default_aud_data_g = {908	false,			/* audio_is_active */909	DRX_AUD_STANDARD_AUTO,	/* audio_standard  */910 911	/* i2sdata */912	{913	 false,			/* output_enable   */914	 48000,			/* frequency      */915	 DRX_I2S_MODE_MASTER,	/* mode           */916	 DRX_I2S_WORDLENGTH_32,	/* word_length     */917	 DRX_I2S_POLARITY_RIGHT,	/* polarity       */918	 DRX_I2S_FORMAT_WS_WITH_DATA	/* format         */919	 },920	/* volume            */921	{922	 true,			/* mute;          */923	 0,			/* volume         */924	 DRX_AUD_AVC_OFF,	/* avc_mode        */925	 0,			/* avc_ref_level    */926	 DRX_AUD_AVC_MAX_GAIN_12DB,	/* avc_max_gain     */927	 DRX_AUD_AVC_MAX_ATTEN_24DB,	/* avc_max_atten    */928	 0,			/* strength_left   */929	 0			/* strength_right  */930	 },931	DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON,	/* auto_sound */932	/*  ass_thresholds */933	{934	 440,			/* A2    */935	 12,			/* BTSC  */936	 700,			/* NICAM */937	 },938	/* carrier */939	{940	 /* a */941	 {942	  42,			/* thres */943	  DRX_NO_CARRIER_NOISE,	/* opt   */944	  0,			/* shift */945	  0			/* dco   */946	  },947	 /* b */948	 {949	  42,			/* thres */950	  DRX_NO_CARRIER_MUTE,	/* opt   */951	  0,			/* shift */952	  0			/* dco   */953	  },954 955	 },956	/* mixer */957	{958	 DRX_AUD_SRC_STEREO_OR_A,	/* source_i2s */959	 DRX_AUD_I2S_MATRIX_STEREO,	/* matrix_i2s */960	 DRX_AUD_FM_MATRIX_SOUND_A	/* matrix_fm  */961	 },962	DRX_AUD_DEVIATION_NORMAL,	/* deviation */963	DRX_AUD_AVSYNC_OFF,	/* av_sync */964 965	/* prescale */966	{967	 DRX_AUD_MAX_FM_DEVIATION,	/* fm_deviation */968	 DRX_AUD_MAX_NICAM_PRESCALE	/* nicam_gain */969	 },970	DRX_AUD_FM_DEEMPH_75US,	/* deemph */971	DRX_BTSC_STEREO,	/* btsc_detect */972	0,			/* rds_data_counter */973	false			/* rds_data_present */974};975 976/*-----------------------------------------------------------------------------977STRUCTURES978----------------------------------------------------------------------------*/979/* HI command */980struct drxj_hi_cmd {981	u16 cmd;982	u16 param1;983	u16 param2;984	u16 param3;985	u16 param4;986	u16 param5;987	u16 param6;988};989 990/*============================================================================*/991/*=== MICROCODE RELATED STRUCTURES ===========================================*/992/*============================================================================*/993 994/*995 * struct drxu_code_block_hdr - Structure of the microcode block headers996 *997 * @addr:	Destination address of the data in this block998 * @size:	Size of the block data following this header counted in999 *		16 bits words1000 * @CRC:	CRC value of the data block, only valid if CRC flag is1001 *		set.1002 */1003struct drxu_code_block_hdr {1004	u32 addr;1005	u16 size;1006	u16 flags;1007	u16 CRC;1008};1009 1010/*-----------------------------------------------------------------------------1011FUNCTIONS1012----------------------------------------------------------------------------*/1013/* Some prototypes */1014static int1015hi_command(struct i2c_device_addr *dev_addr,1016	   const struct drxj_hi_cmd *cmd, u16 *result);1017 1018static int1019ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);1020 1021static int1022ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);1023 1024static int power_down_aud(struct drx_demod_instance *demod);1025 1026static int1027ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);1028 1029static int1030ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);1031 1032/*============================================================================*/1033/*============================================================================*/1034/*==                          HELPER FUNCTIONS                              ==*/1035/*============================================================================*/1036/*============================================================================*/1037 1038 1039/*============================================================================*/1040 1041/*1042* \fn u32 frac28(u32 N, u32 D)1043* \brief Compute: (1<<28)*N/D1044* \param N 32 bits1045* \param D 32 bits1046* \return (1<<28)*N/D1047* This function is used to avoid floating-point calculations as they may1048* not be present on the target platform.1049 1050* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point1051* fraction used for setting the Frequency Shifter registers.1052* N and D can hold numbers up to width: 28-bits.1053* The 4 bits integer part and the 28 bits fractional part are calculated.1054 1055* Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.9991056 1057* N: 0...(1<<28)-1 = 2684354541058* D: 0...(1<<28)-11059* Q: 0...(1<<32)-11060*/1061static u32 frac28(u32 N, u32 D)1062{1063	int i = 0;1064	u32 Q1 = 0;1065	u32 R0 = 0;1066 1067	R0 = (N % D) << 4;	/* 32-28 == 4 shifts possible at max */1068	Q1 = N / D;		/* integer part, only the 4 least significant bits1069				   will be visible in the result */1070 1071	/* division using radix 16, 7 nibbles in the result */1072	for (i = 0; i < 7; i++) {1073		Q1 = (Q1 << 4) | R0 / D;1074		R0 = (R0 % D) << 4;1075	}1076	/* rounding */1077	if ((R0 >> 3) >= D)1078		Q1++;1079 1080	return Q1;1081}1082 1083/*1084* \fn u32 log1_times100( u32 x)1085* \brief Compute: 100*log10(x)1086* \param x 32 bits1087* \return 100*log10(x)1088*1089* 100*log10(x)1090* = 100*(log2(x)/log2(10)))1091* = (100*(2^15)*log2(x))/((2^15)*log2(10))1092* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/21093* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/21094* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/21095*1096* where y = 2^k and 1<= (x/y) < 21097*/1098 1099static u32 log1_times100(u32 x)1100{1101	static const u8 scale = 15;1102	static const u8 index_width = 5;1103	/*1104	   log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))1105	   0 <= n < ((1<<INDEXWIDTH)+1)1106	 */1107 1108	static const u32 log2lut[] = {1109		0,		/* 0.000000 */1110		290941,		/* 290941.300628 */1111		573196,		/* 573196.476418 */1112		847269,		/* 847269.179851 */1113		1113620,	/* 1113620.489452 */1114		1372674,	/* 1372673.576986 */1115		1624818,	/* 1624817.752104 */1116		1870412,	/* 1870411.981536 */1117		2109788,	/* 2109787.962654 */1118		2343253,	/* 2343252.817465 */1119		2571091,	/* 2571091.461923 */1120		2793569,	/* 2793568.696416 */1121		3010931,	/* 3010931.055901 */1122		3223408,	/* 3223408.452106 */1123		3431216,	/* 3431215.635215 */1124		3634553,	/* 3634553.498355 */1125		3833610,	/* 3833610.244726 */1126		4028562,	/* 4028562.434393 */1127		4219576,	/* 4219575.925308 */1128		4406807,	/* 4406806.721144 */1129		4590402,	/* 4590401.736809 */1130		4770499,	/* 4770499.491025 */1131		4947231,	/* 4947230.734179 */1132		5120719,	/* 5120719.018555 */1133		5291081,	/* 5291081.217197 */1134		5458428,	/* 5458427.996830 */1135		5622864,	/* 5622864.249668 */1136		5784489,	/* 5784489.488298 */1137		5943398,	/* 5943398.207380 */1138		6099680,	/* 6099680.215452 */1139		6253421,	/* 6253420.939751 */1140		6404702,	/* 6404701.706649 */1141		6553600,	/* 6553600.000000 */1142	};1143 1144	u8 i = 0;1145	u32 y = 0;1146	u32 d = 0;1147	u32 k = 0;1148	u32 r = 0;1149 1150	if (x == 0)1151		return 0;1152 1153	/* Scale x (normalize) */1154	/* computing y in log(x/y) = log(x) - log(y) */1155	if ((x & (((u32) (-1)) << (scale + 1))) == 0) {1156		for (k = scale; k > 0; k--) {1157			if (x & (((u32) 1) << scale))1158				break;1159			x <<= 1;1160		}1161	} else {1162		for (k = scale; k < 31; k++) {1163			if ((x & (((u32) (-1)) << (scale + 1))) == 0)1164				break;1165			x >>= 1;1166		}1167	}1168	/*1169	   Now x has binary point between bit[scale] and bit[scale-1]1170	   and 1.0 <= x < 2.0 */1171 1172	/* correction for division: log(x) = log(x/y)+log(y) */1173	y = k * ((((u32) 1) << scale) * 200);1174 1175	/* remove integer part */1176	x &= ((((u32) 1) << scale) - 1);1177	/* get index */1178	i = (u8) (x >> (scale - index_width));1179	/* compute delta (x-a) */1180	d = x & ((((u32) 1) << (scale - index_width)) - 1);1181	/* compute log, multiplication ( d* (.. )) must be within range ! */1182	y += log2lut[i] +1183	    ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));1184	/* Conver to log10() */1185	y /= 108853;		/* (log2(10) << scale) */1186	r = (y >> 1);1187	/* rounding */1188	if (y & ((u32)1))1189		r++;1190 1191	return r;1192 1193}1194 1195/*1196* \fn u32 frac_times1e6( u16 N, u32 D)1197* \brief Compute: (N/D) * 1000000.1198* \param N nominator 16-bits.1199* \param D denominator 32-bits.1200* \return u321201* \retval ((N/D) * 1000000), 32 bits1202*1203* No check on D=0!1204*/1205static u32 frac_times1e6(u32 N, u32 D)1206{1207	u32 remainder = 0;1208	u32 frac = 0;1209 1210	/*1211	   frac = (N * 1000000) / D1212	   To let it fit in a 32 bits computation:1213	   frac = (N * (1000000 >> 4)) / (D >> 4)1214	   This would result in a problem in case D < 16 (div by 0).1215	   So we do it more elaborate as shown below.1216	 */1217	frac = (((u32) N) * (1000000 >> 4)) / D;1218	frac <<= 4;1219	remainder = (((u32) N) * (1000000 >> 4)) % D;1220	remainder <<= 4;1221	frac += remainder / D;1222	remainder = remainder % D;1223	if ((remainder * 2) > D)1224		frac++;1225 1226	return frac;1227}1228 1229/*============================================================================*/1230 1231 1232/*1233* \brief Values for NICAM prescaler gain. Computed from dB to integer1234*        and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).1235*1236*/1237#if 01238/* Currently, unused as we lack support for analog TV */1239static const u16 nicam_presc_table_val[43] = {1240	1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,1241	5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,1242	18, 20, 23, 25, 28, 32, 36, 40, 45,1243	51, 57, 64, 71, 80, 90, 101, 113, 1271244};1245#endif1246 1247/*============================================================================*/1248/*==                        END HELPER FUNCTIONS                            ==*/1249/*============================================================================*/1250 1251/*============================================================================*/1252/*============================================================================*/1253/*==                      DRXJ DAP FUNCTIONS                                ==*/1254/*============================================================================*/1255/*============================================================================*/1256 1257/*1258   This layer takes care of some device specific register access protocols:1259   -conversion to short address format1260   -access to audio block1261   This layer is placed between the drx_dap_fasi and the rest of the drxj1262   specific implementation. This layer can use address map knowledge whereas1263   dap_fasi may not use memory map knowledge.1264 1265   * For audio currently only 16 bits read and write register access is1266     supported. More is not needed. RMW and 32 or 8 bit access on audio1267     registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast1268     single/multi master) will be ignored.1269 1270   TODO: check ignoring single/multimaster is ok for AUD access ?1271*/1272 1273#define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)1274#define DRXJ_DAP_AUDTRIF_TIMEOUT 80	/* millisec */1275/*============================================================================*/1276 1277/*1278* \fn bool is_handled_by_aud_tr_if( u32 addr )1279* \brief Check if this address is handled by the audio token ring interface.1280* \param addr1281* \return bool1282* \retval true  Yes, handled by audio token ring interface1283* \retval false No, not handled by audio token ring interface1284*1285*/1286static1287bool is_handled_by_aud_tr_if(u32 addr)1288{1289	bool retval = false;1290 1291	if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&1292	    (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&1293	    (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {1294		retval = true;1295	}1296 1297	return retval;1298}1299 1300/*============================================================================*/1301 1302int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,1303				 u16 w_count,1304				 u8 *wData,1305				 struct i2c_device_addr *r_dev_addr,1306				 u16 r_count, u8 *r_data)1307{1308	struct drx39xxj_state *state;1309	struct i2c_msg msg[2];1310	unsigned int num_msgs;1311 1312	if (w_dev_addr == NULL) {1313		/* Read only */1314		state = r_dev_addr->user_data;1315		msg[0].addr = r_dev_addr->i2c_addr >> 1;1316		msg[0].flags = I2C_M_RD;1317		msg[0].buf = r_data;1318		msg[0].len = r_count;1319		num_msgs = 1;1320	} else if (r_dev_addr == NULL) {1321		/* Write only */1322		state = w_dev_addr->user_data;1323		msg[0].addr = w_dev_addr->i2c_addr >> 1;1324		msg[0].flags = 0;1325		msg[0].buf = wData;1326		msg[0].len = w_count;1327		num_msgs = 1;1328	} else {1329		/* Both write and read */1330		state = w_dev_addr->user_data;1331		msg[0].addr = w_dev_addr->i2c_addr >> 1;1332		msg[0].flags = 0;1333		msg[0].buf = wData;1334		msg[0].len = w_count;1335		msg[1].addr = r_dev_addr->i2c_addr >> 1;1336		msg[1].flags = I2C_M_RD;1337		msg[1].buf = r_data;1338		msg[1].len = r_count;1339		num_msgs = 2;1340	}1341 1342	if (state->i2c == NULL) {1343		pr_err("i2c was zero, aborting\n");1344		return 0;1345	}1346	if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {1347		pr_warn("drx3933: I2C write/read failed\n");1348		return -EREMOTEIO;1349	}1350 1351#ifdef DJH_DEBUG1352	if (w_dev_addr == NULL || r_dev_addr == NULL)1353		return 0;1354 1355	state = w_dev_addr->user_data;1356 1357	if (state->i2c == NULL)1358		return 0;1359 1360	msg[0].addr = w_dev_addr->i2c_addr;1361	msg[0].flags = 0;1362	msg[0].buf = wData;1363	msg[0].len = w_count;1364	msg[1].addr = r_dev_addr->i2c_addr;1365	msg[1].flags = I2C_M_RD;1366	msg[1].buf = r_data;1367	msg[1].len = r_count;1368	num_msgs = 2;1369 1370	pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",1371	       w_dev_addr->i2c_addr, state->i2c, w_count, r_count);1372 1373	if (i2c_transfer(state->i2c, msg, 2) != 2) {1374		pr_warn("drx3933: I2C write/read failed\n");1375		return -EREMOTEIO;1376	}1377#endif1378	return 0;1379}1380 1381/*============================================================================*/1382 1383/*****************************1384*1385* int drxdap_fasi_read_block (1386*      struct i2c_device_addr *dev_addr,      -- address of I2C device1387*      u32 addr,         -- address of chip register/memory1388*      u16            datasize,     -- number of bytes to read1389*      u8 *data,         -- data to receive1390*      u32 flags)        -- special device flags1391*1392* Read block data from chip address. Because the chip is word oriented,1393* the number of bytes to read must be even.1394*1395* Make sure that the buffer to receive the data is large enough.1396*1397* Although this function expects an even number of bytes, it is still byte1398* oriented, and the data read back is NOT translated to the endianness of1399* the target platform.1400*1401* Output:1402* - 0     if reading was successful1403*                  in that case: data read is in *data.1404* - -EIO  if anything went wrong1405*1406******************************/1407 1408static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,1409					 u32 addr,1410					 u16 datasize,1411					 u8 *data, u32 flags)1412{1413	u8 buf[4];1414	u16 bufx;1415	int rc;1416	u16 overhead_size = 0;1417 1418	/* Check parameters ******************************************************* */1419	if (dev_addr == NULL)1420		return -EINVAL;1421 1422	overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +1423	    (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);1424 1425	if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||1426	    ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&1427	     DRXDAP_FASI_LONG_FORMAT(addr)) ||1428	    (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||1429	    ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {1430		return -EINVAL;1431	}1432 1433	/* ReadModifyWrite & mode flag bits are not allowed */1434	flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);1435#if DRXDAP_SINGLE_MASTER1436	flags |= DRXDAP_FASI_SINGLE_MASTER;1437#endif1438 1439	/* Read block from I2C **************************************************** */1440	do {1441		u16 todo = min(datasize, DRXDAP_MAX_RCHUNKSIZE);1442 1443		bufx = 0;1444 1445		addr &= ~DRXDAP_FASI_FLAGS;1446		addr |= flags;1447 1448#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))1449		/* short format address preferred but long format otherwise */1450		if (DRXDAP_FASI_LONG_FORMAT(addr)) {1451#endif1452#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)1453			buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);1454			buf[bufx++] = (u8) ((addr >> 16) & 0xFF);1455			buf[bufx++] = (u8) ((addr >> 24) & 0xFF);1456			buf[bufx++] = (u8) ((addr >> 7) & 0xFF);1457#endif1458#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))1459		} else {1460#endif1461#if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)1462			buf[bufx++] = (u8) ((addr << 1) & 0xFF);1463			buf[bufx++] =1464			    (u8) (((addr >> 16) & 0x0F) |1465				    ((addr >> 18) & 0xF0));1466#endif1467#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))1468		}1469#endif1470 1471#if DRXDAP_SINGLE_MASTER1472		/*1473		 * In single master mode, split the read and write actions.1474		 * No special action is needed for write chunks here.1475		 */1476		rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,1477					   NULL, 0, NULL);1478		if (rc == 0)1479			rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data);1480#else1481		/* In multi master mode, do everything in one RW action */1482		rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,1483					  data);1484#endif1485		data += todo;1486		addr += (todo >> 1);1487		datasize -= todo;1488	} while (datasize && rc == 0);1489 1490	return rc;1491}1492 1493 1494/*****************************1495*1496* int drxdap_fasi_read_reg16 (1497*     struct i2c_device_addr *dev_addr, -- address of I2C device1498*     u32 addr,    -- address of chip register/memory1499*     u16 *data,    -- data to receive1500*     u32 flags)   -- special device flags1501*1502* Read one 16-bit register or memory location. The data received back is1503* converted back to the target platform's endianness.1504*1505* Output:1506* - 0     if reading was successful1507*                  in that case: read data is at *data1508* - -EIO  if anything went wrong1509*1510******************************/1511 1512static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,1513					 u32 addr,1514					 u16 *data, u32 flags)1515{1516	u8 buf[sizeof(*data)];1517	int rc;1518 1519	if (!data)1520		return -EINVAL;1521 1522	rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);1523	*data = buf[0] + (((u16) buf[1]) << 8);1524	return rc;1525}1526 1527/*****************************1528*1529* int drxdap_fasi_read_reg32 (1530*     struct i2c_device_addr *dev_addr, -- address of I2C device1531*     u32 addr,    -- address of chip register/memory1532*     u32 *data,    -- data to receive1533*     u32 flags)   -- special device flags1534*1535* Read one 32-bit register or memory location. The data received back is1536* converted back to the target platform's endianness.1537*1538* Output:1539* - 0     if reading was successful1540*                  in that case: read data is at *data1541* - -EIO  if anything went wrong1542*1543******************************/1544 1545static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,1546					 u32 addr,1547					 u32 *data, u32 flags)1548{1549	u8 buf[sizeof(*data)];1550	int rc;1551 1552	if (!data)1553		return -EINVAL;1554 1555	rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);1556	*data = (((u32) buf[0]) << 0) +1557	    (((u32) buf[1]) << 8) +1558	    (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);1559	return rc;1560}1561 1562/*****************************1563*1564* int drxdap_fasi_write_block (1565*      struct i2c_device_addr *dev_addr,    -- address of I2C device1566*      u32 addr,       -- address of chip register/memory1567*      u16            datasize,   -- number of bytes to read1568*      u8 *data,       -- data to receive1569*      u32 flags)      -- special device flags1570*1571* Write block data to chip address. Because the chip is word oriented,1572* the number of bytes to write must be even.1573*1574* Although this function expects an even number of bytes, it is still byte1575* oriented, and the data being written is NOT translated from the endianness of1576* the target platform.1577*1578* Output:1579* - 0     if writing was successful1580* - -EIO  if anything went wrong1581*1582******************************/1583 1584static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,1585					  u32 addr,1586					  u16 datasize,1587					  u8 *data, u32 flags)1588{1589	u8 buf[DRXDAP_MAX_WCHUNKSIZE];1590	int st = -EIO;1591	int first_err = 0;1592	u16 overhead_size = 0;1593	u16 block_size = 0;1594 1595	/* Check parameters ******************************************************* */1596	if (dev_addr == NULL)1597		return -EINVAL;1598 1599	overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +1600	    (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);1601 1602	if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||1603	    ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&1604	     DRXDAP_FASI_LONG_FORMAT(addr)) ||1605	    (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||1606	    ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))1607		return -EINVAL;1608 1609	flags &= DRXDAP_FASI_FLAGS;1610	flags &= ~DRXDAP_FASI_MODEFLAGS;1611#if DRXDAP_SINGLE_MASTER1612	flags |= DRXDAP_FASI_SINGLE_MASTER;1613#endif1614 1615	/* Write block to I2C ***************************************************** */1616	block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;1617	do {1618		u16 todo = 0;1619		u16 bufx = 0;1620 1621		/* Buffer device address */1622		addr &= ~DRXDAP_FASI_FLAGS;1623		addr |= flags;1624#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))1625		/* short format address preferred but long format otherwise */1626		if (DRXDAP_FASI_LONG_FORMAT(addr)) {1627#endif1628#if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)1629			buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);1630			buf[bufx++] = (u8) ((addr >> 16) & 0xFF);1631			buf[bufx++] = (u8) ((addr >> 24) & 0xFF);1632			buf[bufx++] = (u8) ((addr >> 7) & 0xFF);1633#endif1634#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))1635		} else {1636#endif1637#if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)1638			buf[bufx++] = (u8) ((addr << 1) & 0xFF);1639			buf[bufx++] =1640			    (u8) (((addr >> 16) & 0x0F) |1641				    ((addr >> 18) & 0xF0));1642#endif1643#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))1644		}1645#endif1646 1647		/*1648		   In single master mode block_size can be 0. In such a case this I2C1649		   sequense will be visible: (1) write address {i2c addr,1650		   4 bytes chip address} (2) write data {i2c addr, 4 bytes data }1651		   (3) write address (4) write data etc...1652		   Address must be rewritten because HI is reset after data transport and1653		   expects an address.1654		 */1655		todo = min(block_size, datasize);1656		if (todo == 0) {1657			u16 overhead_size_i2c_addr = 0;1658			u16 data_block_size = 0;1659 1660			overhead_size_i2c_addr =1661			    (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);1662			data_block_size =1663			    (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;1664 1665			/* write device address */1666			st = drxbsp_i2c_write_read(dev_addr,1667						  (u16) (bufx),1668						  buf,1669						  (struct i2c_device_addr *)(NULL),1670						  0, (u8 *)(NULL));1671 1672			if ((st != 0) && (first_err == 0)) {1673				/* at the end, return the first error encountered */1674				first_err = st;1675			}1676			bufx = 0;1677			todo = min(data_block_size, datasize);1678		}1679		memcpy(&buf[bufx], data, todo);1680		/* write (address if can do and) data */1681		st = drxbsp_i2c_write_read(dev_addr,1682					  (u16) (bufx + todo),1683					  buf,1684					  (struct i2c_device_addr *)(NULL),1685					  0, (u8 *)(NULL));1686 1687		if ((st != 0) && (first_err == 0)) {1688			/* at the end, return the first error encountered */1689			first_err = st;1690		}1691		datasize -= todo;1692		data += todo;1693		addr += (todo >> 1);1694	} while (datasize);1695 1696	return first_err;1697}1698 1699/*****************************1700*1701* int drxdap_fasi_write_reg16 (1702*     struct i2c_device_addr *dev_addr, -- address of I2C device1703*     u32 addr,    -- address of chip register/memory1704*     u16            data,    -- data to send1705*     u32 flags)   -- special device flags1706*1707* Write one 16-bit register or memory location. The data being written is1708* converted from the target platform's endianness to little endian.1709*1710* Output:1711* - 0     if writing was successful1712* - -EIO  if anything went wrong1713*1714******************************/1715 1716static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,1717					  u32 addr,1718					  u16 data, u32 flags)1719{1720	u8 buf[sizeof(data)];1721 1722	buf[0] = (u8) ((data >> 0) & 0xFF);1723	buf[1] = (u8) ((data >> 8) & 0xFF);1724 1725	return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);1726}1727 1728/*****************************1729*1730* int drxdap_fasi_read_modify_write_reg16 (1731*      struct i2c_device_addr *dev_addr,   -- address of I2C device1732*      u32 waddr,     -- address of chip register/memory1733*      u32 raddr,     -- chip address to read back from1734*      u16            wdata,     -- data to send1735*      u16 *rdata)     -- data to receive back1736*1737* Write 16-bit data, then read back the original contents of that location.1738* Requires long addressing format to be allowed.1739*1740* Before sending data, the data is converted to little endian. The1741* data received back is converted back to the target platform's endianness.1742*1743* WARNING: This function is only guaranteed to work if there is one1744* master on the I2C bus.1745*1746* Output:1747* - 0     if reading was successful1748*                  in that case: read back data is at *rdata1749* - -EIO  if anything went wrong1750*1751******************************/1752 1753static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,1754						    u32 waddr,1755						    u32 raddr,1756						    u16 wdata, u16 *rdata)1757{1758	int rc = -EIO;1759 1760#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)1761	if (rdata == NULL)1762		return -EINVAL;1763 1764	rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);1765	if (rc == 0)1766		rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);1767#endif1768 1769	return rc;1770}1771 1772/*****************************1773*1774* int drxdap_fasi_write_reg32 (1775*     struct i2c_device_addr *dev_addr, -- address of I2C device1776*     u32 addr,    -- address of chip register/memory1777*     u32            data,    -- data to send1778*     u32 flags)   -- special device flags1779*1780* Write one 32-bit register or memory location. The data being written is1781* converted from the target platform's endianness to little endian.1782*1783* Output:1784* - 0     if writing was successful1785* - -EIO  if anything went wrong1786*1787******************************/1788 1789static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,1790					  u32 addr,1791					  u32 data, u32 flags)1792{1793	u8 buf[sizeof(data)];1794 1795	buf[0] = (u8) ((data >> 0) & 0xFF);1796	buf[1] = (u8) ((data >> 8) & 0xFF);1797	buf[2] = (u8) ((data >> 16) & 0xFF);1798	buf[3] = (u8) ((data >> 24) & 0xFF);1799 1800	return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);1801}1802 1803/*============================================================================*/1804 1805/*1806* \fn int drxj_dap_rm_write_reg16short1807* \brief Read modify write 16 bits audio register using short format only.1808* \param dev_addr1809* \param waddr    Address to write to1810* \param raddr    Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)1811* \param wdata    Data to write1812* \param rdata    Buffer for data to read1813* \return int1814* \retval 0 Success1815* \retval -EIO Timeout, I2C error, illegal bank1816*1817* 16 bits register read modify write access using short addressing format only.1818* Requires knowledge of the registermap, thus device dependent.1819* Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.1820*1821*/1822 1823/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )1824   See comments drxj_dap_read_modify_write_reg16 */1825#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)1826static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,1827					      u32 waddr,1828					      u32 raddr,1829					      u16 wdata, u16 *rdata)1830{1831	int rc;1832 1833	if (rdata == NULL)1834		return -EINVAL;1835 1836	/* Set RMW flag */1837	rc = drxdap_fasi_write_reg16(dev_addr,1838					      SIO_HI_RA_RAM_S0_FLG_ACC__A,1839					      SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,1840					      0x0000);1841	if (rc == 0) {1842		/* Write new data: triggers RMW */1843		rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,1844						      0x0000);1845	}1846	if (rc == 0) {1847		/* Read old data */1848		rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,1849						     0x0000);1850	}1851	if (rc == 0) {1852		/* Reset RMW flag */1853		rc = drxdap_fasi_write_reg16(dev_addr,1854						      SIO_HI_RA_RAM_S0_FLG_ACC__A,1855						      0, 0x0000);1856	}1857 1858	return rc;1859}1860#endif1861 1862/*============================================================================*/1863 1864static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,1865						 u32 waddr,1866						 u32 raddr,1867						 u16 wdata, u16 *rdata)1868{1869	/* TODO: correct short/long addressing format decision,1870	   now long format has higher prio then short because short also1871	   needs virt bnks (not impl yet) for certain audio registers */1872#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)1873	return drxdap_fasi_read_modify_write_reg16(dev_addr,1874							  waddr,1875							  raddr, wdata, rdata);1876#else1877	return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);1878#endif1879}1880 1881 1882/*============================================================================*/1883 1884/*1885* \fn int drxj_dap_read_aud_reg161886* \brief Read 16 bits audio register1887* \param dev_addr1888* \param addr1889* \param data1890* \return int1891* \retval 0 Success1892* \retval -EIO Timeout, I2C error, illegal bank1893*1894* 16 bits register read access via audio token ring interface.1895*1896*/1897static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,1898					 u32 addr, u16 *data)1899{1900	u32 start_timer = 0;1901	u32 current_timer = 0;1902	u32 delta_timer = 0;1903	u16 tr_status = 0;1904	int stat = -EIO;1905 1906	/* No read possible for bank 3, return with error */1907	if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {1908		stat = -EINVAL;1909	} else {1910		const u32 write_bit = ((dr_xaddr_t) 1) << 16;1911 1912		/* Force reset write bit */1913		addr &= (~write_bit);1914 1915		/* Set up read */1916		start_timer = jiffies_to_msecs(jiffies);1917		do {1918			/* RMW to aud TR IF until request is granted or timeout */1919			stat = drxj_dap_read_modify_write_reg16(dev_addr,1920							     addr,1921							     SIO_HI_RA_RAM_S0_RMWBUF__A,1922							     0x0000, &tr_status);1923 1924			if (stat != 0)1925				break;1926 1927			current_timer = jiffies_to_msecs(jiffies);1928			delta_timer = current_timer - start_timer;1929			if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {1930				stat = -EIO;1931				break;1932			}1933 1934		} while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==1935			  AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||1936			 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==1937			  AUD_TOP_TR_CTR_FIFO_FULL_FULL));1938	}			/* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */1939 1940	/* Wait for read ready status or timeout */1941	if (stat == 0) {1942		start_timer = jiffies_to_msecs(jiffies);1943 1944		while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=1945		       AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {1946			stat = drxj_dap_read_reg16(dev_addr,1947						  AUD_TOP_TR_CTR__A,1948						  &tr_status, 0x0000);1949			if (stat != 0)1950				break;1951 1952			current_timer = jiffies_to_msecs(jiffies);1953			delta_timer = current_timer - start_timer;1954			if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {1955				stat = -EIO;1956				break;1957			}1958		}		/* while ( ... ) */1959	}1960 1961	/* Read value */1962	if (stat == 0)1963		stat = drxj_dap_read_modify_write_reg16(dev_addr,1964						     AUD_TOP_TR_RD_REG__A,1965						     SIO_HI_RA_RAM_S0_RMWBUF__A,1966						     0x0000, data);1967	return stat;1968}1969 1970/*============================================================================*/1971 1972static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,1973				      u32 addr,1974				      u16 *data, u32 flags)1975{1976	int stat = -EIO;1977 1978	/* Check param */1979	if ((dev_addr == NULL) || (data == NULL))1980		return -EINVAL;1981 1982	if (is_handled_by_aud_tr_if(addr))1983		stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);1984	else1985		stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);1986 1987	return stat;1988}1989/*============================================================================*/1990 1991/*1992* \fn int drxj_dap_write_aud_reg161993* \brief Write 16 bits audio register1994* \param dev_addr1995* \param addr1996* \param data1997* \return int1998* \retval 0 Success1999* \retval -EIO Timeout, I2C error, illegal bank2000*2001* 16 bits register write access via audio token ring interface.2002*2003*/2004static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,2005					  u32 addr, u16 data)2006{2007	int stat = -EIO;2008 2009	/* No write possible for bank 2, return with error */2010	if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {2011		stat = -EINVAL;2012	} else {2013		u32 start_timer = 0;2014		u32 current_timer = 0;2015		u32 delta_timer = 0;2016		u16 tr_status = 0;2017		const u32 write_bit = ((dr_xaddr_t) 1) << 16;2018 2019		/* Force write bit */2020		addr |= write_bit;2021		start_timer = jiffies_to_msecs(jiffies);2022		do {2023			/* RMW to aud TR IF until request is granted or timeout */2024			stat = drxj_dap_read_modify_write_reg16(dev_addr,2025							     addr,2026							     SIO_HI_RA_RAM_S0_RMWBUF__A,2027							     data, &tr_status);2028			if (stat != 0)2029				break;2030 2031			current_timer = jiffies_to_msecs(jiffies);2032			delta_timer = current_timer - start_timer;2033			if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {2034				stat = -EIO;2035				break;2036			}2037 2038		} while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==2039			  AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||2040			 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==2041			  AUD_TOP_TR_CTR_FIFO_FULL_FULL));2042 2043	}			/* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */2044 2045	return stat;2046}2047 2048/*============================================================================*/2049 2050static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,2051				       u32 addr,2052				       u16 data, u32 flags)2053{2054	int stat = -EIO;2055 2056	/* Check param */2057	if (dev_addr == NULL)2058		return -EINVAL;2059 2060	if (is_handled_by_aud_tr_if(addr))2061		stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);2062	else2063		stat = drxdap_fasi_write_reg16(dev_addr,2064							    addr, data, flags);2065 2066	return stat;2067}2068 2069/*============================================================================*/2070 2071/* Free data ram in SIO HI */2072#define SIO_HI_RA_RAM_USR_BEGIN__A 0x4200402073#define SIO_HI_RA_RAM_USR_END__A   0x4200602074 2075#define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)2076#define DRXJ_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)2077#define DRXJ_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ2078#define DRXJ_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE2079 2080/*2081* \fn int drxj_dap_atomic_read_write_block()2082* \brief Basic access routine for atomic read or write access2083* \param dev_addr  pointer to i2c dev address2084* \param addr     destination/source address2085* \param datasize size of data buffer in bytes2086* \param data     pointer to data buffer2087* \return int2088* \retval 0 Success2089* \retval -EIO Timeout, I2C error, illegal bank2090*2091*/2092static2093int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,2094					  u32 addr,2095					  u16 datasize,2096					  u8 *data, bool read_flag)2097{2098	struct drxj_hi_cmd hi_cmd;2099	int rc;2100	u16 word;2101	u16 dummy = 0;2102	u16 i = 0;2103 2104	/* Parameter check */2105	if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))2106		return -EINVAL;2107 2108	/* Set up HI parameters to read or write n bytes */2109	hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;2110	hi_cmd.param1 =2111	    (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +2112		     DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));2113	hi_cmd.param2 =2114	    (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);2115	hi_cmd.param3 = (u16) ((datasize / 2) - 1);2116	if (!read_flag)2117		hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;2118	else2119		hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;2120	hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +2121				DRXDAP_FASI_ADDR2BANK(addr));2122	hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);2123 2124	if (!read_flag) {2125		/* write data to buffer */2126		for (i = 0; i < (datasize / 2); i++) {2127 2128			word = ((u16) data[2 * i]);2129			word += (((u16) data[(2 * i) + 1]) << 8);2130			drxj_dap_write_reg16(dev_addr,2131					     (DRXJ_HI_ATOMIC_BUF_START + i),2132					    word, 0);2133		}2134	}2135 2136	rc = hi_command(dev_addr, &hi_cmd, &dummy);2137	if (rc != 0) {2138		pr_err("error %d\n", rc);2139		goto rw_error;2140	}2141 2142	if (read_flag) {2143		/* read data from buffer */2144		for (i = 0; i < (datasize / 2); i++) {2145			rc = drxj_dap_read_reg16(dev_addr,2146						 (DRXJ_HI_ATOMIC_BUF_START + i),2147						 &word, 0);2148			if (rc) {2149				pr_err("error %d\n", rc);2150				goto rw_error;2151			}2152			data[2 * i] = (u8) (word & 0xFF);2153			data[(2 * i) + 1] = (u8) (word >> 8);2154		}2155	}2156 2157	return 0;2158 2159rw_error:2160	return rc;2161 2162}2163 2164/*============================================================================*/2165 2166/*2167* \fn int drxj_dap_atomic_read_reg32()2168* \brief Atomic read of 32 bits words2169*/2170static2171int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,2172				     u32 addr,2173				     u32 *data, u32 flags)2174{2175	u8 buf[sizeof(*data)] = { 0 };2176	int rc;2177	u32 word = 0;2178 2179	if (!data)2180		return -EINVAL;2181 2182	rc = drxj_dap_atomic_read_write_block(dev_addr, addr,2183					      sizeof(*data), buf, true);2184 2185	if (rc < 0)2186		return 0;2187 2188	word = (u32) buf[3];2189	word <<= 8;2190	word |= (u32) buf[2];2191	word <<= 8;2192	word |= (u32) buf[1];2193	word <<= 8;2194	word |= (u32) buf[0];2195 2196	*data = word;2197 2198	return rc;2199}2200 2201/*============================================================================*/2202 2203/*============================================================================*/2204/*==                        END DRXJ DAP FUNCTIONS                          ==*/2205/*============================================================================*/2206 2207/*============================================================================*/2208/*============================================================================*/2209/*==                      HOST INTERFACE FUNCTIONS                          ==*/2210/*============================================================================*/2211/*============================================================================*/2212 2213/*2214* \fn int hi_cfg_command()2215* \brief Configure HI with settings stored in the demod structure.2216* \param demod Demodulator.2217* \return int.2218*2219* This routine was created because to much orthogonal settings have2220* been put into one HI API function (configure). Especially the I2C bridge2221* enable/disable should not need re-configuration of the HI.2222*2223*/2224static int hi_cfg_command(const struct drx_demod_instance *demod)2225{2226	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);2227	struct drxj_hi_cmd hi_cmd;2228	u16 result = 0;2229	int rc;2230 2231	ext_attr = (struct drxj_data *) demod->my_ext_attr;2232 2233	hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;2234	hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;2235	hi_cmd.param2 = ext_attr->hi_cfg_timing_div;2236	hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;2237	hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;2238	hi_cmd.param5 = ext_attr->hi_cfg_ctrl;2239	hi_cmd.param6 = ext_attr->hi_cfg_transmit;2240 2241	rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);2242	if (rc != 0) {2243		pr_err("error %d\n", rc);2244		goto rw_error;2245	}2246 2247	/* Reset power down flag (set one call only) */2248	ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));2249 2250	return 0;2251 2252rw_error:2253	return rc;2254}2255 2256/*2257* \fn int hi_command()2258* \brief Configure HI with settings stored in the demod structure.2259* \param dev_addr I2C address.2260* \param cmd HI command.2261* \param result HI command result.2262* \return int.2263*2264* Sends command to HI2265*2266*/2267static int2268hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)2269{2270	u16 wait_cmd = 0;2271	u16 nr_retries = 0;2272	bool powerdown_cmd = false;2273	int rc;2274 2275	/* Write parameters */2276	switch (cmd->cmd) {2277 2278	case SIO_HI_RA_RAM_CMD_CONFIG:2279	case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:2280		rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);2281		if (rc != 0) {2282			pr_err("error %d\n", rc);2283			goto rw_error;2284		}2285		rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);2286		if (rc != 0) {2287			pr_err("error %d\n", rc);2288			goto rw_error;2289		}2290		rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);2291		if (rc != 0) {2292			pr_err("error %d\n", rc);2293			goto rw_error;2294		}2295		rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);2296		if (rc != 0) {2297			pr_err("error %d\n", rc);2298			goto rw_error;2299		}2300		fallthrough;2301	case SIO_HI_RA_RAM_CMD_BRDCTRL:2302		rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);2303		if (rc != 0) {2304			pr_err("error %d\n", rc);2305			goto rw_error;2306		}2307		rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);2308		if (rc != 0) {2309			pr_err("error %d\n", rc);2310			goto rw_error;2311		}2312		fallthrough;2313	case SIO_HI_RA_RAM_CMD_NULL:2314		/* No parameters */2315		break;2316 2317	default:2318		return -EINVAL;2319	}2320 2321	/* Write command */2322	rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);2323	if (rc != 0) {2324		pr_err("error %d\n", rc);2325		goto rw_error;2326	}2327 2328	if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)2329		msleep(1);2330 2331	/* Detect power down to omit reading result */2332	powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&2333				  (((cmd->2334				     param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)2335				   == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));2336	if (!powerdown_cmd) {2337		/* Wait until command rdy */2338		do {2339			nr_retries++;2340			if (nr_retries > DRXJ_MAX_RETRIES) {2341				rc = -ETIMEDOUT;2342				pr_err("timeout\n");2343				goto rw_error;2344			}2345 2346			rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);2347			if (rc != 0) {2348				pr_err("error %d\n", rc);2349				goto rw_error;2350			}2351		} while (wait_cmd != 0);2352 2353		/* Read result */2354		rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);2355		if (rc != 0) {2356			pr_err("error %d\n", rc);2357			goto rw_error;2358		}2359 2360	}2361	/* if ( powerdown_cmd == true ) */2362	return 0;2363rw_error:2364	return rc;2365}2366 2367/*2368* \fn int init_hi( const struct drx_demod_instance *demod )2369* \brief Initialise and configurate HI.2370* \param demod pointer to demod data.2371* \return int Return status.2372* \retval 0 Success.2373* \retval -EIO Failure.2374*2375* Needs to know Psys (System Clock period) and Posc (Osc Clock period)2376* Need to store configuration in driver because of the way I2C2377* bridging is controlled.2378*2379*/2380static int init_hi(const struct drx_demod_instance *demod)2381{2382	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);2383	struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);2384	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);2385	int rc;2386 2387	ext_attr = (struct drxj_data *) demod->my_ext_attr;2388	common_attr = (struct drx_common_attr *) demod->my_common_attr;2389	dev_addr = demod->my_i2c_dev_addr;2390 2391	/* PATCH for bug 5003, HI ucode v3.1.0 */2392	rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);2393	if (rc != 0) {2394		pr_err("error %d\n", rc);2395		goto rw_error;2396	}2397 2398	/* Timing div, 250ns/Psys */2399	/* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */2400	ext_attr->hi_cfg_timing_div =2401	    (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;2402	/* Clipping */2403	if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)2404		ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;2405	/* Bridge delay, uses oscilator clock */2406	/* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */2407	/* SDA brdige delay */2408	ext_attr->hi_cfg_bridge_delay =2409	    (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /2410	    1000;2411	/* Clipping */2412	if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)2413		ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;2414	/* SCL bridge delay, same as SDA for now */2415	ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<2416				      SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);2417	/* Wakeup key, setting the read flag (as suggest in the documentation) does2418	   not always result into a working solution (barebones worked VI2C failed).2419	   Not setting the bit works in all cases . */2420	ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;2421	/* port/bridge/power down ctrl */2422	ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);2423	/* transit mode time out delay and watch dog divider */2424	ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;2425 2426	rc = hi_cfg_command(demod);2427	if (rc != 0) {2428		pr_err("error %d\n", rc);2429		goto rw_error;2430	}2431 2432	return 0;2433 2434rw_error:2435	return rc;2436}2437 2438/*============================================================================*/2439/*==                   END HOST INTERFACE FUNCTIONS                         ==*/2440/*============================================================================*/2441 2442/*============================================================================*/2443/*============================================================================*/2444/*==                        AUXILIARY FUNCTIONS                             ==*/2445/*============================================================================*/2446/*============================================================================*/2447 2448/*2449* \fn int get_device_capabilities()2450* \brief Get and store device capabilities.2451* \param demod  Pointer to demodulator instance.2452* \return int.2453* \return 0    Success2454* \retval -EIO Failure2455*2456* Depending on pulldowns on MDx pins the following internals are set:2457*  * common_attr->osc_clock_freq2458*  * ext_attr->has_lna2459*  * ext_attr->has_ntsc2460*  * ext_attr->has_btsc2461*  * ext_attr->has_oob2462*2463*/2464static int get_device_capabilities(struct drx_demod_instance *demod)2465{2466	struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);2467	struct drxj_data *ext_attr = (struct drxj_data *) NULL;2468	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);2469	u16 sio_pdr_ohw_cfg = 0;2470	u32 sio_top_jtagid_lo = 0;2471	u16 bid = 0;2472	int rc;2473 2474	common_attr = (struct drx_common_attr *) demod->my_common_attr;2475	ext_attr = (struct drxj_data *) demod->my_ext_attr;2476	dev_addr = demod->my_i2c_dev_addr;2477 2478	rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);2479	if (rc != 0) {2480		pr_err("error %d\n", rc);2481		goto rw_error;2482	}2483	rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);2484	if (rc != 0) {2485		pr_err("error %d\n", rc);2486		goto rw_error;2487	}2488	rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);2489	if (rc != 0) {2490		pr_err("error %d\n", rc);2491		goto rw_error;2492	}2493 2494	switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {2495	case 0:2496		/* ignore (bypass ?) */2497		break;2498	case 1:2499		/* 27 MHz */2500		common_attr->osc_clock_freq = 27000;2501		break;2502	case 2:2503		/* 20.25 MHz */2504		common_attr->osc_clock_freq = 20250;2505		break;2506	case 3:2507		/* 4 MHz */2508		common_attr->osc_clock_freq = 4000;2509		break;2510	default:2511		return -EIO;2512	}2513 2514	/*2515	   Determine device capabilities2516	   Based on pinning v472517	 */2518	rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);2519	if (rc != 0) {2520		pr_err("error %d\n", rc);2521		goto rw_error;2522	}2523	ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);2524 2525	switch ((sio_top_jtagid_lo >> 12) & 0xFF) {2526	case 0x31:2527		rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);2528		if (rc != 0) {2529			pr_err("error %d\n", rc);2530			goto rw_error;2531		}2532		rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);2533		if (rc != 0) {2534			pr_err("error %d\n", rc);2535			goto rw_error;2536		}2537		bid = (bid >> 10) & 0xf;2538		rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);2539		if (rc != 0) {2540			pr_err("error %d\n", rc);2541			goto rw_error;2542		}2543 2544		ext_attr->has_lna = true;2545		ext_attr->has_ntsc = false;2546		ext_attr->has_btsc = false;2547		ext_attr->has_oob = false;2548		ext_attr->has_smatx = true;2549		ext_attr->has_smarx = false;2550		ext_attr->has_gpio = false;2551		ext_attr->has_irqn = false;2552		break;2553	case 0x33:2554		ext_attr->has_lna = false;2555		ext_attr->has_ntsc = false;2556		ext_attr->has_btsc = false;2557		ext_attr->has_oob = false;2558		ext_attr->has_smatx = true;2559		ext_attr->has_smarx = false;2560		ext_attr->has_gpio = false;2561		ext_attr->has_irqn = false;2562		break;2563	case 0x45:2564		ext_attr->has_lna = true;2565		ext_attr->has_ntsc = true;2566		ext_attr->has_btsc = false;2567		ext_attr->has_oob = false;2568		ext_attr->has_smatx = true;2569		ext_attr->has_smarx = true;2570		ext_attr->has_gpio = true;2571		ext_attr->has_irqn = false;2572		break;2573	case 0x46:2574		ext_attr->has_lna = false;2575		ext_attr->has_ntsc = true;2576		ext_attr->has_btsc = false;2577		ext_attr->has_oob = false;2578		ext_attr->has_smatx = true;2579		ext_attr->has_smarx = true;2580		ext_attr->has_gpio = true;2581		ext_attr->has_irqn = false;2582		break;2583	case 0x41:2584		ext_attr->has_lna = true;2585		ext_attr->has_ntsc = true;2586		ext_attr->has_btsc = true;2587		ext_attr->has_oob = false;2588		ext_attr->has_smatx = true;2589		ext_attr->has_smarx = true;2590		ext_attr->has_gpio = true;2591		ext_attr->has_irqn = false;2592		break;2593	case 0x43:2594		ext_attr->has_lna = false;2595		ext_attr->has_ntsc = true;2596		ext_attr->has_btsc = true;2597		ext_attr->has_oob = false;2598		ext_attr->has_smatx = true;2599		ext_attr->has_smarx = true;2600		ext_attr->has_gpio = true;2601		ext_attr->has_irqn = false;2602		break;2603	case 0x32:2604		ext_attr->has_lna = true;2605		ext_attr->has_ntsc = false;2606		ext_attr->has_btsc = false;2607		ext_attr->has_oob = true;2608		ext_attr->has_smatx = true;2609		ext_attr->has_smarx = true;2610		ext_attr->has_gpio = true;2611		ext_attr->has_irqn = true;2612		break;2613	case 0x34:2614		ext_attr->has_lna = false;2615		ext_attr->has_ntsc = true;2616		ext_attr->has_btsc = true;2617		ext_attr->has_oob = true;2618		ext_attr->has_smatx = true;2619		ext_attr->has_smarx = true;2620		ext_attr->has_gpio = true;2621		ext_attr->has_irqn = true;2622		break;2623	case 0x42:2624		ext_attr->has_lna = true;2625		ext_attr->has_ntsc = true;2626		ext_attr->has_btsc = true;2627		ext_attr->has_oob = true;2628		ext_attr->has_smatx = true;2629		ext_attr->has_smarx = true;2630		ext_attr->has_gpio = true;2631		ext_attr->has_irqn = true;2632		break;2633	case 0x44:2634		ext_attr->has_lna = false;2635		ext_attr->has_ntsc = true;2636		ext_attr->has_btsc = true;2637		ext_attr->has_oob = true;2638		ext_attr->has_smatx = true;2639		ext_attr->has_smarx = true;2640		ext_attr->has_gpio = true;2641		ext_attr->has_irqn = true;2642		break;2643	default:2644		/* Unknown device variant */2645		return -EIO;2646		break;2647	}2648 2649	return 0;2650rw_error:2651	return rc;2652}2653 2654/*2655* \fn int power_up_device()2656* \brief Power up device.2657* \param demod  Pointer to demodulator instance.2658* \return int.2659* \return 0    Success2660* \retval -EIO Failure, I2C or max retries reached2661*2662*/2663 2664#ifndef DRXJ_MAX_RETRIES_POWERUP2665#define DRXJ_MAX_RETRIES_POWERUP 102666#endif2667 2668static int power_up_device(struct drx_demod_instance *demod)2669{2670	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);2671	u8 data = 0;2672	u16 retry_count = 0;2673	struct i2c_device_addr wake_up_addr;2674 2675	dev_addr = demod->my_i2c_dev_addr;2676	wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;2677	wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;2678	wake_up_addr.user_data = dev_addr->user_data;2679	/*2680	 * I2C access may fail in this case: no ack2681	 * dummy write must be used to wake uop device, dummy read must be used to2682	 * reset HI state machine (avoiding actual writes)2683	 */2684	do {2685		data = 0;2686		drxbsp_i2c_write_read(&wake_up_addr, 1, &data,2687				      (struct i2c_device_addr *)(NULL), 0,2688				     (u8 *)(NULL));2689		msleep(10);2690		retry_count++;2691	} while ((drxbsp_i2c_write_read2692		  ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,2693		   &data)2694		  != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));2695 2696	/* Need some recovery time .... */2697	msleep(10);2698 2699	if (retry_count == DRXJ_MAX_RETRIES_POWERUP)2700		return -EIO;2701 2702	return 0;2703}2704 2705/*----------------------------------------------------------------------------*/2706/* MPEG Output Configuration Functions - begin                                */2707/*----------------------------------------------------------------------------*/2708/*2709* \fn int ctrl_set_cfg_mpeg_output()2710* \brief Set MPEG output configuration of the device.2711* \param devmod  Pointer to demodulator instance.2712* \param cfg_data Pointer to mpeg output configuaration.2713* \return int.2714*2715*  Configure MPEG output parameters.2716*2717*/2718static int2719ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)2720{2721	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);2722	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);2723	struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);2724	int rc;2725	u16 fec_oc_reg_mode = 0;2726	u16 fec_oc_reg_ipr_mode = 0;2727	u16 fec_oc_reg_ipr_invert = 0;2728	u32 max_bit_rate = 0;2729	u32 rcn_rate = 0;2730	u32 nr_bits = 0;2731	u16 sio_pdr_md_cfg = 0;2732	/* data mask for the output data byte */2733	u16 invert_data_mask =2734	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |2735	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |2736	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |2737	    FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;2738 2739	/* check arguments */2740	if ((demod == NULL) || (cfg_data == NULL))2741		return -EINVAL;2742 2743	dev_addr = demod->my_i2c_dev_addr;2744	ext_attr = (struct drxj_data *) demod->my_ext_attr;2745	common_attr = (struct drx_common_attr *) demod->my_common_attr;2746 2747	if (cfg_data->enable_mpeg_output == true) {2748		/* quick and dirty patch to set MPEG in case current std is not2749		   producing MPEG */2750		switch (ext_attr->standard) {2751		case DRX_STANDARD_8VSB:2752		case DRX_STANDARD_ITU_A:2753		case DRX_STANDARD_ITU_B:2754		case DRX_STANDARD_ITU_C:2755			break;2756		default:2757			return 0;2758		}2759 2760		rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);2761		if (rc != 0) {2762			pr_err("error %d\n", rc);2763			goto rw_error;2764		}2765		switch (ext_attr->standard) {2766		case DRX_STANDARD_8VSB:2767			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);2768			if (rc != 0) {2769				pr_err("error %d\n", rc);2770				goto rw_error;2771			}	/* 2048 bytes fifo ram */2772			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);2773			if (rc != 0) {2774				pr_err("error %d\n", rc);2775				goto rw_error;2776			}2777			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);2778			if (rc != 0) {2779				pr_err("error %d\n", rc);2780				goto rw_error;2781			}2782			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);2783			if (rc != 0) {2784				pr_err("error %d\n", rc);2785				goto rw_error;2786			}2787			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);2788			if (rc != 0) {2789				pr_err("error %d\n", rc);2790				goto rw_error;2791			}2792			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);2793			if (rc != 0) {2794				pr_err("error %d\n", rc);2795				goto rw_error;2796			}2797			/* Low Water Mark for synchronization  */2798			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);2799			if (rc != 0) {2800				pr_err("error %d\n", rc);2801				goto rw_error;2802			}2803			/* High Water Mark for synchronization */2804			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);2805			if (rc != 0) {2806				pr_err("error %d\n", rc);2807				goto rw_error;2808			}2809			break;2810		case DRX_STANDARD_ITU_A:2811		case DRX_STANDARD_ITU_C:2812			switch (ext_attr->constellation) {2813			case DRX_CONSTELLATION_QAM256:2814				nr_bits = 8;2815				break;2816			case DRX_CONSTELLATION_QAM128:2817				nr_bits = 7;2818				break;2819			case DRX_CONSTELLATION_QAM64:2820				nr_bits = 6;2821				break;2822			case DRX_CONSTELLATION_QAM32:2823				nr_bits = 5;2824				break;2825			case DRX_CONSTELLATION_QAM16:2826				nr_bits = 4;2827				break;2828			default:2829				return -EIO;2830			}	/* ext_attr->constellation */2831			/* max_bit_rate = symbol_rate * nr_bits * coef */2832			/* coef = 188/204                          */2833			max_bit_rate =2834			    (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;2835			fallthrough;	/* as b/c Annex A/C need following settings */2836		case DRX_STANDARD_ITU_B:2837			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);2838			if (rc != 0) {2839				pr_err("error %d\n", rc);2840				goto rw_error;2841			}2842			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);2843			if (rc != 0) {2844				pr_err("error %d\n", rc);2845				goto rw_error;2846			}2847			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);2848			if (rc != 0) {2849				pr_err("error %d\n", rc);2850				goto rw_error;2851			}2852			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);2853			if (rc != 0) {2854				pr_err("error %d\n", rc);2855				goto rw_error;2856			}2857			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);2858			if (rc != 0) {2859				pr_err("error %d\n", rc);2860				goto rw_error;2861			}2862			if (cfg_data->static_clk == true) {2863				rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);2864				if (rc != 0) {2865					pr_err("error %d\n", rc);2866					goto rw_error;2867				}2868			} else {2869				rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);2870				if (rc != 0) {2871					pr_err("error %d\n", rc);2872					goto rw_error;2873				}2874			}2875			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);2876			if (rc != 0) {2877				pr_err("error %d\n", rc);2878				goto rw_error;2879			}2880			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);2881			if (rc != 0) {2882				pr_err("error %d\n", rc);2883				goto rw_error;2884			}2885			break;2886		default:2887			break;2888		}		/* switch (standard) */2889 2890		/* Check insertion of the Reed-Solomon parity bytes */2891		rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);2892		if (rc != 0) {2893			pr_err("error %d\n", rc);2894			goto rw_error;2895		}2896		rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);2897		if (rc != 0) {2898			pr_err("error %d\n", rc);2899			goto rw_error;2900		}2901		if (cfg_data->insert_rs_byte == true) {2902			/* enable parity symbol forward */2903			fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;2904			/* MVAL disable during parity bytes */2905			fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;2906			switch (ext_attr->standard) {2907			case DRX_STANDARD_8VSB:2908				rcn_rate = 0x004854D3;2909				break;2910			case DRX_STANDARD_ITU_B:2911				fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;2912				switch (ext_attr->constellation) {2913				case DRX_CONSTELLATION_QAM256:2914					rcn_rate = 0x008945E7;2915					break;2916				case DRX_CONSTELLATION_QAM64:2917					rcn_rate = 0x005F64D4;2918					break;2919				default:2920					return -EIO;2921				}2922				break;2923			case DRX_STANDARD_ITU_A:2924			case DRX_STANDARD_ITU_C:2925				/* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */2926				rcn_rate =2927				    (frac282928				     (max_bit_rate,2929				      (u32) (common_attr->sys_clock_freq / 8))) /2930				    188;2931				break;2932			default:2933				return -EIO;2934			}	/* ext_attr->standard */2935		} else {	/* insert_rs_byte == false */2936 2937			/* disable parity symbol forward */2938			fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);2939			/* MVAL enable during parity bytes */2940			fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);2941			switch (ext_attr->standard) {2942			case DRX_STANDARD_8VSB:2943				rcn_rate = 0x0041605C;2944				break;2945			case DRX_STANDARD_ITU_B:2946				fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);2947				switch (ext_attr->constellation) {2948				case DRX_CONSTELLATION_QAM256:2949					rcn_rate = 0x0082D6A0;2950					break;2951				case DRX_CONSTELLATION_QAM64:2952					rcn_rate = 0x005AEC1A;2953					break;2954				default:2955					return -EIO;2956				}2957				break;2958			case DRX_STANDARD_ITU_A:2959			case DRX_STANDARD_ITU_C:2960				/* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */2961				rcn_rate =2962				    (frac282963				     (max_bit_rate,2964				      (u32) (common_attr->sys_clock_freq / 8))) /2965				    204;2966				break;2967			default:2968				return -EIO;2969			}	/* ext_attr->standard */2970		}2971 2972		if (cfg_data->enable_parallel == true) {	/* MPEG data output is parallel -> clear ipr_mode[0] */2973			fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));2974		} else {	/* MPEG data output is serial -> set ipr_mode[0] */2975			fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;2976		}2977 2978		/* Control slective inversion of output bits */2979		if (cfg_data->invert_data == true)2980			fec_oc_reg_ipr_invert |= invert_data_mask;2981		else2982			fec_oc_reg_ipr_invert &= (~(invert_data_mask));2983 2984		if (cfg_data->invert_err == true)2985			fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;2986		else2987			fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));2988 2989		if (cfg_data->invert_str == true)2990			fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;2991		else2992			fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));2993 2994		if (cfg_data->invert_val == true)2995			fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;2996		else2997			fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));2998 2999		if (cfg_data->invert_clk == true)3000			fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;3001		else3002			fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));3003 3004 3005		if (cfg_data->static_clk == true) {	/* Static mode */3006			u32 dto_rate = 0;3007			u32 bit_rate = 0;3008			u16 fec_oc_dto_burst_len = 0;3009			u16 fec_oc_dto_period = 0;3010 3011			fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;3012 3013			switch (ext_attr->standard) {3014			case DRX_STANDARD_8VSB:3015				fec_oc_dto_period = 4;3016				if (cfg_data->insert_rs_byte == true)3017					fec_oc_dto_burst_len = 208;3018				break;3019			case DRX_STANDARD_ITU_A:3020				{3021					u32 symbol_rate_th = 6400000;3022					if (cfg_data->insert_rs_byte == true) {3023						fec_oc_dto_burst_len = 204;3024						symbol_rate_th = 5900000;3025					}3026					if (ext_attr->curr_symbol_rate >=3027					    symbol_rate_th) {3028						fec_oc_dto_period = 0;3029					} else {3030						fec_oc_dto_period = 1;3031					}3032				}3033				break;3034			case DRX_STANDARD_ITU_B:3035				fec_oc_dto_period = 1;3036				if (cfg_data->insert_rs_byte == true)3037					fec_oc_dto_burst_len = 128;3038				break;3039			case DRX_STANDARD_ITU_C:3040				fec_oc_dto_period = 1;3041				if (cfg_data->insert_rs_byte == true)3042					fec_oc_dto_burst_len = 204;3043				break;3044			default:3045				return -EIO;3046			}3047			bit_rate =3048			    common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +3049							       2);3050			dto_rate =3051			    frac28(bit_rate, common_attr->sys_clock_freq * 1000);3052			dto_rate >>= 3;3053			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);3054			if (rc != 0) {3055				pr_err("error %d\n", rc);3056				goto rw_error;3057			}3058			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);3059			if (rc != 0) {3060				pr_err("error %d\n", rc);3061				goto rw_error;3062			}3063			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);3064			if (rc != 0) {3065				pr_err("error %d\n", rc);3066				goto rw_error;3067			}3068			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);3069			if (rc != 0) {3070				pr_err("error %d\n", rc);3071				goto rw_error;3072			}3073			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);3074			if (rc != 0) {3075				pr_err("error %d\n", rc);3076				goto rw_error;3077			}3078			if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)3079				fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;3080			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);3081			if (rc != 0) {3082				pr_err("error %d\n", rc);3083				goto rw_error;3084			}3085		} else {	/* Dynamic mode */3086 3087			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);3088			if (rc != 0) {3089				pr_err("error %d\n", rc);3090				goto rw_error;3091			}3092			rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);3093			if (rc != 0) {3094				pr_err("error %d\n", rc);3095				goto rw_error;3096			}3097		}3098 3099		rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);3100		if (rc != 0) {3101			pr_err("error %d\n", rc);3102			goto rw_error;3103		}3104 3105		/* Write appropriate registers with requested configuration */3106		rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);3107		if (rc != 0) {3108			pr_err("error %d\n", rc);3109			goto rw_error;3110		}3111		rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);3112		if (rc != 0) {3113			pr_err("error %d\n", rc);3114			goto rw_error;3115		}3116		rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);3117		if (rc != 0) {3118			pr_err("error %d\n", rc);3119			goto rw_error;3120		}3121 3122		/* enabling for both parallel and serial now */3123		/*  Write magic word to enable pdr reg write */3124		rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);3125		if (rc != 0) {3126			pr_err("error %d\n", rc);3127			goto rw_error;3128		}3129		/*  Set MPEG TS pads to outputmode */3130		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);3131		if (rc != 0) {3132			pr_err("error %d\n", rc);3133			goto rw_error;3134		}3135		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);3136		if (rc != 0) {3137			pr_err("error %d\n", rc);3138			goto rw_error;3139		}3140		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);3141		if (rc != 0) {3142			pr_err("error %d\n", rc);3143			goto rw_error;3144		}3145		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);3146		if (rc != 0) {3147			pr_err("error %d\n", rc);3148			goto rw_error;3149		}3150		sio_pdr_md_cfg =3151		    MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<3152		    SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;3153		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);3154		if (rc != 0) {3155			pr_err("error %d\n", rc);3156			goto rw_error;3157		}3158		if (cfg_data->enable_parallel == true) {	/* MPEG data output is parallel -> set MD1 to MD7 to output mode */3159			sio_pdr_md_cfg =3160			    MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<3161			    SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<3162			    SIO_PDR_MD0_CFG_MODE__B;3163			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);3164			if (rc != 0) {3165				pr_err("error %d\n", rc);3166				goto rw_error;3167			}3168			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);3169			if (rc != 0) {3170				pr_err("error %d\n", rc);3171				goto rw_error;3172			}3173			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);3174			if (rc != 0) {3175				pr_err("error %d\n", rc);3176				goto rw_error;3177			}3178			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);3179			if (rc != 0) {3180				pr_err("error %d\n", rc);3181				goto rw_error;3182			}3183			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);3184			if (rc != 0) {3185				pr_err("error %d\n", rc);3186				goto rw_error;3187			}3188			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);3189			if (rc != 0) {3190				pr_err("error %d\n", rc);3191				goto rw_error;3192			}3193			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);3194			if (rc != 0) {3195				pr_err("error %d\n", rc);3196				goto rw_error;3197			}3198			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);3199			if (rc != 0) {3200				pr_err("error %d\n", rc);3201				goto rw_error;3202			}3203		} else {	/* MPEG data output is serial -> set MD1 to MD7 to tri-state */3204			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);3205			if (rc != 0) {3206				pr_err("error %d\n", rc);3207				goto rw_error;3208			}3209			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);3210			if (rc != 0) {3211				pr_err("error %d\n", rc);3212				goto rw_error;3213			}3214			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);3215			if (rc != 0) {3216				pr_err("error %d\n", rc);3217				goto rw_error;3218			}3219			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);3220			if (rc != 0) {3221				pr_err("error %d\n", rc);3222				goto rw_error;3223			}3224			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);3225			if (rc != 0) {3226				pr_err("error %d\n", rc);3227				goto rw_error;3228			}3229			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);3230			if (rc != 0) {3231				pr_err("error %d\n", rc);3232				goto rw_error;3233			}3234			rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);3235			if (rc != 0) {3236				pr_err("error %d\n", rc);3237				goto rw_error;3238			}3239		}3240		/*  Enable Monitor Bus output over MPEG pads and ctl input */3241		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);3242		if (rc != 0) {3243			pr_err("error %d\n", rc);3244			goto rw_error;3245		}3246		/*  Write nomagic word to enable pdr reg write */3247		rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);3248		if (rc != 0) {3249			pr_err("error %d\n", rc);3250			goto rw_error;3251		}3252	} else {3253		/*  Write magic word to enable pdr reg write */3254		rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);3255		if (rc != 0) {3256			pr_err("error %d\n", rc);3257			goto rw_error;3258		}3259		/*  Set MPEG TS pads to inputmode */3260		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);3261		if (rc != 0) {3262			pr_err("error %d\n", rc);3263			goto rw_error;3264		}3265		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);3266		if (rc != 0) {3267			pr_err("error %d\n", rc);3268			goto rw_error;3269		}3270		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);3271		if (rc != 0) {3272			pr_err("error %d\n", rc);3273			goto rw_error;3274		}3275		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);3276		if (rc != 0) {3277			pr_err("error %d\n", rc);3278			goto rw_error;3279		}3280		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);3281		if (rc != 0) {3282			pr_err("error %d\n", rc);3283			goto rw_error;3284		}3285		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);3286		if (rc != 0) {3287			pr_err("error %d\n", rc);3288			goto rw_error;3289		}3290		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);3291		if (rc != 0) {3292			pr_err("error %d\n", rc);3293			goto rw_error;3294		}3295		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);3296		if (rc != 0) {3297			pr_err("error %d\n", rc);3298			goto rw_error;3299		}3300		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);3301		if (rc != 0) {3302			pr_err("error %d\n", rc);3303			goto rw_error;3304		}3305		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);3306		if (rc != 0) {3307			pr_err("error %d\n", rc);3308			goto rw_error;3309		}3310		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);3311		if (rc != 0) {3312			pr_err("error %d\n", rc);3313			goto rw_error;3314		}3315		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);3316		if (rc != 0) {3317			pr_err("error %d\n", rc);3318			goto rw_error;3319		}3320		/* Enable Monitor Bus output over MPEG pads and ctl input */3321		rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);3322		if (rc != 0) {3323			pr_err("error %d\n", rc);3324			goto rw_error;3325		}3326		/* Write nomagic word to enable pdr reg write */3327		rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);3328		if (rc != 0) {3329			pr_err("error %d\n", rc);3330			goto rw_error;3331		}3332	}3333 3334	/* save values for restore after re-acquire */3335	common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;3336 3337	return 0;3338rw_error:3339	return rc;3340}3341 3342/*----------------------------------------------------------------------------*/3343 3344 3345/*----------------------------------------------------------------------------*/3346/* MPEG Output Configuration Functions - end                                  */3347/*----------------------------------------------------------------------------*/3348 3349/*----------------------------------------------------------------------------*/3350/* miscellaneous configurations - begin                           */3351/*----------------------------------------------------------------------------*/3352 3353/*3354* \fn int set_mpegtei_handling()3355* \brief Activate MPEG TEI handling settings.3356* \param devmod  Pointer to demodulator instance.3357* \return int.3358*3359* This routine should be called during a set channel of QAM/VSB3360*3361*/3362static int set_mpegtei_handling(struct drx_demod_instance *demod)3363{3364	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);3365	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);3366	int rc;3367	u16 fec_oc_dpr_mode = 0;3368	u16 fec_oc_snc_mode = 0;3369	u16 fec_oc_ems_mode = 0;3370 3371	dev_addr = demod->my_i2c_dev_addr;3372	ext_attr = (struct drxj_data *) demod->my_ext_attr;3373 3374	rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);3375	if (rc != 0) {3376		pr_err("error %d\n", rc);3377		goto rw_error;3378	}3379	rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);3380	if (rc != 0) {3381		pr_err("error %d\n", rc);3382		goto rw_error;3383	}3384	rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);3385	if (rc != 0) {3386		pr_err("error %d\n", rc);3387		goto rw_error;3388	}3389 3390	/* reset to default, allow TEI bit to be changed */3391	fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);3392	fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |3393			   FEC_OC_SNC_MODE_CORR_DISABLE__M));3394	fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);3395 3396	if (ext_attr->disable_te_ihandling) {3397		/* do not change TEI bit */3398		fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;3399		fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |3400		    ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));3401		fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));3402	}3403 3404	rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);3405	if (rc != 0) {3406		pr_err("error %d\n", rc);3407		goto rw_error;3408	}3409	rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);3410	if (rc != 0) {3411		pr_err("error %d\n", rc);3412		goto rw_error;3413	}3414	rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);3415	if (rc != 0) {3416		pr_err("error %d\n", rc);3417		goto rw_error;3418	}3419 3420	return 0;3421rw_error:3422	return rc;3423}3424 3425/*----------------------------------------------------------------------------*/3426/*3427* \fn int bit_reverse_mpeg_output()3428* \brief Set MPEG output bit-endian settings.3429* \param devmod  Pointer to demodulator instance.3430* \return int.3431*3432* This routine should be called during a set channel of QAM/VSB3433*3434*/3435static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)3436{3437	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);3438	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);3439	int rc;3440	u16 fec_oc_ipr_mode = 0;3441 3442	dev_addr = demod->my_i2c_dev_addr;3443	ext_attr = (struct drxj_data *) demod->my_ext_attr;3444 3445	rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);3446	if (rc != 0) {3447		pr_err("error %d\n", rc);3448		goto rw_error;3449	}3450 3451	/* reset to default (normal bit order) */3452	fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);3453 3454	if (ext_attr->bit_reverse_mpeg_outout)3455		fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;3456 3457	rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);3458	if (rc != 0) {3459		pr_err("error %d\n", rc);3460		goto rw_error;3461	}3462 3463	return 0;3464rw_error:3465	return rc;3466}3467 3468/*----------------------------------------------------------------------------*/3469/*3470* \fn int set_mpeg_start_width()3471* \brief Set MPEG start width.3472* \param devmod  Pointer to demodulator instance.3473* \return int.3474*3475* This routine should be called during a set channel of QAM/VSB3476*3477*/3478static int set_mpeg_start_width(struct drx_demod_instance *demod)3479{3480	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);3481	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);3482	struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;3483	int rc;3484	u16 fec_oc_comm_mb = 0;3485 3486	dev_addr = demod->my_i2c_dev_addr;3487	ext_attr = (struct drxj_data *) demod->my_ext_attr;3488	common_attr = demod->my_common_attr;3489 3490	if ((common_attr->mpeg_cfg.static_clk == true)3491	    && (common_attr->mpeg_cfg.enable_parallel == false)) {3492		rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);3493		if (rc != 0) {3494			pr_err("error %d\n", rc);3495			goto rw_error;3496		}3497		fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;3498		if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)3499			fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;3500		rc = drxj_dap_write_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	}3506 3507	return 0;3508rw_error:3509	return rc;3510}3511 3512/*----------------------------------------------------------------------------*/3513/* miscellaneous configurations - end                             */3514/*----------------------------------------------------------------------------*/3515 3516/*----------------------------------------------------------------------------*/3517/* UIO Configuration Functions - begin                                        */3518/*----------------------------------------------------------------------------*/3519/*3520* \fn int ctrl_set_uio_cfg()3521* \brief Configure modus oprandi UIO.3522* \param demod Pointer to demodulator instance.3523* \param uio_cfg Pointer to a configuration setting for a certain UIO.3524* \return int.3525*/3526static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)3527{3528	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);3529	int rc;3530 3531	if ((uio_cfg == NULL) || (demod == NULL))3532		return -EINVAL;3533 3534	ext_attr = (struct drxj_data *) demod->my_ext_attr;3535 3536	/*  Write magic word to enable pdr reg write               */3537	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);3538	if (rc != 0) {3539		pr_err("error %d\n", rc);3540		goto rw_error;3541	}3542	switch (uio_cfg->uio) {3543      /*====================================================================*/3544	case DRX_UIO1:3545		/* DRX_UIO1: SMA_TX UIO-1 */3546		if (!ext_attr->has_smatx)3547			return -EIO;3548		switch (uio_cfg->mode) {3549		case DRX_UIO_MODE_FIRMWARE_SMA:3550		case DRX_UIO_MODE_FIRMWARE_SAW:3551		case DRX_UIO_MODE_READWRITE:3552			ext_attr->uio_sma_tx_mode = uio_cfg->mode;3553			break;3554		case DRX_UIO_MODE_DISABLE:3555			ext_attr->uio_sma_tx_mode = uio_cfg->mode;3556			/* pad configuration register is set 0 - input mode */3557			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);3558			if (rc != 0) {3559				pr_err("error %d\n", rc);3560				goto rw_error;3561			}3562			break;3563		default:3564			return -EINVAL;3565		}		/* switch ( uio_cfg->mode ) */3566		break;3567      /*====================================================================*/3568	case DRX_UIO2:3569		/* DRX_UIO2: SMA_RX UIO-2 */3570		if (!ext_attr->has_smarx)3571			return -EIO;3572		switch (uio_cfg->mode) {3573		case DRX_UIO_MODE_FIRMWARE0:3574		case DRX_UIO_MODE_READWRITE:3575			ext_attr->uio_sma_rx_mode = uio_cfg->mode;3576			break;3577		case DRX_UIO_MODE_DISABLE:3578			ext_attr->uio_sma_rx_mode = uio_cfg->mode;3579			/* pad configuration register is set 0 - input mode */3580			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);3581			if (rc != 0) {3582				pr_err("error %d\n", rc);3583				goto rw_error;3584			}3585			break;3586		default:3587			return -EINVAL;3588		}		/* switch ( uio_cfg->mode ) */3589		break;3590      /*====================================================================*/3591	case DRX_UIO3:3592		/* DRX_UIO3: GPIO UIO-3 */3593		if (!ext_attr->has_gpio)3594			return -EIO;3595		switch (uio_cfg->mode) {3596		case DRX_UIO_MODE_FIRMWARE0:3597		case DRX_UIO_MODE_READWRITE:3598			ext_attr->uio_gpio_mode = uio_cfg->mode;3599			break;3600		case DRX_UIO_MODE_DISABLE:3601			ext_attr->uio_gpio_mode = uio_cfg->mode;3602			/* pad configuration register is set 0 - input mode */3603			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);3604			if (rc != 0) {3605				pr_err("error %d\n", rc);3606				goto rw_error;3607			}3608			break;3609		default:3610			return -EINVAL;3611		}		/* switch ( uio_cfg->mode ) */3612		break;3613      /*====================================================================*/3614	case DRX_UIO4:3615		/* DRX_UIO4: IRQN UIO-4 */3616		if (!ext_attr->has_irqn)3617			return -EIO;3618		switch (uio_cfg->mode) {3619		case DRX_UIO_MODE_READWRITE:3620			ext_attr->uio_irqn_mode = uio_cfg->mode;3621			break;3622		case DRX_UIO_MODE_DISABLE:3623			/* pad configuration register is set 0 - input mode */3624			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);3625			if (rc != 0) {3626				pr_err("error %d\n", rc);3627				goto rw_error;3628			}3629			ext_attr->uio_irqn_mode = uio_cfg->mode;3630			break;3631		case DRX_UIO_MODE_FIRMWARE0:3632		default:3633			return -EINVAL;3634		}		/* switch ( uio_cfg->mode ) */3635		break;3636      /*====================================================================*/3637	default:3638		return -EINVAL;3639	}			/* switch ( uio_cfg->uio ) */3640 3641	/*  Write magic word to disable pdr reg write               */3642	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);3643	if (rc != 0) {3644		pr_err("error %d\n", rc);3645		goto rw_error;3646	}3647 3648	return 0;3649rw_error:3650	return rc;3651}3652 3653/*3654* \fn int ctrl_uio_write()3655* \brief Write to a UIO.3656* \param demod Pointer to demodulator instance.3657* \param uio_data Pointer to data container for a certain UIO.3658* \return int.3659*/3660static int3661ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)3662{3663	struct drxj_data *ext_attr = (struct drxj_data *) (NULL);3664	int rc;3665	u16 pin_cfg_value = 0;3666	u16 value = 0;3667 3668	if ((uio_data == NULL) || (demod == NULL))3669		return -EINVAL;3670 3671	ext_attr = (struct drxj_data *) demod->my_ext_attr;3672 3673	/*  Write magic word to enable pdr reg write               */3674	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);3675	if (rc != 0) {3676		pr_err("error %d\n", rc);3677		goto rw_error;3678	}3679	switch (uio_data->uio) {3680      /*====================================================================*/3681	case DRX_UIO1:3682		/* DRX_UIO1: SMA_TX UIO-1 */3683		if (!ext_attr->has_smatx)3684			return -EIO;3685		if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)3686		    && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {3687			return -EIO;3688		}3689		pin_cfg_value = 0;3690		/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */3691		pin_cfg_value |= 0x0113;3692		/* io_pad_cfg_mode output mode is drive always */3693		/* io_pad_cfg_drive is set to power 2 (23 mA) */3694 3695		/* write to io pad configuration register - output mode */3696		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);3697		if (rc != 0) {3698			pr_err("error %d\n", rc);3699			goto rw_error;3700		}3701 3702		/* use corresponding bit in io data output registar */3703		rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);3704		if (rc != 0) {3705			pr_err("error %d\n", rc);3706			goto rw_error;3707		}3708		if (!uio_data->value)3709			value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */3710		else3711			value |= 0x8000;	/* write one to 15th bit - 1st UIO */3712 3713		/* write back to io data output register */3714		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);3715		if (rc != 0) {3716			pr_err("error %d\n", rc);3717			goto rw_error;3718		}3719		break;3720   /*======================================================================*/3721	case DRX_UIO2:3722		/* DRX_UIO2: SMA_RX UIO-2 */3723		if (!ext_attr->has_smarx)3724			return -EIO;3725		if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)3726			return -EIO;3727 3728		pin_cfg_value = 0;3729		/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */3730		pin_cfg_value |= 0x0113;3731		/* io_pad_cfg_mode output mode is drive always */3732		/* io_pad_cfg_drive is set to power 2 (23 mA) */3733 3734		/* write to io pad configuration register - output mode */3735		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);3736		if (rc != 0) {3737			pr_err("error %d\n", rc);3738			goto rw_error;3739		}3740 3741		/* use corresponding bit in io data output registar */3742		rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);3743		if (rc != 0) {3744			pr_err("error %d\n", rc);3745			goto rw_error;3746		}3747		if (!uio_data->value)3748			value &= 0xBFFF;	/* write zero to 14th bit - 2nd UIO */3749		else3750			value |= 0x4000;	/* write one to 14th bit - 2nd UIO */3751 3752		/* write back to io data output register */3753		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);3754		if (rc != 0) {3755			pr_err("error %d\n", rc);3756			goto rw_error;3757		}3758		break;3759   /*====================================================================*/3760	case DRX_UIO3:3761		/* DRX_UIO3: ASEL UIO-3 */3762		if (!ext_attr->has_gpio)3763			return -EIO;3764		if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)3765			return -EIO;3766 3767		pin_cfg_value = 0;3768		/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */3769		pin_cfg_value |= 0x0113;3770		/* io_pad_cfg_mode output mode is drive always */3771		/* io_pad_cfg_drive is set to power 2 (23 mA) */3772 3773		/* write to io pad configuration register - output mode */3774		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);3775		if (rc != 0) {3776			pr_err("error %d\n", rc);3777			goto rw_error;3778		}3779 3780		/* use corresponding bit in io data output registar */3781		rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);3782		if (rc != 0) {3783			pr_err("error %d\n", rc);3784			goto rw_error;3785		}3786		if (!uio_data->value)3787			value &= 0xFFFB;	/* write zero to 2nd bit - 3rd UIO */3788		else3789			value |= 0x0004;	/* write one to 2nd bit - 3rd UIO */3790 3791		/* write back to io data output register */3792		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);3793		if (rc != 0) {3794			pr_err("error %d\n", rc);3795			goto rw_error;3796		}3797		break;3798   /*=====================================================================*/3799	case DRX_UIO4:3800		/* DRX_UIO4: IRQN UIO-4 */3801		if (!ext_attr->has_irqn)3802			return -EIO;3803 3804		if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)3805			return -EIO;3806 3807		pin_cfg_value = 0;3808		/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */3809		pin_cfg_value |= 0x0113;3810		/* io_pad_cfg_mode output mode is drive always */3811		/* io_pad_cfg_drive is set to power 2 (23 mA) */3812 3813		/* write to io pad configuration register - output mode */3814		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);3815		if (rc != 0) {3816			pr_err("error %d\n", rc);3817			goto rw_error;3818		}3819 3820		/* use corresponding bit in io data output registar */3821		rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);3822		if (rc != 0) {3823			pr_err("error %d\n", rc);3824			goto rw_error;3825		}3826		if (uio_data->value == false)3827			value &= 0xEFFF;	/* write zero to 12th bit - 4th UIO */3828		else3829			value |= 0x1000;	/* write one to 12th bit - 4th UIO */3830 3831		/* write back to io data output register */3832		rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);3833		if (rc != 0) {3834			pr_err("error %d\n", rc);3835			goto rw_error;3836		}3837		break;3838      /*=====================================================================*/3839	default:3840		return -EINVAL;3841	}			/* switch ( uio_data->uio ) */3842 3843	/*  Write magic word to disable pdr reg write               */3844	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);3845	if (rc != 0) {3846		pr_err("error %d\n", rc);3847		goto rw_error;3848	}3849 3850	return 0;3851rw_error:3852	return rc;3853}3854 3855/*---------------------------------------------------------------------------*/3856/* UIO Configuration Functions - end                                         */3857/*---------------------------------------------------------------------------*/3858 3859/*----------------------------------------------------------------------------*/3860/* I2C Bridge Functions - begin                                               */3861/*----------------------------------------------------------------------------*/3862/*3863* \fn int ctrl_i2c_bridge()3864* \brief Open or close the I2C switch to tuner.3865* \param demod Pointer to demodulator instance.3866* \param bridge_closed Pointer to bool indication if bridge is closed not.3867* \return int.3868 3869*/3870static int3871ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)3872{3873	struct drxj_hi_cmd hi_cmd;3874	u16 result = 0;3875 3876	/* check arguments */3877	if (bridge_closed == NULL)3878		return -EINVAL;3879 3880	hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;3881	hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;3882	if (*bridge_closed)3883		hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;3884	else3885		hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;3886 3887	return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);3888}3889 3890/*----------------------------------------------------------------------------*/3891/* I2C Bridge Functions - end                                                 */3892/*----------------------------------------------------------------------------*/3893 3894/*----------------------------------------------------------------------------*/3895/* Smart antenna Functions - begin                                            */3896/*----------------------------------------------------------------------------*/3897/*3898* \fn int smart_ant_init()3899* \brief Initialize Smart Antenna.3900* \param pointer to struct drx_demod_instance.3901* \return int.3902*3903*/3904static int smart_ant_init(struct drx_demod_instance *demod)3905{3906	struct drxj_data *ext_attr = NULL;3907	struct i2c_device_addr *dev_addr = NULL;3908	struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };3909	int rc;3910	u16 data = 0;3911 3912	dev_addr = demod->my_i2c_dev_addr;3913	ext_attr = (struct drxj_data *) demod->my_ext_attr;3914 3915	/*  Write magic word to enable pdr reg write               */3916	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);3917	if (rc != 0) {3918		pr_err("error %d\n", rc);3919		goto rw_error;3920	}3921	/* init smart antenna */3922	rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);3923	if (rc != 0) {3924		pr_err("error %d\n", rc);3925		goto rw_error;3926	}3927	if (ext_attr->smart_ant_inverted) {3928		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);3929		if (rc != 0) {3930			pr_err("error %d\n", rc);3931			goto rw_error;3932		}3933	} else {3934		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);3935		if (rc != 0) {3936			pr_err("error %d\n", rc);3937			goto rw_error;3938		}3939	}3940 3941	/* config SMA_TX pin to smart antenna mode */3942	rc = ctrl_set_uio_cfg(demod, &uio_cfg);3943	if (rc != 0) {3944		pr_err("error %d\n", rc);3945		goto rw_error;3946	}3947	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);3948	if (rc != 0) {3949		pr_err("error %d\n", rc);3950		goto rw_error;3951	}3952	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);3953	if (rc != 0) {3954		pr_err("error %d\n", rc);3955		goto rw_error;3956	}3957 3958	/*  Write magic word to disable pdr reg write               */3959	rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);3960	if (rc != 0) {3961		pr_err("error %d\n", rc);3962		goto rw_error;3963	}3964 3965	return 0;3966rw_error:3967	return rc;3968}3969 3970static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)3971{3972	int rc;3973	u16 cur_cmd = 0;3974	unsigned long timeout;3975 3976	/* Check param */3977	if (cmd == NULL)3978		return -EINVAL;3979 3980	/* Wait until SCU command interface is ready to receive command */3981	rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);3982	if (rc != 0) {3983		pr_err("error %d\n", rc);3984		goto rw_error;3985	}3986	if (cur_cmd != DRX_SCU_READY)3987		return -EIO;3988 3989	switch (cmd->parameter_len) {3990	case 5:3991		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);3992		if (rc != 0) {3993			pr_err("error %d\n", rc);3994			goto rw_error;3995		}3996		fallthrough;3997	case 4:3998		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);3999		if (rc != 0) {4000			pr_err("error %d\n", rc);4001			goto rw_error;4002		}4003		fallthrough;4004	case 3:4005		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);4006		if (rc != 0) {4007			pr_err("error %d\n", rc);4008			goto rw_error;4009		}4010		fallthrough;4011	case 2:4012		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);4013		if (rc != 0) {4014			pr_err("error %d\n", rc);4015			goto rw_error;4016		}4017		fallthrough;4018	case 1:4019		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);4020		if (rc != 0) {4021			pr_err("error %d\n", rc);4022			goto rw_error;4023		}4024		fallthrough;4025	case 0:4026		/* do nothing */4027		break;4028	default:4029		/* this number of parameters is not supported */4030		return -EIO;4031	}4032	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);4033	if (rc != 0) {4034		pr_err("error %d\n", rc);4035		goto rw_error;4036	}4037 4038	/* Wait until SCU has processed command */4039	timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);4040	while (time_is_after_jiffies(timeout)) {4041		rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);4042		if (rc != 0) {4043			pr_err("error %d\n", rc);4044			goto rw_error;4045		}4046		if (cur_cmd == DRX_SCU_READY)4047			break;4048		usleep_range(1000, 2000);4049	}4050 4051	if (cur_cmd != DRX_SCU_READY)4052		return -EIO;4053 4054	/* read results */4055	if ((cmd->result_len > 0) && (cmd->result != NULL)) {4056		s16 err;4057 4058		switch (cmd->result_len) {4059		case 4:4060			rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);4061			if (rc != 0) {4062				pr_err("error %d\n", rc);4063				goto rw_error;4064			}4065			fallthrough;4066		case 3:4067			rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);4068			if (rc != 0) {4069				pr_err("error %d\n", rc);4070				goto rw_error;4071			}4072			fallthrough;4073		case 2:4074			rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);4075			if (rc != 0) {4076				pr_err("error %d\n", rc);4077				goto rw_error;4078			}4079			fallthrough;4080		case 1:4081			rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);4082			if (rc != 0) {4083				pr_err("error %d\n", rc);4084				goto rw_error;4085			}4086			fallthrough;4087		case 0:4088			/* do nothing */4089			break;4090		default:4091			/* this number of parameters is not supported */4092			return -EIO;4093		}4094 4095		/* Check if an error was reported by SCU */4096		err = cmd->result[0];4097 4098		/* check a few fixed error codes */4099		if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)4100		    || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)4101		    || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)4102		    || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)4103		    ) {4104			return -EINVAL;4105		}4106		/* here it is assumed that negative means error, and positive no error */4107		else if (err < 0)4108			return -EIO;4109		else4110			return 0;4111	}4112 4113	return 0;4114 4115rw_error:4116	return rc;4117}4118 4119/*4120* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()4121* \brief Basic access routine for SCU atomic read or write access4122* \param dev_addr  pointer to i2c dev address4123* \param addr     destination/source address4124* \param datasize size of data buffer in bytes4125* \param data     pointer to data buffer4126* \return int4127* \retval 0 Success4128* \retval -EIO Timeout, I2C error, illegal bank4129*4130*/4131#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)4132static4133int 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 */4134					      u8 *data, bool read_flag)4135{4136	struct drxjscu_cmd scu_cmd;4137	int rc;4138	u16 set_param_parameters[18];4139	u16 cmd_result[15];4140 4141	/* Parameter check */4142	if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))4143		return -EINVAL;4144 4145	set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);4146	if (read_flag) {		/* read */4147		set_param_parameters[0] = ((~(0x0080)) & datasize);4148		scu_cmd.parameter_len = 2;4149		scu_cmd.result_len = datasize / 2 + 2;4150	} else {4151		int i = 0;4152 4153		set_param_parameters[0] = 0x0080 | datasize;4154		for (i = 0; i < (datasize / 2); i++) {4155			set_param_parameters[i + 2] =4156			    (data[2 * i] | (data[(2 * i) + 1] << 8));4157		}4158		scu_cmd.parameter_len = datasize / 2 + 2;4159		scu_cmd.result_len = 1;4160	}4161 4162	scu_cmd.command =4163	    SCU_RAM_COMMAND_STANDARD_TOP |4164	    SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;4165	scu_cmd.result = cmd_result;4166	scu_cmd.parameter = set_param_parameters;4167	rc = scu_command(dev_addr, &scu_cmd);4168	if (rc != 0) {4169		pr_err("error %d\n", rc);4170		goto rw_error;4171	}4172 4173	if (read_flag) {4174		int i = 0;4175		/* read data from buffer */4176		for (i = 0; i < (datasize / 2); i++) {4177			data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);4178			data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);4179		}4180	}4181 4182	return 0;4183 4184rw_error:4185	return rc;4186 4187}4188 4189/*============================================================================*/4190 4191/*4192* \fn int DRXJ_DAP_AtomicReadReg16()4193* \brief Atomic read of 16 bits words4194*/4195static4196int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,4197					 u32 addr,4198					 u16 *data, u32 flags)4199{4200	u8 buf[2] = { 0 };4201	int rc;4202	u16 word = 0;4203 4204	if (!data)4205		return -EINVAL;4206 4207	rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);4208	if (rc < 0)4209		return rc;4210 4211	word = (u16) (buf[0] + (buf[1] << 8));4212 4213	*data = word;4214 4215	return rc;4216}4217 4218/*============================================================================*/4219/*4220* \fn int drxj_dap_scu_atomic_write_reg16()4221* \brief Atomic read of 16 bits words4222*/4223static4224int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,4225					  u32 addr,4226					  u16 data, u32 flags)4227{4228	u8 buf[2];4229	int rc;4230 4231	buf[0] = (u8) (data & 0xff);4232	buf[1] = (u8) ((data >> 8) & 0xff);4233 4234	rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);4235 4236	return rc;4237}4238 4239/* -------------------------------------------------------------------------- */4240/*4241* \brief Measure result of ADC synchronisation4242* \param demod demod instance4243* \param count (returned) count4244* \return int.4245* \retval 0    Success4246* \retval -EIO Failure: I2C error4247*4248*/4249static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)4250{4251	struct i2c_device_addr *dev_addr = NULL;4252	int rc;4253	u16 data = 0;4254 4255	dev_addr = demod->my_i2c_dev_addr;4256 4257	/* Start measurement */4258	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);4259	if (rc != 0) {4260		pr_err("error %d\n", rc);4261		goto rw_error;4262	}4263	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);4264	if (rc != 0) {4265		pr_err("error %d\n", rc);4266		goto rw_error;4267	}4268 4269	/* Wait at least 3*128*(1/sysclk) <<< 1 millisec */4270	msleep(1);4271 4272	*count = 0;4273	rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);4274	if (rc != 0) {4275		pr_err("error %d\n", rc);4276		goto rw_error;4277	}4278	if (data == 127)4279		*count = *count + 1;4280	rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);4281	if (rc != 0) {4282		pr_err("error %d\n", rc);4283		goto rw_error;4284	}4285	if (data == 127)4286		*count = *count + 1;4287	rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);4288	if (rc != 0) {4289		pr_err("error %d\n", rc);4290		goto rw_error;4291	}4292	if (data == 127)4293		*count = *count + 1;4294 4295	return 0;4296rw_error:4297	return rc;4298}4299 4300/*4301* \brief Synchronize analog and digital clock domains4302* \param demod demod instance4303* \return int.4304* \retval 0    Success4305* \retval -EIO Failure: I2C error or failure to synchronize4306*4307* An IQM reset will also reset the results of this synchronization.4308* After an IQM reset this routine needs to be called again.4309*4310*/4311 4312static int adc_synchronization(struct drx_demod_instance *demod)4313{4314	struct i2c_device_addr *dev_addr = NULL;4315	int rc;4316	u16 count = 0;4317 4318	dev_addr = demod->my_i2c_dev_addr;4319 4320	rc = adc_sync_measurement(demod, &count);4321	if (rc != 0) {4322		pr_err("error %d\n", rc);4323		goto rw_error;4324	}4325 4326	if (count == 1) {4327		/* Try sampling on a different edge */4328		u16 clk_neg = 0;4329 4330		rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);4331		if (rc != 0) {4332			pr_err("error %d\n", rc);4333			goto rw_error;4334		}4335 4336		clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;4337		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);4338		if (rc != 0) {4339			pr_err("error %d\n", rc);4340			goto rw_error;4341		}4342 4343		rc = adc_sync_measurement(demod, &count);4344		if (rc != 0) {4345			pr_err("error %d\n", rc);4346			goto rw_error;4347		}4348	}4349 4350	/* TODO: implement fallback scenarios */4351	if (count < 2)4352		return -EIO;4353 4354	return 0;4355rw_error:4356	return rc;4357}4358 4359/*============================================================================*/4360/*==                      END AUXILIARY FUNCTIONS                           ==*/4361/*============================================================================*/4362 4363/*============================================================================*/4364/*============================================================================*/4365/*==                8VSB & QAM COMMON DATAPATH FUNCTIONS                    ==*/4366/*============================================================================*/4367/*============================================================================*/4368/*4369* \fn int init_agc ()4370* \brief Initialize AGC for all standards.4371* \param demod instance of demodulator.4372* \param channel pointer to channel data.4373* \return int.4374*/4375static int init_agc(struct drx_demod_instance *demod)4376{4377	struct i2c_device_addr *dev_addr = NULL;4378	struct drx_common_attr *common_attr = NULL;4379	struct drxj_data *ext_attr = NULL;4380	struct drxj_cfg_agc *p_agc_rf_settings = NULL;4381	struct drxj_cfg_agc *p_agc_if_settings = NULL;4382	int rc;4383	u16 ingain_tgt_max = 0;4384	u16 clp_dir_to = 0;4385	u16 sns_sum_max = 0;4386	u16 clp_sum_max = 0;4387	u16 sns_dir_to = 0;4388	u16 ki_innergain_min = 0;4389	u16 agc_ki = 0;4390	u16 ki_max = 0;4391	u16 if_iaccu_hi_tgt_min = 0;4392	u16 data = 0;4393	u16 agc_ki_dgain = 0;4394	u16 ki_min = 0;4395	u16 clp_ctrl_mode = 0;4396	u16 agc_rf = 0;4397	u16 agc_if = 0;4398 4399	dev_addr = demod->my_i2c_dev_addr;4400	common_attr = (struct drx_common_attr *) demod->my_common_attr;4401	ext_attr = (struct drxj_data *) demod->my_ext_attr;4402 4403	switch (ext_attr->standard) {4404	case DRX_STANDARD_8VSB:4405		clp_sum_max = 1023;4406		clp_dir_to = (u16) (-9);4407		sns_sum_max = 1023;4408		sns_dir_to = (u16) (-9);4409		ki_innergain_min = (u16) (-32768);4410		ki_max = 0x032C;4411		agc_ki_dgain = 0xC;4412		if_iaccu_hi_tgt_min = 2047;4413		ki_min = 0x0117;4414		ingain_tgt_max = 16383;4415		clp_ctrl_mode = 0;4416		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);4417		if (rc != 0) {4418			pr_err("error %d\n", rc);4419			goto rw_error;4420		}4421		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);4422		if (rc != 0) {4423			pr_err("error %d\n", rc);4424			goto rw_error;4425		}4426		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);4427		if (rc != 0) {4428			pr_err("error %d\n", rc);4429			goto rw_error;4430		}4431		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);4432		if (rc != 0) {4433			pr_err("error %d\n", rc);4434			goto rw_error;4435		}4436		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);4437		if (rc != 0) {4438			pr_err("error %d\n", rc);4439			goto rw_error;4440		}4441		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);4442		if (rc != 0) {4443			pr_err("error %d\n", rc);4444			goto rw_error;4445		}4446		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);4447		if (rc != 0) {4448			pr_err("error %d\n", rc);4449			goto rw_error;4450		}4451		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);4452		if (rc != 0) {4453			pr_err("error %d\n", rc);4454			goto rw_error;4455		}4456		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);4457		if (rc != 0) {4458			pr_err("error %d\n", rc);4459			goto rw_error;4460		}4461		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);4462		if (rc != 0) {4463			pr_err("error %d\n", rc);4464			goto rw_error;4465		}4466		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);4467		if (rc != 0) {4468			pr_err("error %d\n", rc);4469			goto rw_error;4470		}4471		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);4472		if (rc != 0) {4473			pr_err("error %d\n", rc);4474			goto rw_error;4475		}4476		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);4477		if (rc != 0) {4478			pr_err("error %d\n", rc);4479			goto rw_error;4480		}4481		p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);4482		p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);4483		break;4484#ifndef DRXJ_VSB_ONLY4485	case DRX_STANDARD_ITU_A:4486	case DRX_STANDARD_ITU_C:4487	case DRX_STANDARD_ITU_B:4488		ingain_tgt_max = 5119;4489		clp_sum_max = 1023;4490		clp_dir_to = (u16) (-5);4491		sns_sum_max = 127;4492		sns_dir_to = (u16) (-3);4493		ki_innergain_min = 0;4494		ki_max = 0x0657;4495		if_iaccu_hi_tgt_min = 2047;4496		agc_ki_dgain = 0x7;4497		ki_min = 0x0117;4498		clp_ctrl_mode = 0;4499		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);4500		if (rc != 0) {4501			pr_err("error %d\n", rc);4502			goto rw_error;4503		}4504		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);4505		if (rc != 0) {4506			pr_err("error %d\n", rc);4507			goto rw_error;4508		}4509		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);4510		if (rc != 0) {4511			pr_err("error %d\n", rc);4512			goto rw_error;4513		}4514		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);4515		if (rc != 0) {4516			pr_err("error %d\n", rc);4517			goto rw_error;4518		}4519		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);4520		if (rc != 0) {4521			pr_err("error %d\n", rc);4522			goto rw_error;4523		}4524		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);4525		if (rc != 0) {4526			pr_err("error %d\n", rc);4527			goto rw_error;4528		}4529		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);4530		if (rc != 0) {4531			pr_err("error %d\n", rc);4532			goto rw_error;4533		}4534		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);4535		if (rc != 0) {4536			pr_err("error %d\n", rc);4537			goto rw_error;4538		}4539		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);4540		if (rc != 0) {4541			pr_err("error %d\n", rc);4542			goto rw_error;4543		}4544		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);4545		if (rc != 0) {4546			pr_err("error %d\n", rc);4547			goto rw_error;4548		}4549		p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);4550		p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);4551		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);4552		if (rc != 0) {4553			pr_err("error %d\n", rc);4554			goto rw_error;4555		}4556 4557		rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);4558		if (rc != 0) {4559			pr_err("error %d\n", rc);4560			goto rw_error;4561		}4562		agc_ki &= 0xf000;4563		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);4564		if (rc != 0) {4565			pr_err("error %d\n", rc);4566			goto rw_error;4567		}4568		break;4569#endif4570	default:4571		return -EINVAL;4572	}4573 4574	/* for new AGC interface */4575	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);4576	if (rc != 0) {4577		pr_err("error %d\n", rc);4578		goto rw_error;4579	}4580	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);4581	if (rc != 0) {4582		pr_err("error %d\n", rc);4583		goto rw_error;4584	}	/* Gain fed from inner to outer AGC */4585	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);4586	if (rc != 0) {4587		pr_err("error %d\n", rc);4588		goto rw_error;4589	}4590	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);4591	if (rc != 0) {4592		pr_err("error %d\n", rc);4593		goto rw_error;4594	}4595	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);4596	if (rc != 0) {4597		pr_err("error %d\n", rc);4598		goto rw_error;4599	}	/* set to p_agc_settings->top before */4600	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);4601	if (rc != 0) {4602		pr_err("error %d\n", rc);4603		goto rw_error;4604	}4605	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);4606	if (rc != 0) {4607		pr_err("error %d\n", rc);4608		goto rw_error;4609	}4610	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);4611	if (rc != 0) {4612		pr_err("error %d\n", rc);4613		goto rw_error;4614	}4615	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);4616	if (rc != 0) {4617		pr_err("error %d\n", rc);4618		goto rw_error;4619	}4620	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);4621	if (rc != 0) {4622		pr_err("error %d\n", rc);4623		goto rw_error;4624	}4625	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);4626	if (rc != 0) {4627		pr_err("error %d\n", rc);4628		goto rw_error;4629	}4630	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);4631	if (rc != 0) {4632		pr_err("error %d\n", rc);4633		goto rw_error;4634	}4635	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);4636	if (rc != 0) {4637		pr_err("error %d\n", rc);4638		goto rw_error;4639	}4640	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);4641	if (rc != 0) {4642		pr_err("error %d\n", rc);4643		goto rw_error;4644	}4645	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);4646	if (rc != 0) {4647		pr_err("error %d\n", rc);4648		goto rw_error;4649	}4650	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);4651	if (rc != 0) {4652		pr_err("error %d\n", rc);4653		goto rw_error;4654	}4655	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);4656	if (rc != 0) {4657		pr_err("error %d\n", rc);4658		goto rw_error;4659	}4660	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);4661	if (rc != 0) {4662		pr_err("error %d\n", rc);4663		goto rw_error;4664	}4665	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);4666	if (rc != 0) {4667		pr_err("error %d\n", rc);4668		goto rw_error;4669	}4670	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);4671	if (rc != 0) {4672		pr_err("error %d\n", rc);4673		goto rw_error;4674	}4675	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);4676	if (rc != 0) {4677		pr_err("error %d\n", rc);4678		goto rw_error;4679	}4680	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);4681	if (rc != 0) {4682		pr_err("error %d\n", rc);4683		goto rw_error;4684	}4685	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);4686	if (rc != 0) {4687		pr_err("error %d\n", rc);4688		goto rw_error;4689	}4690	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);4691	if (rc != 0) {4692		pr_err("error %d\n", rc);4693		goto rw_error;4694	}4695	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);4696	if (rc != 0) {4697		pr_err("error %d\n", rc);4698		goto rw_error;4699	}4700	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);4701	if (rc != 0) {4702		pr_err("error %d\n", rc);4703		goto rw_error;4704	}4705 4706	agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;4707	if (common_attr->tuner_rf_agc_pol == true)4708		agc_rf = 0x87ff - agc_rf;4709 4710	agc_if = 0x800;4711	if (common_attr->tuner_if_agc_pol == true)4712		agc_rf = 0x87ff - agc_rf;4713 4714	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);4715	if (rc != 0) {4716		pr_err("error %d\n", rc);4717		goto rw_error;4718	}4719	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);4720	if (rc != 0) {4721		pr_err("error %d\n", rc);4722		goto rw_error;4723	}4724 4725	/* Set/restore Ki DGAIN factor */4726	rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);4727	if (rc != 0) {4728		pr_err("error %d\n", rc);4729		goto rw_error;4730	}4731	data &= ~SCU_RAM_AGC_KI_DGAIN__M;4732	data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);4733	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);4734	if (rc != 0) {4735		pr_err("error %d\n", rc);4736		goto rw_error;4737	}4738 4739	return 0;4740rw_error:4741	return rc;4742}4743 4744/*4745* \fn int set_frequency ()4746* \brief Set frequency shift.4747* \param demod instance of demodulator.4748* \param channel pointer to channel data.4749* \param tuner_freq_offset residual frequency from tuner.4750* \return int.4751*/4752static int4753set_frequency(struct drx_demod_instance *demod,4754	      struct drx_channel *channel, s32 tuner_freq_offset)4755{4756	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;4757	struct drxj_data *ext_attr = demod->my_ext_attr;4758	int rc;4759	s32 sampling_frequency = 0;4760	s32 frequency_shift = 0;4761	s32 if_freq_actual = 0;4762	s32 rf_freq_residual = -1 * tuner_freq_offset;4763	s32 adc_freq = 0;4764	s32 intermediate_freq = 0;4765	u32 iqm_fs_rate_ofs = 0;4766	bool adc_flip = true;4767	bool select_pos_image = false;4768	bool rf_mirror;4769	bool tuner_mirror;4770	bool image_to_select;4771	s32 fm_frequency_shift = 0;4772 4773	rf_mirror = ext_attr->mirror == DRX_MIRROR_YES;4774	tuner_mirror = !demod->my_common_attr->mirror_freq_spect;4775	/*4776	   Program frequency shifter4777	   No need to account for mirroring on RF4778	 */4779	switch (ext_attr->standard) {4780	case DRX_STANDARD_ITU_A:4781	case DRX_STANDARD_ITU_C:4782	case DRX_STANDARD_PAL_SECAM_LP:4783	case DRX_STANDARD_8VSB:4784		select_pos_image = true;4785		break;4786	case DRX_STANDARD_FM:4787		/* After IQM FS sound carrier must appear at 4 Mhz in spect.4788		   Sound carrier is already 3Mhz above centre frequency due4789		   to tuner setting so now add an extra shift of 1MHz... */4790		fm_frequency_shift = 1000;4791		fallthrough;4792	case DRX_STANDARD_ITU_B:4793	case DRX_STANDARD_NTSC:4794	case DRX_STANDARD_PAL_SECAM_BG:4795	case DRX_STANDARD_PAL_SECAM_DK:4796	case DRX_STANDARD_PAL_SECAM_I:4797	case DRX_STANDARD_PAL_SECAM_L:4798		select_pos_image = false;4799		break;4800	default:4801		return -EINVAL;4802	}4803	intermediate_freq = demod->my_common_attr->intermediate_freq;4804	sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;4805	if (tuner_mirror)4806		if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;4807	else4808		if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;4809	if (if_freq_actual > sampling_frequency / 2) {4810		/* adc mirrors */4811		adc_freq = sampling_frequency - if_freq_actual;4812		adc_flip = true;4813	} else {4814		/* adc doesn't mirror */4815		adc_freq = if_freq_actual;4816		adc_flip = false;4817	}4818 4819	frequency_shift = adc_freq;4820	image_to_select =4821	    (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);4822	iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);4823 4824	if (image_to_select)4825		iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;4826 4827	/* Program frequency shifter with tuner offset compensation */4828	/* frequency_shift += tuner_freq_offset; TODO */4829	rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);4830	if (rc != 0) {4831		pr_err("error %d\n", rc);4832		goto rw_error;4833	}4834	ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;4835	ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);4836 4837	return 0;4838rw_error:4839	return rc;4840}4841 4842/*4843* \fn int get_acc_pkt_err()4844* \brief Retrieve signal strength for VSB and QAM.4845* \param demod Pointer to demod instance4846* \param packet_err Pointer to packet error4847* \return int.4848* \retval 0 sig_strength contains valid data.4849* \retval -EINVAL sig_strength is NULL.4850* \retval -EIO Erroneous data, sig_strength contains invalid data.4851*/4852#ifdef DRXJ_SIGNAL_ACCUM_ERR4853static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)4854{4855	int rc;4856	static u16 pkt_err;4857	static u16 last_pkt_err;4858	u16 data = 0;4859	struct drxj_data *ext_attr = NULL;4860	struct i2c_device_addr *dev_addr = NULL;4861 4862	ext_attr = (struct drxj_data *) demod->my_ext_attr;4863	dev_addr = demod->my_i2c_dev_addr;4864 4865	rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);4866	if (rc != 0) {4867		pr_err("error %d\n", rc);4868		goto rw_error;4869	}4870	if (ext_attr->reset_pkt_err_acc) {4871		last_pkt_err = data;4872		pkt_err = 0;4873		ext_attr->reset_pkt_err_acc = false;4874	}4875 4876	if (data < last_pkt_err) {4877		pkt_err += 0xffff - last_pkt_err;4878		pkt_err += data;4879	} else {4880		pkt_err += (data - last_pkt_err);4881	}4882	*packet_err = pkt_err;4883	last_pkt_err = data;4884 4885	return 0;4886rw_error:4887	return rc;4888}4889#endif4890 4891 4892/*============================================================================*/4893 4894/*4895* \fn int set_agc_rf ()4896* \brief Configure RF AGC4897* \param demod instance of demodulator.4898* \param agc_settings AGC configuration structure4899* \return int.4900*/4901static int4902set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)4903{4904	struct i2c_device_addr *dev_addr = NULL;4905	struct drxj_data *ext_attr = NULL;4906	struct drxj_cfg_agc *p_agc_settings = NULL;4907	struct drx_common_attr *common_attr = NULL;4908	int rc;4909	drx_write_reg16func_t scu_wr16 = NULL;4910	drx_read_reg16func_t scu_rr16 = NULL;4911 4912	common_attr = (struct drx_common_attr *) demod->my_common_attr;4913	dev_addr = demod->my_i2c_dev_addr;4914	ext_attr = (struct drxj_data *) demod->my_ext_attr;4915 4916	if (atomic) {4917		scu_rr16 = drxj_dap_scu_atomic_read_reg16;4918		scu_wr16 = drxj_dap_scu_atomic_write_reg16;4919	} else {4920		scu_rr16 = drxj_dap_read_reg16;4921		scu_wr16 = drxj_dap_write_reg16;4922	}4923 4924	/* Configure AGC only if standard is currently active */4925	if ((ext_attr->standard == agc_settings->standard) ||4926	    (DRXJ_ISQAMSTD(ext_attr->standard) &&4927	     DRXJ_ISQAMSTD(agc_settings->standard)) ||4928	    (DRXJ_ISATVSTD(ext_attr->standard) &&4929	     DRXJ_ISATVSTD(agc_settings->standard))) {4930		u16 data = 0;4931 4932		switch (agc_settings->ctrl_mode) {4933		case DRX_AGC_CTRL_AUTO:4934 4935			/* Enable RF AGC DAC */4936			rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);4937			if (rc != 0) {4938				pr_err("error %d\n", rc);4939				goto rw_error;4940			}4941			data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;4942			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);4943			if (rc != 0) {4944				pr_err("error %d\n", rc);4945				goto rw_error;4946			}4947 4948			/* Enable SCU RF AGC loop */4949			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);4950			if (rc != 0) {4951				pr_err("error %d\n", rc);4952				goto rw_error;4953			}4954			data &= ~SCU_RAM_AGC_KI_RF__M;4955			if (ext_attr->standard == DRX_STANDARD_8VSB)4956				data |= (2 << SCU_RAM_AGC_KI_RF__B);4957			else if (DRXJ_ISQAMSTD(ext_attr->standard))4958				data |= (5 << SCU_RAM_AGC_KI_RF__B);4959			else4960				data |= (4 << SCU_RAM_AGC_KI_RF__B);4961 4962			if (common_attr->tuner_rf_agc_pol)4963				data |= SCU_RAM_AGC_KI_INV_RF_POL__M;4964			else4965				data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;4966			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);4967			if (rc != 0) {4968				pr_err("error %d\n", rc);4969				goto rw_error;4970			}4971 4972			/* Set speed ( using complementary reduction value ) */4973			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);4974			if (rc != 0) {4975				pr_err("error %d\n", rc);4976				goto rw_error;4977			}4978			data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;4979			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);4980			if (rc != 0) {4981				pr_err("error %d\n", rc);4982				goto rw_error;4983			}4984 4985			if (agc_settings->standard == DRX_STANDARD_8VSB)4986				p_agc_settings = &(ext_attr->vsb_if_agc_cfg);4987			else if (DRXJ_ISQAMSTD(agc_settings->standard))4988				p_agc_settings = &(ext_attr->qam_if_agc_cfg);4989			else if (DRXJ_ISATVSTD(agc_settings->standard))4990				p_agc_settings = &(ext_attr->atv_if_agc_cfg);4991			else4992				return -EINVAL;4993 4994			/* Set TOP, only if IF-AGC is in AUTO mode */4995			if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {4996				rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);4997				if (rc != 0) {4998					pr_err("error %d\n", rc);4999					goto rw_error;5000				}5001				rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);5002				if (rc != 0) {5003					pr_err("error %d\n", rc);5004					goto rw_error;5005				}5006			}5007 5008			/* Cut-Off current */5009			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);5010			if (rc != 0) {5011				pr_err("error %d\n", rc);5012				goto rw_error;5013			}5014			break;5015		case DRX_AGC_CTRL_USER:5016 5017			/* Enable RF AGC DAC */5018			rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);5019			if (rc != 0) {5020				pr_err("error %d\n", rc);5021				goto rw_error;5022			}5023			data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;5024			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);5025			if (rc != 0) {5026				pr_err("error %d\n", rc);5027				goto rw_error;5028			}5029 5030			/* Disable SCU RF AGC loop */5031			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);5032			if (rc != 0) {5033				pr_err("error %d\n", rc);5034				goto rw_error;5035			}5036			data &= ~SCU_RAM_AGC_KI_RF__M;5037			if (common_attr->tuner_rf_agc_pol)5038				data |= SCU_RAM_AGC_KI_INV_RF_POL__M;5039			else5040				data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;5041			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);5042			if (rc != 0) {5043				pr_err("error %d\n", rc);5044				goto rw_error;5045			}5046 5047			/* Write value to output pin */5048			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);5049			if (rc != 0) {5050				pr_err("error %d\n", rc);5051				goto rw_error;5052			}5053			break;5054		case DRX_AGC_CTRL_OFF:5055 5056			/* Disable RF AGC DAC */5057			rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);5058			if (rc != 0) {5059				pr_err("error %d\n", rc);5060				goto rw_error;5061			}5062			data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);5063			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);5064			if (rc != 0) {5065				pr_err("error %d\n", rc);5066				goto rw_error;5067			}5068 5069			/* Disable SCU RF AGC loop */5070			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);5071			if (rc != 0) {5072				pr_err("error %d\n", rc);5073				goto rw_error;5074			}5075			data &= ~SCU_RAM_AGC_KI_RF__M;5076			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);5077			if (rc != 0) {5078				pr_err("error %d\n", rc);5079				goto rw_error;5080			}5081			break;5082		default:5083			return -EINVAL;5084		}		/* switch ( agcsettings->ctrl_mode ) */5085	}5086 5087	/* Store rf agc settings */5088	switch (agc_settings->standard) {5089	case DRX_STANDARD_8VSB:5090		ext_attr->vsb_rf_agc_cfg = *agc_settings;5091		break;5092#ifndef DRXJ_VSB_ONLY5093	case DRX_STANDARD_ITU_A:5094	case DRX_STANDARD_ITU_B:5095	case DRX_STANDARD_ITU_C:5096		ext_attr->qam_rf_agc_cfg = *agc_settings;5097		break;5098#endif5099	default:5100		return -EIO;5101	}5102 5103	return 0;5104rw_error:5105	return rc;5106}5107 5108/*5109* \fn int set_agc_if ()5110* \brief Configure If AGC5111* \param demod instance of demodulator.5112* \param agc_settings AGC configuration structure5113* \return int.5114*/5115static int5116set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)5117{5118	struct i2c_device_addr *dev_addr = NULL;5119	struct drxj_data *ext_attr = NULL;5120	struct drxj_cfg_agc *p_agc_settings = NULL;5121	struct drx_common_attr *common_attr = NULL;5122	drx_write_reg16func_t scu_wr16 = NULL;5123	drx_read_reg16func_t scu_rr16 = NULL;5124	int rc;5125 5126	common_attr = (struct drx_common_attr *) demod->my_common_attr;5127	dev_addr = demod->my_i2c_dev_addr;5128	ext_attr = (struct drxj_data *) demod->my_ext_attr;5129 5130	if (atomic) {5131		scu_rr16 = drxj_dap_scu_atomic_read_reg16;5132		scu_wr16 = drxj_dap_scu_atomic_write_reg16;5133	} else {5134		scu_rr16 = drxj_dap_read_reg16;5135		scu_wr16 = drxj_dap_write_reg16;5136	}5137 5138	/* Configure AGC only if standard is currently active */5139	if ((ext_attr->standard == agc_settings->standard) ||5140	    (DRXJ_ISQAMSTD(ext_attr->standard) &&5141	     DRXJ_ISQAMSTD(agc_settings->standard)) ||5142	    (DRXJ_ISATVSTD(ext_attr->standard) &&5143	     DRXJ_ISATVSTD(agc_settings->standard))) {5144		u16 data = 0;5145 5146		switch (agc_settings->ctrl_mode) {5147		case DRX_AGC_CTRL_AUTO:5148			/* Enable IF AGC DAC */5149			rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);5150			if (rc != 0) {5151				pr_err("error %d\n", rc);5152				goto rw_error;5153			}5154			data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;5155			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);5156			if (rc != 0) {5157				pr_err("error %d\n", rc);5158				goto rw_error;5159			}5160 5161			/* Enable SCU IF AGC loop */5162			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);5163			if (rc != 0) {5164				pr_err("error %d\n", rc);5165				goto rw_error;5166			}5167			data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;5168			data &= ~SCU_RAM_AGC_KI_IF__M;5169			if (ext_attr->standard == DRX_STANDARD_8VSB)5170				data |= (3 << SCU_RAM_AGC_KI_IF__B);5171			else if (DRXJ_ISQAMSTD(ext_attr->standard))5172				data |= (6 << SCU_RAM_AGC_KI_IF__B);5173			else5174				data |= (5 << SCU_RAM_AGC_KI_IF__B);5175 5176			if (common_attr->tuner_if_agc_pol)5177				data |= SCU_RAM_AGC_KI_INV_IF_POL__M;5178			else5179				data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;5180			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);5181			if (rc != 0) {5182				pr_err("error %d\n", rc);5183				goto rw_error;5184			}5185 5186			/* Set speed (using complementary reduction value) */5187			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);5188			if (rc != 0) {5189				pr_err("error %d\n", rc);5190				goto rw_error;5191			}5192			data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;5193			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);5194			if (rc != 0) {5195				pr_err("error %d\n", rc);5196				goto rw_error;5197			}5198 5199			if (agc_settings->standard == DRX_STANDARD_8VSB)5200				p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);5201			else if (DRXJ_ISQAMSTD(agc_settings->standard))5202				p_agc_settings = &(ext_attr->qam_rf_agc_cfg);5203			else if (DRXJ_ISATVSTD(agc_settings->standard))5204				p_agc_settings = &(ext_attr->atv_rf_agc_cfg);5205			else5206				return -EINVAL;5207 5208			/* Restore TOP */5209			if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {5210				rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);5211				if (rc != 0) {5212					pr_err("error %d\n", rc);5213					goto rw_error;5214				}5215				rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);5216				if (rc != 0) {5217					pr_err("error %d\n", rc);5218					goto rw_error;5219				}5220			} else {5221				rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);5222				if (rc != 0) {5223					pr_err("error %d\n", rc);5224					goto rw_error;5225				}5226				rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);5227				if (rc != 0) {5228					pr_err("error %d\n", rc);5229					goto rw_error;5230				}5231			}5232			break;5233 5234		case DRX_AGC_CTRL_USER:5235 5236			/* Enable IF AGC DAC */5237			rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);5238			if (rc != 0) {5239				pr_err("error %d\n", rc);5240				goto rw_error;5241			}5242			data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;5243			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);5244			if (rc != 0) {5245				pr_err("error %d\n", rc);5246				goto rw_error;5247			}5248 5249			/* Disable SCU IF AGC loop */5250			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);5251			if (rc != 0) {5252				pr_err("error %d\n", rc);5253				goto rw_error;5254			}5255			data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;5256			data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;5257			if (common_attr->tuner_if_agc_pol)5258				data |= SCU_RAM_AGC_KI_INV_IF_POL__M;5259			else5260				data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;5261			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);5262			if (rc != 0) {5263				pr_err("error %d\n", rc);5264				goto rw_error;5265			}5266 5267			/* Write value to output pin */5268			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);5269			if (rc != 0) {5270				pr_err("error %d\n", rc);5271				goto rw_error;5272			}5273			break;5274 5275		case DRX_AGC_CTRL_OFF:5276 5277			/* Disable If AGC DAC */5278			rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);5279			if (rc != 0) {5280				pr_err("error %d\n", rc);5281				goto rw_error;5282			}5283			data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);5284			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);5285			if (rc != 0) {5286				pr_err("error %d\n", rc);5287				goto rw_error;5288			}5289 5290			/* Disable SCU IF AGC loop */5291			rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);5292			if (rc != 0) {5293				pr_err("error %d\n", rc);5294				goto rw_error;5295			}5296			data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;5297			data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;5298			rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);5299			if (rc != 0) {5300				pr_err("error %d\n", rc);5301				goto rw_error;5302			}5303			break;5304		default:5305			return -EINVAL;5306		}		/* switch ( agcsettings->ctrl_mode ) */5307 5308		/* always set the top to support configurations without if-loop */5309		rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);5310		if (rc != 0) {5311			pr_err("error %d\n", rc);5312			goto rw_error;5313		}5314	}5315 5316	/* Store if agc settings */5317	switch (agc_settings->standard) {5318	case DRX_STANDARD_8VSB:5319		ext_attr->vsb_if_agc_cfg = *agc_settings;5320		break;5321#ifndef DRXJ_VSB_ONLY5322	case DRX_STANDARD_ITU_A:5323	case DRX_STANDARD_ITU_B:5324	case DRX_STANDARD_ITU_C:5325		ext_attr->qam_if_agc_cfg = *agc_settings;5326		break;5327#endif5328	default:5329		return -EIO;5330	}5331 5332	return 0;5333rw_error:5334	return rc;5335}5336 5337/*5338* \fn int set_iqm_af ()5339* \brief Configure IQM AF registers5340* \param demod instance of demodulator.5341* \param active5342* \return int.5343*/5344static int set_iqm_af(struct drx_demod_instance *demod, bool active)5345{5346	u16 data = 0;5347	struct i2c_device_addr *dev_addr = NULL;5348	int rc;5349 5350	dev_addr = demod->my_i2c_dev_addr;5351 5352	/* Configure IQM */5353	rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);5354	if (rc != 0) {5355		pr_err("error %d\n", rc);5356		goto rw_error;5357	}5358	if (!active)5359		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));5360	else5361		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);5362	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);5363	if (rc != 0) {5364		pr_err("error %d\n", rc);5365		goto rw_error;5366	}5367 5368	return 0;5369rw_error:5370	return rc;5371}5372 5373/*============================================================================*/5374/*==              END 8VSB & QAM COMMON DATAPATH FUNCTIONS                  ==*/5375/*============================================================================*/5376 5377/*============================================================================*/5378/*============================================================================*/5379/*==                       8VSB DATAPATH FUNCTIONS                          ==*/5380/*============================================================================*/5381/*============================================================================*/5382 5383/*5384* \fn int power_down_vsb ()5385* \brief Powr down QAM related blocks.5386* \param demod instance of demodulator.5387* \param channel pointer to channel data.5388* \return int.5389*/5390static int power_down_vsb(struct drx_demod_instance *demod, bool primary)5391{5392	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;5393	struct drxjscu_cmd cmd_scu = { /* command     */ 0,5394		/* parameter_len */ 0,5395		/* result_len    */ 0,5396		/* *parameter   */ NULL,5397		/* *result      */ NULL5398	};5399	struct drx_cfg_mpeg_output cfg_mpeg_output;5400	int rc;5401	u16 cmd_result = 0;5402 5403	/*5404	   STOP demodulator5405	   reset of FEC and VSB HW5406	 */5407	cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |5408	    SCU_RAM_COMMAND_CMD_DEMOD_STOP;5409	cmd_scu.parameter_len = 0;5410	cmd_scu.result_len = 1;5411	cmd_scu.parameter = NULL;5412	cmd_scu.result = &cmd_result;5413	rc = scu_command(dev_addr, &cmd_scu);5414	if (rc != 0) {5415		pr_err("error %d\n", rc);5416		goto rw_error;5417	}5418 5419	/* stop all comm_exec */5420	rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);5421	if (rc != 0) {5422		pr_err("error %d\n", rc);5423		goto rw_error;5424	}5425	rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);5426	if (rc != 0) {5427		pr_err("error %d\n", rc);5428		goto rw_error;5429	}5430	if (primary) {5431		rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);5432		if (rc != 0) {5433			pr_err("error %d\n", rc);5434			goto rw_error;5435		}5436		rc = set_iqm_af(demod, false);5437		if (rc != 0) {5438			pr_err("error %d\n", rc);5439			goto rw_error;5440		}5441	} else {5442		rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);5443		if (rc != 0) {5444			pr_err("error %d\n", rc);5445			goto rw_error;5446		}5447		rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);5448		if (rc != 0) {5449			pr_err("error %d\n", rc);5450			goto rw_error;5451		}5452		rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);5453		if (rc != 0) {5454			pr_err("error %d\n", rc);5455			goto rw_error;5456		}5457		rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);5458		if (rc != 0) {5459			pr_err("error %d\n", rc);5460			goto rw_error;5461		}5462		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);5463		if (rc != 0) {5464			pr_err("error %d\n", rc);5465			goto rw_error;5466		}5467	}5468 5469	cfg_mpeg_output.enable_mpeg_output = false;5470	rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);5471	if (rc != 0) {5472		pr_err("error %d\n", rc);5473		goto rw_error;5474	}5475 5476	return 0;5477rw_error:5478	return rc;5479}5480 5481/*5482* \fn int set_vsb_leak_n_gain ()5483* \brief Set ATSC demod.5484* \param demod instance of demodulator.5485* \return int.5486*/5487static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)5488{5489	struct i2c_device_addr *dev_addr = NULL;5490	int rc;5491 5492	static const u8 vsb_ffe_leak_gain_ram0[] = {5493		DRXJ_16TO8(0x8),	/* FFETRAINLKRATIO1  */5494		DRXJ_16TO8(0x8),	/* FFETRAINLKRATIO2  */5495		DRXJ_16TO8(0x8),	/* FFETRAINLKRATIO3  */5496		DRXJ_16TO8(0xf),	/* FFETRAINLKRATIO4  */5497		DRXJ_16TO8(0xf),	/* FFETRAINLKRATIO5  */5498		DRXJ_16TO8(0xf),	/* FFETRAINLKRATIO6  */5499		DRXJ_16TO8(0xf),	/* FFETRAINLKRATIO7  */5500		DRXJ_16TO8(0xf),	/* FFETRAINLKRATIO8  */5501		DRXJ_16TO8(0xf),	/* FFETRAINLKRATIO9  */5502		DRXJ_16TO8(0x8),	/* FFETRAINLKRATIO10  */5503		DRXJ_16TO8(0x8),	/* FFETRAINLKRATIO11 */5504		DRXJ_16TO8(0x8),	/* FFETRAINLKRATIO12 */5505		DRXJ_16TO8(0x10),	/* FFERCA1TRAINLKRATIO1 */5506		DRXJ_16TO8(0x10),	/* FFERCA1TRAINLKRATIO2 */5507		DRXJ_16TO8(0x10),	/* FFERCA1TRAINLKRATIO3 */5508		DRXJ_16TO8(0x20),	/* FFERCA1TRAINLKRATIO4 */5509		DRXJ_16TO8(0x20),	/* FFERCA1TRAINLKRATIO5 */5510		DRXJ_16TO8(0x20),	/* FFERCA1TRAINLKRATIO6 */5511		DRXJ_16TO8(0x20),	/* FFERCA1TRAINLKRATIO7 */5512		DRXJ_16TO8(0x20),	/* FFERCA1TRAINLKRATIO8 */5513		DRXJ_16TO8(0x20),	/* FFERCA1TRAINLKRATIO9 */5514		DRXJ_16TO8(0x10),	/* FFERCA1TRAINLKRATIO10 */5515		DRXJ_16TO8(0x10),	/* FFERCA1TRAINLKRATIO11 */5516		DRXJ_16TO8(0x10),	/* FFERCA1TRAINLKRATIO12 */5517		DRXJ_16TO8(0x10),	/* FFERCA1DATALKRATIO1 */5518		DRXJ_16TO8(0x10),	/* FFERCA1DATALKRATIO2 */5519		DRXJ_16TO8(0x10),	/* FFERCA1DATALKRATIO3 */5520		DRXJ_16TO8(0x20),	/* FFERCA1DATALKRATIO4 */5521		DRXJ_16TO8(0x20),	/* FFERCA1DATALKRATIO5 */5522		DRXJ_16TO8(0x20),	/* FFERCA1DATALKRATIO6 */5523		DRXJ_16TO8(0x20),	/* FFERCA1DATALKRATIO7 */5524		DRXJ_16TO8(0x20),	/* FFERCA1DATALKRATIO8 */5525		DRXJ_16TO8(0x20),	/* FFERCA1DATALKRATIO9 */5526		DRXJ_16TO8(0x10),	/* FFERCA1DATALKRATIO10 */5527		DRXJ_16TO8(0x10),	/* FFERCA1DATALKRATIO11 */5528		DRXJ_16TO8(0x10),	/* FFERCA1DATALKRATIO12 */5529		DRXJ_16TO8(0x10),	/* FFERCA2TRAINLKRATIO1 */5530		DRXJ_16TO8(0x10),	/* FFERCA2TRAINLKRATIO2 */5531		DRXJ_16TO8(0x10),	/* FFERCA2TRAINLKRATIO3 */5532		DRXJ_16TO8(0x20),	/* FFERCA2TRAINLKRATIO4 */5533		DRXJ_16TO8(0x20),	/* FFERCA2TRAINLKRATIO5 */5534		DRXJ_16TO8(0x20),	/* FFERCA2TRAINLKRATIO6 */5535		DRXJ_16TO8(0x20),	/* FFERCA2TRAINLKRATIO7 */5536		DRXJ_16TO8(0x20),	/* FFERCA2TRAINLKRATIO8 */5537		DRXJ_16TO8(0x20),	/* FFERCA2TRAINLKRATIO9 */5538		DRXJ_16TO8(0x10),	/* FFERCA2TRAINLKRATIO10 */5539		DRXJ_16TO8(0x10),	/* FFERCA2TRAINLKRATIO11 */5540		DRXJ_16TO8(0x10),	/* FFERCA2TRAINLKRATIO12 */5541		DRXJ_16TO8(0x10),	/* FFERCA2DATALKRATIO1 */5542		DRXJ_16TO8(0x10),	/* FFERCA2DATALKRATIO2 */5543		DRXJ_16TO8(0x10),	/* FFERCA2DATALKRATIO3 */5544		DRXJ_16TO8(0x20),	/* FFERCA2DATALKRATIO4 */5545		DRXJ_16TO8(0x20),	/* FFERCA2DATALKRATIO5 */5546		DRXJ_16TO8(0x20),	/* FFERCA2DATALKRATIO6 */5547		DRXJ_16TO8(0x20),	/* FFERCA2DATALKRATIO7 */5548		DRXJ_16TO8(0x20),	/* FFERCA2DATALKRATIO8 */5549		DRXJ_16TO8(0x20),	/* FFERCA2DATALKRATIO9 */5550		DRXJ_16TO8(0x10),	/* FFERCA2DATALKRATIO10 */5551		DRXJ_16TO8(0x10),	/* FFERCA2DATALKRATIO11 */5552		DRXJ_16TO8(0x10),	/* FFERCA2DATALKRATIO12 */5553		DRXJ_16TO8(0x07),	/* FFEDDM1TRAINLKRATIO1 */5554		DRXJ_16TO8(0x07),	/* FFEDDM1TRAINLKRATIO2 */5555		DRXJ_16TO8(0x07),	/* FFEDDM1TRAINLKRATIO3 */5556		DRXJ_16TO8(0x0e),	/* FFEDDM1TRAINLKRATIO4 */5557		DRXJ_16TO8(0x0e),	/* FFEDDM1TRAINLKRATIO5 */5558		DRXJ_16TO8(0x0e),	/* FFEDDM1TRAINLKRATIO6 */5559		DRXJ_16TO8(0x0e),	/* FFEDDM1TRAINLKRATIO7 */5560		DRXJ_16TO8(0x0e),	/* FFEDDM1TRAINLKRATIO8 */5561		DRXJ_16TO8(0x0e),	/* FFEDDM1TRAINLKRATIO9 */5562		DRXJ_16TO8(0x07),	/* FFEDDM1TRAINLKRATIO10 */5563		DRXJ_16TO8(0x07),	/* FFEDDM1TRAINLKRATIO11 */5564		DRXJ_16TO8(0x07),	/* FFEDDM1TRAINLKRATIO12 */5565		DRXJ_16TO8(0x07),	/* FFEDDM1DATALKRATIO1 */5566		DRXJ_16TO8(0x07),	/* FFEDDM1DATALKRATIO2 */5567		DRXJ_16TO8(0x07),	/* FFEDDM1DATALKRATIO3 */5568		DRXJ_16TO8(0x0e),	/* FFEDDM1DATALKRATIO4 */5569		DRXJ_16TO8(0x0e),	/* FFEDDM1DATALKRATIO5 */5570		DRXJ_16TO8(0x0e),	/* FFEDDM1DATALKRATIO6 */5571		DRXJ_16TO8(0x0e),	/* FFEDDM1DATALKRATIO7 */5572		DRXJ_16TO8(0x0e),	/* FFEDDM1DATALKRATIO8 */5573		DRXJ_16TO8(0x0e),	/* FFEDDM1DATALKRATIO9 */5574		DRXJ_16TO8(0x07),	/* FFEDDM1DATALKRATIO10 */5575		DRXJ_16TO8(0x07),	/* FFEDDM1DATALKRATIO11 */5576		DRXJ_16TO8(0x07),	/* FFEDDM1DATALKRATIO12 */5577		DRXJ_16TO8(0x06),	/* FFEDDM2TRAINLKRATIO1 */5578		DRXJ_16TO8(0x06),	/* FFEDDM2TRAINLKRATIO2 */5579		DRXJ_16TO8(0x06),	/* FFEDDM2TRAINLKRATIO3 */5580		DRXJ_16TO8(0x0c),	/* FFEDDM2TRAINLKRATIO4 */5581		DRXJ_16TO8(0x0c),	/* FFEDDM2TRAINLKRATIO5 */5582		DRXJ_16TO8(0x0c),	/* FFEDDM2TRAINLKRATIO6 */5583		DRXJ_16TO8(0x0c),	/* FFEDDM2TRAINLKRATIO7 */5584		DRXJ_16TO8(0x0c),	/* FFEDDM2TRAINLKRATIO8 */5585		DRXJ_16TO8(0x0c),	/* FFEDDM2TRAINLKRATIO9 */5586		DRXJ_16TO8(0x06),	/* FFEDDM2TRAINLKRATIO10 */5587		DRXJ_16TO8(0x06),	/* FFEDDM2TRAINLKRATIO11 */5588		DRXJ_16TO8(0x06),	/* FFEDDM2TRAINLKRATIO12 */5589		DRXJ_16TO8(0x06),	/* FFEDDM2DATALKRATIO1 */5590		DRXJ_16TO8(0x06),	/* FFEDDM2DATALKRATIO2 */5591		DRXJ_16TO8(0x06),	/* FFEDDM2DATALKRATIO3 */5592		DRXJ_16TO8(0x0c),	/* FFEDDM2DATALKRATIO4 */5593		DRXJ_16TO8(0x0c),	/* FFEDDM2DATALKRATIO5 */5594		DRXJ_16TO8(0x0c),	/* FFEDDM2DATALKRATIO6 */5595		DRXJ_16TO8(0x0c),	/* FFEDDM2DATALKRATIO7 */5596		DRXJ_16TO8(0x0c),	/* FFEDDM2DATALKRATIO8 */5597		DRXJ_16TO8(0x0c),	/* FFEDDM2DATALKRATIO9 */5598		DRXJ_16TO8(0x06),	/* FFEDDM2DATALKRATIO10 */5599		DRXJ_16TO8(0x06),	/* FFEDDM2DATALKRATIO11 */5600		DRXJ_16TO8(0x06),	/* FFEDDM2DATALKRATIO12 */5601		DRXJ_16TO8(0x2020),	/* FIRTRAINGAIN1 */5602		DRXJ_16TO8(0x2020),	/* FIRTRAINGAIN2 */5603		DRXJ_16TO8(0x2020),	/* FIRTRAINGAIN3 */5604		DRXJ_16TO8(0x4040),	/* FIRTRAINGAIN4 */5605		DRXJ_16TO8(0x4040),	/* FIRTRAINGAIN5 */5606		DRXJ_16TO8(0x4040),	/* FIRTRAINGAIN6 */5607		DRXJ_16TO8(0x4040),	/* FIRTRAINGAIN7 */5608		DRXJ_16TO8(0x4040),	/* FIRTRAINGAIN8 */5609		DRXJ_16TO8(0x4040),	/* FIRTRAINGAIN9 */5610		DRXJ_16TO8(0x2020),	/* FIRTRAINGAIN10 */5611		DRXJ_16TO8(0x2020),	/* FIRTRAINGAIN11 */5612		DRXJ_16TO8(0x2020),	/* FIRTRAINGAIN12 */5613		DRXJ_16TO8(0x0808),	/* FIRRCA1GAIN1 */5614		DRXJ_16TO8(0x0808),	/* FIRRCA1GAIN2 */5615		DRXJ_16TO8(0x0808),	/* FIRRCA1GAIN3 */5616		DRXJ_16TO8(0x1010),	/* FIRRCA1GAIN4 */5617		DRXJ_16TO8(0x1010),	/* FIRRCA1GAIN5 */5618		DRXJ_16TO8(0x1010),	/* FIRRCA1GAIN6 */5619		DRXJ_16TO8(0x1010),	/* FIRRCA1GAIN7 */5620		DRXJ_16TO8(0x1010)	/* FIRRCA1GAIN8 */5621	};5622 5623	static const u8 vsb_ffe_leak_gain_ram1[] = {5624		DRXJ_16TO8(0x1010),	/* FIRRCA1GAIN9 */5625		DRXJ_16TO8(0x0808),	/* FIRRCA1GAIN10 */5626		DRXJ_16TO8(0x0808),	/* FIRRCA1GAIN11 */5627		DRXJ_16TO8(0x0808),	/* FIRRCA1GAIN12 */5628		DRXJ_16TO8(0x0808),	/* FIRRCA2GAIN1 */5629		DRXJ_16TO8(0x0808),	/* FIRRCA2GAIN2 */5630		DRXJ_16TO8(0x0808),	/* FIRRCA2GAIN3 */5631		DRXJ_16TO8(0x1010),	/* FIRRCA2GAIN4 */5632		DRXJ_16TO8(0x1010),	/* FIRRCA2GAIN5 */5633		DRXJ_16TO8(0x1010),	/* FIRRCA2GAIN6 */5634		DRXJ_16TO8(0x1010),	/* FIRRCA2GAIN7 */5635		DRXJ_16TO8(0x1010),	/* FIRRCA2GAIN8 */5636		DRXJ_16TO8(0x1010),	/* FIRRCA2GAIN9 */5637		DRXJ_16TO8(0x0808),	/* FIRRCA2GAIN10 */5638		DRXJ_16TO8(0x0808),	/* FIRRCA2GAIN11 */5639		DRXJ_16TO8(0x0808),	/* FIRRCA2GAIN12 */5640		DRXJ_16TO8(0x0303),	/* FIRDDM1GAIN1 */5641		DRXJ_16TO8(0x0303),	/* FIRDDM1GAIN2 */5642		DRXJ_16TO8(0x0303),	/* FIRDDM1GAIN3 */5643		DRXJ_16TO8(0x0606),	/* FIRDDM1GAIN4 */5644		DRXJ_16TO8(0x0606),	/* FIRDDM1GAIN5 */5645		DRXJ_16TO8(0x0606),	/* FIRDDM1GAIN6 */5646		DRXJ_16TO8(0x0606),	/* FIRDDM1GAIN7 */5647		DRXJ_16TO8(0x0606),	/* FIRDDM1GAIN8 */5648		DRXJ_16TO8(0x0606),	/* FIRDDM1GAIN9 */5649		DRXJ_16TO8(0x0303),	/* FIRDDM1GAIN10 */5650		DRXJ_16TO8(0x0303),	/* FIRDDM1GAIN11 */5651		DRXJ_16TO8(0x0303),	/* FIRDDM1GAIN12 */5652		DRXJ_16TO8(0x0303),	/* FIRDDM2GAIN1 */5653		DRXJ_16TO8(0x0303),	/* FIRDDM2GAIN2 */5654		DRXJ_16TO8(0x0303),	/* FIRDDM2GAIN3 */5655		DRXJ_16TO8(0x0505),	/* FIRDDM2GAIN4 */5656		DRXJ_16TO8(0x0505),	/* FIRDDM2GAIN5 */5657		DRXJ_16TO8(0x0505),	/* FIRDDM2GAIN6 */5658		DRXJ_16TO8(0x0505),	/* FIRDDM2GAIN7 */5659		DRXJ_16TO8(0x0505),	/* FIRDDM2GAIN8 */5660		DRXJ_16TO8(0x0505),	/* FIRDDM2GAIN9 */5661		DRXJ_16TO8(0x0303),	/* FIRDDM2GAIN10 */5662		DRXJ_16TO8(0x0303),	/* FIRDDM2GAIN11 */5663		DRXJ_16TO8(0x0303),	/* FIRDDM2GAIN12 */5664		DRXJ_16TO8(0x001f),	/* DFETRAINLKRATIO */5665		DRXJ_16TO8(0x01ff),	/* DFERCA1TRAINLKRATIO */5666		DRXJ_16TO8(0x01ff),	/* DFERCA1DATALKRATIO */5667		DRXJ_16TO8(0x004f),	/* DFERCA2TRAINLKRATIO */5668		DRXJ_16TO8(0x004f),	/* DFERCA2DATALKRATIO */5669		DRXJ_16TO8(0x01ff),	/* DFEDDM1TRAINLKRATIO */5670		DRXJ_16TO8(0x01ff),	/* DFEDDM1DATALKRATIO */5671		DRXJ_16TO8(0x0352),	/* DFEDDM2TRAINLKRATIO */5672		DRXJ_16TO8(0x0352),	/* DFEDDM2DATALKRATIO */5673		DRXJ_16TO8(0x0000),	/* DFETRAINGAIN */5674		DRXJ_16TO8(0x2020),	/* DFERCA1GAIN */5675		DRXJ_16TO8(0x1010),	/* DFERCA2GAIN */5676		DRXJ_16TO8(0x1818),	/* DFEDDM1GAIN */5677		DRXJ_16TO8(0x1212)	/* DFEDDM2GAIN */5678	};5679 5680	dev_addr = demod->my_i2c_dev_addr;5681	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);5682	if (rc != 0) {5683		pr_err("error %d\n", rc);5684		goto rw_error;5685	}5686	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);5687	if (rc != 0) {5688		pr_err("error %d\n", rc);5689		goto rw_error;5690	}5691 5692	return 0;5693rw_error:5694	return rc;5695}5696 5697/*5698* \fn int set_vsb()5699* \brief Set 8VSB demod.5700* \param demod instance of demodulator.5701* \return int.5702*5703*/5704static int set_vsb(struct drx_demod_instance *demod)5705{5706	struct i2c_device_addr *dev_addr = NULL;5707	int rc;5708	struct drx_common_attr *common_attr = NULL;5709	struct drxjscu_cmd cmd_scu;5710	struct drxj_data *ext_attr = NULL;5711	u16 cmd_result = 0;5712	u16 cmd_param = 0;5713	static const u8 vsb_taps_re[] = {5714		DRXJ_16TO8(-2),	/* re0  */5715		DRXJ_16TO8(4),	/* re1  */5716		DRXJ_16TO8(1),	/* re2  */5717		DRXJ_16TO8(-4),	/* re3  */5718		DRXJ_16TO8(1),	/* re4  */5719		DRXJ_16TO8(4),	/* re5  */5720		DRXJ_16TO8(-3),	/* re6  */5721		DRXJ_16TO8(-3),	/* re7  */5722		DRXJ_16TO8(6),	/* re8  */5723		DRXJ_16TO8(1),	/* re9  */5724		DRXJ_16TO8(-9),	/* re10 */5725		DRXJ_16TO8(3),	/* re11 */5726		DRXJ_16TO8(12),	/* re12 */5727		DRXJ_16TO8(-9),	/* re13 */5728		DRXJ_16TO8(-15),	/* re14 */5729		DRXJ_16TO8(17),	/* re15 */5730		DRXJ_16TO8(19),	/* re16 */5731		DRXJ_16TO8(-29),	/* re17 */5732		DRXJ_16TO8(-22),	/* re18 */5733		DRXJ_16TO8(45),	/* re19 */5734		DRXJ_16TO8(25),	/* re20 */5735		DRXJ_16TO8(-70),	/* re21 */5736		DRXJ_16TO8(-28),	/* re22 */5737		DRXJ_16TO8(111),	/* re23 */5738		DRXJ_16TO8(30),	/* re24 */5739		DRXJ_16TO8(-201),	/* re25 */5740		DRXJ_16TO8(-31),	/* re26 */5741		DRXJ_16TO8(629)	/* re27 */5742	};5743 5744	dev_addr = demod->my_i2c_dev_addr;5745	common_attr = (struct drx_common_attr *) demod->my_common_attr;5746	ext_attr = (struct drxj_data *) demod->my_ext_attr;5747 5748	/* stop all comm_exec */5749	rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);5750	if (rc != 0) {5751		pr_err("error %d\n", rc);5752		goto rw_error;5753	}5754	rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);5755	if (rc != 0) {5756		pr_err("error %d\n", rc);5757		goto rw_error;5758	}5759	rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);5760	if (rc != 0) {5761		pr_err("error %d\n", rc);5762		goto rw_error;5763	}5764	rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);5765	if (rc != 0) {5766		pr_err("error %d\n", rc);5767		goto rw_error;5768	}5769	rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);5770	if (rc != 0) {5771		pr_err("error %d\n", rc);5772		goto rw_error;5773	}5774	rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);5775	if (rc != 0) {5776		pr_err("error %d\n", rc);5777		goto rw_error;5778	}5779	rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);5780	if (rc != 0) {5781		pr_err("error %d\n", rc);5782		goto rw_error;5783	}5784 5785	/* reset demodulator */5786	cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB5787	    | SCU_RAM_COMMAND_CMD_DEMOD_RESET;5788	cmd_scu.parameter_len = 0;5789	cmd_scu.result_len = 1;5790	cmd_scu.parameter = NULL;5791	cmd_scu.result = &cmd_result;5792	rc = scu_command(dev_addr, &cmd_scu);5793	if (rc != 0) {5794		pr_err("error %d\n", rc);5795		goto rw_error;5796	}5797 5798	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);5799	if (rc != 0) {5800		pr_err("error %d\n", rc);5801		goto rw_error;5802	}5803	rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);5804	if (rc != 0) {5805		pr_err("error %d\n", rc);5806		goto rw_error;5807	}5808	rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);5809	if (rc != 0) {5810		pr_err("error %d\n", rc);5811		goto rw_error;5812	}5813	ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;5814	rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);5815	if (rc != 0) {5816		pr_err("error %d\n", rc);5817		goto rw_error;5818	}5819	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);5820	if (rc != 0) {5821		pr_err("error %d\n", rc);5822		goto rw_error;5823	}5824	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);5825	if (rc != 0) {5826		pr_err("error %d\n", rc);5827		goto rw_error;5828	}5829 5830	rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);5831	if (rc != 0) {5832		pr_err("error %d\n", rc);5833		goto rw_error;5834	}5835	rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);5836	if (rc != 0) {5837		pr_err("error %d\n", rc);5838		goto rw_error;5839	}5840	rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);5841	if (rc != 0) {5842		pr_err("error %d\n", rc);5843		goto rw_error;5844	}5845	rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);5846	if (rc != 0) {5847		pr_err("error %d\n", rc);5848		goto rw_error;5849	}5850	rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);5851	if (rc != 0) {5852		pr_err("error %d\n", rc);5853		goto rw_error;5854	}5855	rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);5856	if (rc != 0) {5857		pr_err("error %d\n", rc);5858		goto rw_error;5859	}5860	rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);5861	if (rc != 0) {5862		pr_err("error %d\n", rc);5863		goto rw_error;5864	}5865	rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);5866	if (rc != 0) {5867		pr_err("error %d\n", rc);5868		goto rw_error;5869	}5870	rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);5871	if (rc != 0) {5872		pr_err("error %d\n", rc);5873		goto rw_error;5874	}5875 5876	rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);5877	if (rc != 0) {5878		pr_err("error %d\n", rc);5879		goto rw_error;5880	}5881	rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);5882	if (rc != 0) {5883		pr_err("error %d\n", rc);5884		goto rw_error;5885	}5886 5887	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);5888	if (rc != 0) {5889		pr_err("error %d\n", rc);5890		goto rw_error;5891	}	/* set higher threshold */5892	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);5893	if (rc != 0) {5894		pr_err("error %d\n", rc);5895		goto rw_error;5896	}	/* burst detection on   */5897	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);5898	if (rc != 0) {5899		pr_err("error %d\n", rc);5900		goto rw_error;5901	}	/* drop thresholds by 1 dB */5902	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);5903	if (rc != 0) {5904		pr_err("error %d\n", rc);5905		goto rw_error;5906	}	/* drop thresholds by 2 dB */5907	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);5908	if (rc != 0) {5909		pr_err("error %d\n", rc);5910		goto rw_error;5911	}	/* cma on               */5912	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);5913	if (rc != 0) {5914		pr_err("error %d\n", rc);5915		goto rw_error;5916	}	/* GPIO               */5917 5918	/* Initialize the FEC Subsystem */5919	rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);5920	if (rc != 0) {5921		pr_err("error %d\n", rc);5922		goto rw_error;5923	}5924	{5925		u16 fec_oc_snc_mode = 0;5926		rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);5927		if (rc != 0) {5928			pr_err("error %d\n", rc);5929			goto rw_error;5930		}5931		/* output data even when not locked */5932		rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);5933		if (rc != 0) {5934			pr_err("error %d\n", rc);5935			goto rw_error;5936		}5937	}5938 5939	/* set clip */5940	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);5941	if (rc != 0) {5942		pr_err("error %d\n", rc);5943		goto rw_error;5944	}5945	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);5946	if (rc != 0) {5947		pr_err("error %d\n", rc);5948		goto rw_error;5949	}5950	rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);5951	if (rc != 0) {5952		pr_err("error %d\n", rc);5953		goto rw_error;5954	}5955	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);5956	if (rc != 0) {5957		pr_err("error %d\n", rc);5958		goto rw_error;5959	}5960	/* no transparent, no A&C framing; parity is set in mpegoutput */5961	{5962		u16 fec_oc_reg_mode = 0;5963		rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);5964		if (rc != 0) {5965			pr_err("error %d\n", rc);5966			goto rw_error;5967		}5968		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);5969		if (rc != 0) {5970			pr_err("error %d\n", rc);5971			goto rw_error;5972		}5973	}5974 5975	rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);5976	if (rc != 0) {5977		pr_err("error %d\n", rc);5978		goto rw_error;5979	}	/* timeout counter for restarting */5980	rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);5981	if (rc != 0) {5982		pr_err("error %d\n", rc);5983		goto rw_error;5984	}5985	rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);5986	if (rc != 0) {5987		pr_err("error %d\n", rc);5988		goto rw_error;5989	}	/* bypass disabled */5990	/* initialize RS packet error measurement parameters */5991	rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);5992	if (rc != 0) {5993		pr_err("error %d\n", rc);5994		goto rw_error;5995	}5996	rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);5997	if (rc != 0) {5998		pr_err("error %d\n", rc);5999		goto rw_error;6000	}6001 6002	/* init measurement period of MER/SER */6003	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);6004	if (rc != 0) {6005		pr_err("error %d\n", rc);6006		goto rw_error;6007	}6008	rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);6009	if (rc != 0) {6010		pr_err("error %d\n", rc);6011		goto rw_error;6012	}6013	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);6014	if (rc != 0) {6015		pr_err("error %d\n", rc);6016		goto rw_error;6017	}6018	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);6019	if (rc != 0) {6020		pr_err("error %d\n", rc);6021		goto rw_error;6022	}6023 6024	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);6025	if (rc != 0) {6026		pr_err("error %d\n", rc);6027		goto rw_error;6028	}6029	/* B-Input to ADC, PGA+filter in standby */6030	if (!ext_attr->has_lna) {6031		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);6032		if (rc != 0) {6033			pr_err("error %d\n", rc);6034			goto rw_error;6035		}6036	}6037 6038	/* turn on IQMAF. It has to be in front of setAgc**() */6039	rc = set_iqm_af(demod, true);6040	if (rc != 0) {6041		pr_err("error %d\n", rc);6042		goto rw_error;6043	}6044	rc = adc_synchronization(demod);6045	if (rc != 0) {6046		pr_err("error %d\n", rc);6047		goto rw_error;6048	}6049 6050	rc = init_agc(demod);6051	if (rc != 0) {6052		pr_err("error %d\n", rc);6053		goto rw_error;6054	}6055	rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);6056	if (rc != 0) {6057		pr_err("error %d\n", rc);6058		goto rw_error;6059	}6060	rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);6061	if (rc != 0) {6062		pr_err("error %d\n", rc);6063		goto rw_error;6064	}6065	{6066		/* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead6067		   of only the gain */6068		struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };6069 6070		vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;6071		rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);6072		if (rc != 0) {6073			pr_err("error %d\n", rc);6074			goto rw_error;6075		}6076	}6077	rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));6078	if (rc != 0) {6079		pr_err("error %d\n", rc);6080		goto rw_error;6081	}6082 6083	/* Mpeg output has to be in front of FEC active */6084	rc = set_mpegtei_handling(demod);6085	if (rc != 0) {6086		pr_err("error %d\n", rc);6087		goto rw_error;6088	}6089	rc = bit_reverse_mpeg_output(demod);6090	if (rc != 0) {6091		pr_err("error %d\n", rc);6092		goto rw_error;6093	}6094	rc = set_mpeg_start_width(demod);6095	if (rc != 0) {6096		pr_err("error %d\n", rc);6097		goto rw_error;6098	}6099	{6100		/* TODO: move to set_standard after hardware reset value problem is solved */6101		/* Configure initial MPEG output */6102		struct drx_cfg_mpeg_output cfg_mpeg_output;6103 6104		memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));6105		cfg_mpeg_output.enable_mpeg_output = true;6106 6107		rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);6108		if (rc != 0) {6109			pr_err("error %d\n", rc);6110			goto rw_error;6111		}6112	}6113 6114	/* TBD: what parameters should be set */6115	cmd_param = 0x00;	/* Default mode AGC on, etc */6116	cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB6117	    | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;6118	cmd_scu.parameter_len = 1;6119	cmd_scu.result_len = 1;6120	cmd_scu.parameter = &cmd_param;6121	cmd_scu.result = &cmd_result;6122	rc = scu_command(dev_addr, &cmd_scu);6123	if (rc != 0) {6124		pr_err("error %d\n", rc);6125		goto rw_error;6126	}6127 6128	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);6129	if (rc != 0) {6130		pr_err("error %d\n", rc);6131		goto rw_error;6132	}6133	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);6134	if (rc != 0) {6135		pr_err("error %d\n", rc);6136		goto rw_error;6137	}6138	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);6139	if (rc != 0) {6140		pr_err("error %d\n", rc);6141		goto rw_error;6142	}6143	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);6144	if (rc != 0) {6145		pr_err("error %d\n", rc);6146		goto rw_error;6147	}6148	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);6149	if (rc != 0) {6150		pr_err("error %d\n", rc);6151		goto rw_error;6152	}6153	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);6154	if (rc != 0) {6155		pr_err("error %d\n", rc);6156		goto rw_error;6157	}6158	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);6159	if (rc != 0) {6160		pr_err("error %d\n", rc);6161		goto rw_error;6162	}6163	rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);6164	if (rc != 0) {6165		pr_err("error %d\n", rc);6166		goto rw_error;6167	}6168 6169	/* start demodulator */6170	cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB6171	    | SCU_RAM_COMMAND_CMD_DEMOD_START;6172	cmd_scu.parameter_len = 0;6173	cmd_scu.result_len = 1;6174	cmd_scu.parameter = NULL;6175	cmd_scu.result = &cmd_result;6176	rc = scu_command(dev_addr, &cmd_scu);6177	if (rc != 0) {6178		pr_err("error %d\n", rc);6179		goto rw_error;6180	}6181 6182	rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);6183	if (rc != 0) {6184		pr_err("error %d\n", rc);6185		goto rw_error;6186	}6187	rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);6188	if (rc != 0) {6189		pr_err("error %d\n", rc);6190		goto rw_error;6191	}6192	rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);6193	if (rc != 0) {6194		pr_err("error %d\n", rc);6195		goto rw_error;6196	}6197 6198	return 0;6199rw_error:6200	return rc;6201}6202 6203/*6204* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)6205* \brief Get the values of packet error in 8VSB mode6206* \return Error code6207*/6208static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,6209				   u32 *pck_errs, u32 *pck_count)6210{6211	int rc;6212	u16 data = 0;6213	u16 period = 0;6214	u16 prescale = 0;6215	u16 packet_errors_mant = 0;6216	u16 packet_errors_exp = 0;6217 6218	rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);6219	if (rc != 0) {6220		pr_err("error %d\n", rc);6221		goto rw_error;6222	}6223	packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;6224	packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)6225	    >> FEC_RS_NR_FAILURES_EXP__B;6226	period = FEC_RS_MEASUREMENT_PERIOD;6227	prescale = FEC_RS_MEASUREMENT_PRESCALE;6228	/* packet error rate = (error packet number) per second */6229	/* 77.3 us is time for per packet */6230	if (period * prescale == 0) {6231		pr_err("error: period and/or prescale is zero!\n");6232		return -EIO;6233	}6234	*pck_errs = packet_errors_mant * (1 << packet_errors_exp);6235	*pck_count = period * prescale * 77;6236 6237	return 0;6238rw_error:6239	return rc;6240}6241 6242/*6243* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)6244* \brief Get the values of ber in VSB mode6245* \return Error code6246*/6247static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,6248				    u32 *ber, u32 *cnt)6249{6250	int rc;6251	u16 data = 0;6252	u16 period = 0;6253	u16 prescale = 0;6254	u16 bit_errors_mant = 0;6255	u16 bit_errors_exp = 0;6256 6257	rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);6258	if (rc != 0) {6259		pr_err("error %d\n", rc);6260		goto rw_error;6261	}6262	period = FEC_RS_MEASUREMENT_PERIOD;6263	prescale = FEC_RS_MEASUREMENT_PRESCALE;6264 6265	bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;6266	bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)6267	    >> FEC_RS_NR_BIT_ERRORS_EXP__B;6268 6269	*cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);6270 6271	if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)6272		*ber = (*cnt) * 26570;6273	else {6274		if (period * prescale == 0) {6275			pr_err("error: period and/or prescale is zero!\n");6276			return -EIO;6277		}6278		*ber = bit_errors_mant << ((bit_errors_exp > 2) ?6279			(bit_errors_exp - 3) : bit_errors_exp);6280	}6281 6282	return 0;6283rw_error:6284	return rc;6285}6286 6287/*6288* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)6289* \brief Get the values of ber in VSB mode6290* \return Error code6291*/6292static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,6293				   u32 *ber, u32 *cnt)6294{6295	u16 data = 0;6296	int rc;6297 6298	rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);6299	if (rc != 0) {6300		pr_err("error %d\n", rc);6301		return -EIO;6302	}6303	*ber = data;6304	*cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;6305 6306	return 0;6307}6308 6309/*6310* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)6311* \brief Get the values of MER6312* \return Error code6313*/6314static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)6315{6316	int rc;6317	u16 data_hi = 0;6318 6319	rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);6320	if (rc != 0) {6321		pr_err("error %d\n", rc);6322		goto rw_error;6323	}6324	*mer =6325	    (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));6326 6327	return 0;6328rw_error:6329	return rc;6330}6331 6332 6333/*============================================================================*/6334/*==                     END 8VSB DATAPATH FUNCTIONS                        ==*/6335/*============================================================================*/6336 6337/*============================================================================*/6338/*============================================================================*/6339/*==                       QAM DATAPATH FUNCTIONS                           ==*/6340/*============================================================================*/6341/*============================================================================*/6342 6343/*6344* \fn int power_down_qam ()6345* \brief Powr down QAM related blocks.6346* \param demod instance of demodulator.6347* \param channel pointer to channel data.6348* \return int.6349*/6350static int power_down_qam(struct drx_demod_instance *demod, bool primary)6351{6352	struct drxjscu_cmd cmd_scu = { /* command      */ 0,6353		/* parameter_len */ 0,6354		/* result_len    */ 0,6355		/* *parameter   */ NULL,6356		/* *result      */ NULL6357	};6358	int rc;6359	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;6360	struct drx_cfg_mpeg_output cfg_mpeg_output;6361	struct drx_common_attr *common_attr = demod->my_common_attr;6362	u16 cmd_result = 0;6363 6364	/*6365	   STOP demodulator6366	   resets IQM, QAM and FEC HW blocks6367	 */6368	/* stop all comm_exec */6369	rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);6370	if (rc != 0) {6371		pr_err("error %d\n", rc);6372		goto rw_error;6373	}6374	rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);6375	if (rc != 0) {6376		pr_err("error %d\n", rc);6377		goto rw_error;6378	}6379 6380	cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |6381	    SCU_RAM_COMMAND_CMD_DEMOD_STOP;6382	cmd_scu.parameter_len = 0;6383	cmd_scu.result_len = 1;6384	cmd_scu.parameter = NULL;6385	cmd_scu.result = &cmd_result;6386	rc = scu_command(dev_addr, &cmd_scu);6387	if (rc != 0) {6388		pr_err("error %d\n", rc);6389		goto rw_error;6390	}6391 6392	if (primary) {6393		rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);6394		if (rc != 0) {6395			pr_err("error %d\n", rc);6396			goto rw_error;6397		}6398		rc = set_iqm_af(demod, false);6399		if (rc != 0) {6400			pr_err("error %d\n", rc);6401			goto rw_error;6402		}6403	} else {6404		rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);6405		if (rc != 0) {6406			pr_err("error %d\n", rc);6407			goto rw_error;6408		}6409		rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);6410		if (rc != 0) {6411			pr_err("error %d\n", rc);6412			goto rw_error;6413		}6414		rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);6415		if (rc != 0) {6416			pr_err("error %d\n", rc);6417			goto rw_error;6418		}6419		rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);6420		if (rc != 0) {6421			pr_err("error %d\n", rc);6422			goto rw_error;6423		}6424		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);6425		if (rc != 0) {6426			pr_err("error %d\n", rc);6427			goto rw_error;6428		}6429	}6430 6431	memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));6432	cfg_mpeg_output.enable_mpeg_output = false;6433 6434	rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);6435	if (rc != 0) {6436		pr_err("error %d\n", rc);6437		goto rw_error;6438	}6439 6440	return 0;6441rw_error:6442	return rc;6443}6444 6445/*============================================================================*/6446 6447/*6448* \fn int set_qam_measurement ()6449* \brief Setup of the QAM Measuremnt intervals for signal quality6450* \param demod instance of demod.6451* \param constellation current constellation.6452* \return int.6453*6454*  NOTE:6455*  Take into account that for certain settings the errorcounters can overflow.6456*  The implementation does not check this.6457*6458*  TODO: overriding the ext_attr->fec_bits_desired by constellation dependent6459*  constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired6460*  field ?6461*6462*/6463#ifndef DRXJ_VSB_ONLY6464static int6465set_qam_measurement(struct drx_demod_instance *demod,6466		    enum drx_modulation constellation, u32 symbol_rate)6467{6468	struct i2c_device_addr *dev_addr = NULL;	/* device address for I2C writes */6469	struct drxj_data *ext_attr = NULL;	/* Global data container for DRXJ specific data */6470	int rc;6471	u32 fec_bits_desired = 0;	/* BER accounting period */6472	u16 fec_rs_plen = 0;	/* defines RS BER measurement period */6473	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */6474	u32 fec_rs_period = 0;	/* Value for corresponding I2C register */6475	u32 fec_rs_bit_cnt = 0;	/* Actual precise amount of bits */6476	u32 fec_oc_snc_fail_period = 0;	/* Value for corresponding I2C register */6477	u32 qam_vd_period = 0;	/* Value for corresponding I2C register */6478	u32 qam_vd_bit_cnt = 0;	/* Actual precise amount of bits */6479	u16 fec_vd_plen = 0;	/* no of trellis symbols: VD SER measur period */6480	u16 qam_vd_prescale = 0;	/* Viterbi Measurement Prescale */6481 6482	dev_addr = demod->my_i2c_dev_addr;6483	ext_attr = (struct drxj_data *) demod->my_ext_attr;6484 6485	fec_bits_desired = ext_attr->fec_bits_desired;6486	fec_rs_prescale = ext_attr->fec_rs_prescale;6487 6488	switch (constellation) {6489	case DRX_CONSTELLATION_QAM16:6490		fec_bits_desired = 4 * symbol_rate;6491		break;6492	case DRX_CONSTELLATION_QAM32:6493		fec_bits_desired = 5 * symbol_rate;6494		break;6495	case DRX_CONSTELLATION_QAM64:6496		fec_bits_desired = 6 * symbol_rate;6497		break;6498	case DRX_CONSTELLATION_QAM128:6499		fec_bits_desired = 7 * symbol_rate;6500		break;6501	case DRX_CONSTELLATION_QAM256:6502		fec_bits_desired = 8 * symbol_rate;6503		break;6504	default:6505		return -EINVAL;6506	}6507 6508	/* Parameters for Reed-Solomon Decoder */6509	/* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */6510	/* rs_bit_cnt   = fecrs_period*fecrs_prescale*plen                  */6511	/*     result is within 32 bit arithmetic ->                        */6512	/*     no need for mult or frac functions                           */6513 6514	/* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */6515	switch (ext_attr->standard) {6516	case DRX_STANDARD_ITU_A:6517	case DRX_STANDARD_ITU_C:6518		fec_rs_plen = 204 * 8;6519		break;6520	case DRX_STANDARD_ITU_B:6521		fec_rs_plen = 128 * 7;6522		break;6523	default:6524		return -EINVAL;6525	}6526 6527	ext_attr->fec_rs_plen = fec_rs_plen;	/* for getSigQual */6528	fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen;	/* temp storage   */6529	if (fec_rs_bit_cnt == 0) {6530		pr_err("error: fec_rs_bit_cnt is zero!\n");6531		return -EIO;6532	}6533	fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1;	/* ceil */6534	if (ext_attr->standard != DRX_STANDARD_ITU_B)6535		fec_oc_snc_fail_period = fec_rs_period;6536 6537	/* limit to max 16 bit value (I2C register width) if needed */6538	if (fec_rs_period > 0xFFFF)6539		fec_rs_period = 0xFFFF;6540 6541	/* write corresponding registers */6542	switch (ext_attr->standard) {6543	case DRX_STANDARD_ITU_A:6544	case DRX_STANDARD_ITU_C:6545		break;6546	case DRX_STANDARD_ITU_B:6547		switch (constellation) {6548		case DRX_CONSTELLATION_QAM64:6549			fec_rs_period = 31581;6550			fec_oc_snc_fail_period = 17932;6551			break;6552		case DRX_CONSTELLATION_QAM256:6553			fec_rs_period = 45446;6554			fec_oc_snc_fail_period = 25805;6555			break;6556		default:6557			return -EINVAL;6558		}6559		break;6560	default:6561		return -EINVAL;6562	}6563 6564	rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);6565	if (rc != 0) {6566		pr_err("error %d\n", rc);6567		goto rw_error;6568	}6569	rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);6570	if (rc != 0) {6571		pr_err("error %d\n", rc);6572		goto rw_error;6573	}6574	rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);6575	if (rc != 0) {6576		pr_err("error %d\n", rc);6577		goto rw_error;6578	}6579	ext_attr->fec_rs_period = (u16) fec_rs_period;6580	ext_attr->fec_rs_prescale = fec_rs_prescale;6581	rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);6582	if (rc != 0) {6583		pr_err("error %d\n", rc);6584		goto rw_error;6585	}6586	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);6587	if (rc != 0) {6588		pr_err("error %d\n", rc);6589		goto rw_error;6590	}6591	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);6592	if (rc != 0) {6593		pr_err("error %d\n", rc);6594		goto rw_error;6595	}6596 6597	if (ext_attr->standard == DRX_STANDARD_ITU_B) {6598		/* Parameters for Viterbi Decoder */6599		/* qamvd_period = (int)ceil(FEC_BITS_DESIRED/                      */6600		/*                    (qamvd_prescale*plen*(qam_constellation+1))) */6601		/* vd_bit_cnt   = qamvd_period*qamvd_prescale*plen                 */6602		/*     result is within 32 bit arithmetic ->                       */6603		/*     no need for mult or frac functions                          */6604 6605		/* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */6606		fec_vd_plen = ext_attr->fec_vd_plen;6607		qam_vd_prescale = ext_attr->qam_vd_prescale;6608		qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen;	/* temp storage */6609 6610		switch (constellation) {6611		case DRX_CONSTELLATION_QAM64:6612			/* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */6613			qam_vd_period =6614			    qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)6615			    * (QAM_TOP_CONSTELLATION_QAM64 + 1);6616			break;6617		case DRX_CONSTELLATION_QAM256:6618			/* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */6619			qam_vd_period =6620			    qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)6621			    * (QAM_TOP_CONSTELLATION_QAM256 + 1);6622			break;6623		default:6624			return -EINVAL;6625		}6626		if (qam_vd_period == 0) {6627			pr_err("error: qam_vd_period is zero!\n");6628			return -EIO;6629		}6630		qam_vd_period = fec_bits_desired / qam_vd_period;6631		/* limit to max 16 bit value (I2C register width) if needed */6632		if (qam_vd_period > 0xFFFF)6633			qam_vd_period = 0xFFFF;6634 6635		/* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */6636		qam_vd_bit_cnt *= qam_vd_period;6637 6638		rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);6639		if (rc != 0) {6640			pr_err("error %d\n", rc);6641			goto rw_error;6642		}6643		rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);6644		if (rc != 0) {6645			pr_err("error %d\n", rc);6646			goto rw_error;6647		}6648		ext_attr->qam_vd_period = (u16) qam_vd_period;6649		ext_attr->qam_vd_prescale = qam_vd_prescale;6650	}6651 6652	return 0;6653rw_error:6654	return rc;6655}6656 6657/*============================================================================*/6658 6659/*6660* \fn int set_qam16 ()6661* \brief QAM16 specific setup6662* \param demod instance of demod.6663* \return int.6664*/6665static int set_qam16(struct drx_demod_instance *demod)6666{6667	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;6668	int rc;6669	static const u8 qam_dq_qual_fun[] = {6670		DRXJ_16TO8(2),	/* fun0  */6671		DRXJ_16TO8(2),	/* fun1  */6672		DRXJ_16TO8(2),	/* fun2  */6673		DRXJ_16TO8(2),	/* fun3  */6674		DRXJ_16TO8(3),	/* fun4  */6675		DRXJ_16TO8(3),	/* fun5  */6676	};6677	static const u8 qam_eq_cma_rad[] = {6678		DRXJ_16TO8(13517),	/* RAD0  */6679		DRXJ_16TO8(13517),	/* RAD1  */6680		DRXJ_16TO8(13517),	/* RAD2  */6681		DRXJ_16TO8(13517),	/* RAD3  */6682		DRXJ_16TO8(13517),	/* RAD4  */6683		DRXJ_16TO8(13517),	/* RAD5  */6684	};6685 6686	rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);6687	if (rc != 0) {6688		pr_err("error %d\n", rc);6689		goto rw_error;6690	}6691	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);6692	if (rc != 0) {6693		pr_err("error %d\n", rc);6694		goto rw_error;6695	}6696 6697	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);6698	if (rc != 0) {6699		pr_err("error %d\n", rc);6700		goto rw_error;6701	}6702	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);6703	if (rc != 0) {6704		pr_err("error %d\n", rc);6705		goto rw_error;6706	}6707	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);6708	if (rc != 0) {6709		pr_err("error %d\n", rc);6710		goto rw_error;6711	}6712	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);6713	if (rc != 0) {6714		pr_err("error %d\n", rc);6715		goto rw_error;6716	}6717	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);6718	if (rc != 0) {6719		pr_err("error %d\n", rc);6720		goto rw_error;6721	}6722	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);6723	if (rc != 0) {6724		pr_err("error %d\n", rc);6725		goto rw_error;6726	}6727 6728	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);6729	if (rc != 0) {6730		pr_err("error %d\n", rc);6731		goto rw_error;6732	}6733	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);6734	if (rc != 0) {6735		pr_err("error %d\n", rc);6736		goto rw_error;6737	}6738	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);6739	if (rc != 0) {6740		pr_err("error %d\n", rc);6741		goto rw_error;6742	}6743 6744	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);6745	if (rc != 0) {6746		pr_err("error %d\n", rc);6747		goto rw_error;6748	}6749	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);6750	if (rc != 0) {6751		pr_err("error %d\n", rc);6752		goto rw_error;6753	}6754	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);6755	if (rc != 0) {6756		pr_err("error %d\n", rc);6757		goto rw_error;6758	}6759	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);6760	if (rc != 0) {6761		pr_err("error %d\n", rc);6762		goto rw_error;6763	}6764	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);6765	if (rc != 0) {6766		pr_err("error %d\n", rc);6767		goto rw_error;6768	}6769	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);6770	if (rc != 0) {6771		pr_err("error %d\n", rc);6772		goto rw_error;6773	}6774	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);6775	if (rc != 0) {6776		pr_err("error %d\n", rc);6777		goto rw_error;6778	}6779 6780	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);6781	if (rc != 0) {6782		pr_err("error %d\n", rc);6783		goto rw_error;6784	}6785	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);6786	if (rc != 0) {6787		pr_err("error %d\n", rc);6788		goto rw_error;6789	}6790	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);6791	if (rc != 0) {6792		pr_err("error %d\n", rc);6793		goto rw_error;6794	}6795	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);6796	if (rc != 0) {6797		pr_err("error %d\n", rc);6798		goto rw_error;6799	}6800	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);6801	if (rc != 0) {6802		pr_err("error %d\n", rc);6803		goto rw_error;6804	}6805	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);6806	if (rc != 0) {6807		pr_err("error %d\n", rc);6808		goto rw_error;6809	}6810	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);6811	if (rc != 0) {6812		pr_err("error %d\n", rc);6813		goto rw_error;6814	}6815	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);6816	if (rc != 0) {6817		pr_err("error %d\n", rc);6818		goto rw_error;6819	}6820	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);6821	if (rc != 0) {6822		pr_err("error %d\n", rc);6823		goto rw_error;6824	}6825	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);6826	if (rc != 0) {6827		pr_err("error %d\n", rc);6828		goto rw_error;6829	}6830	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);6831	if (rc != 0) {6832		pr_err("error %d\n", rc);6833		goto rw_error;6834	}6835	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);6836	if (rc != 0) {6837		pr_err("error %d\n", rc);6838		goto rw_error;6839	}6840	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);6841	if (rc != 0) {6842		pr_err("error %d\n", rc);6843		goto rw_error;6844	}6845	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);6846	if (rc != 0) {6847		pr_err("error %d\n", rc);6848		goto rw_error;6849	}6850	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);6851	if (rc != 0) {6852		pr_err("error %d\n", rc);6853		goto rw_error;6854	}6855	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);6856	if (rc != 0) {6857		pr_err("error %d\n", rc);6858		goto rw_error;6859	}6860	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);6861	if (rc != 0) {6862		pr_err("error %d\n", rc);6863		goto rw_error;6864	}6865	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);6866	if (rc != 0) {6867		pr_err("error %d\n", rc);6868		goto rw_error;6869	}6870	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);6871	if (rc != 0) {6872		pr_err("error %d\n", rc);6873		goto rw_error;6874	}6875	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);6876	if (rc != 0) {6877		pr_err("error %d\n", rc);6878		goto rw_error;6879	}6880 6881	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);6882	if (rc != 0) {6883		pr_err("error %d\n", rc);6884		goto rw_error;6885	}6886 6887	return 0;6888rw_error:6889	return rc;6890}6891 6892/*============================================================================*/6893 6894/*6895* \fn int set_qam32 ()6896* \brief QAM32 specific setup6897* \param demod instance of demod.6898* \return int.6899*/6900static int set_qam32(struct drx_demod_instance *demod)6901{6902	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;6903	int rc;6904	static const u8 qam_dq_qual_fun[] = {6905		DRXJ_16TO8(3),	/* fun0  */6906		DRXJ_16TO8(3),	/* fun1  */6907		DRXJ_16TO8(3),	/* fun2  */6908		DRXJ_16TO8(3),	/* fun3  */6909		DRXJ_16TO8(4),	/* fun4  */6910		DRXJ_16TO8(4),	/* fun5  */6911	};6912	static const u8 qam_eq_cma_rad[] = {6913		DRXJ_16TO8(6707),	/* RAD0  */6914		DRXJ_16TO8(6707),	/* RAD1  */6915		DRXJ_16TO8(6707),	/* RAD2  */6916		DRXJ_16TO8(6707),	/* RAD3  */6917		DRXJ_16TO8(6707),	/* RAD4  */6918		DRXJ_16TO8(6707),	/* RAD5  */6919	};6920 6921	rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);6922	if (rc != 0) {6923		pr_err("error %d\n", rc);6924		goto rw_error;6925	}6926	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);6927	if (rc != 0) {6928		pr_err("error %d\n", rc);6929		goto rw_error;6930	}6931 6932	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);6933	if (rc != 0) {6934		pr_err("error %d\n", rc);6935		goto rw_error;6936	}6937	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);6938	if (rc != 0) {6939		pr_err("error %d\n", rc);6940		goto rw_error;6941	}6942	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);6943	if (rc != 0) {6944		pr_err("error %d\n", rc);6945		goto rw_error;6946	}6947	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);6948	if (rc != 0) {6949		pr_err("error %d\n", rc);6950		goto rw_error;6951	}6952	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);6953	if (rc != 0) {6954		pr_err("error %d\n", rc);6955		goto rw_error;6956	}6957	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);6958	if (rc != 0) {6959		pr_err("error %d\n", rc);6960		goto rw_error;6961	}6962 6963	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);6964	if (rc != 0) {6965		pr_err("error %d\n", rc);6966		goto rw_error;6967	}6968	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);6969	if (rc != 0) {6970		pr_err("error %d\n", rc);6971		goto rw_error;6972	}6973	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);6974	if (rc != 0) {6975		pr_err("error %d\n", rc);6976		goto rw_error;6977	}6978 6979	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);6980	if (rc != 0) {6981		pr_err("error %d\n", rc);6982		goto rw_error;6983	}6984	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);6985	if (rc != 0) {6986		pr_err("error %d\n", rc);6987		goto rw_error;6988	}6989	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);6990	if (rc != 0) {6991		pr_err("error %d\n", rc);6992		goto rw_error;6993	}6994	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);6995	if (rc != 0) {6996		pr_err("error %d\n", rc);6997		goto rw_error;6998	}6999	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);7000	if (rc != 0) {7001		pr_err("error %d\n", rc);7002		goto rw_error;7003	}7004	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);7005	if (rc != 0) {7006		pr_err("error %d\n", rc);7007		goto rw_error;7008	}7009	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);7010	if (rc != 0) {7011		pr_err("error %d\n", rc);7012		goto rw_error;7013	}7014 7015	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);7016	if (rc != 0) {7017		pr_err("error %d\n", rc);7018		goto rw_error;7019	}7020	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);7021	if (rc != 0) {7022		pr_err("error %d\n", rc);7023		goto rw_error;7024	}7025	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);7026	if (rc != 0) {7027		pr_err("error %d\n", rc);7028		goto rw_error;7029	}7030	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);7031	if (rc != 0) {7032		pr_err("error %d\n", rc);7033		goto rw_error;7034	}7035	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);7036	if (rc != 0) {7037		pr_err("error %d\n", rc);7038		goto rw_error;7039	}7040	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);7041	if (rc != 0) {7042		pr_err("error %d\n", rc);7043		goto rw_error;7044	}7045	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);7046	if (rc != 0) {7047		pr_err("error %d\n", rc);7048		goto rw_error;7049	}7050	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);7051	if (rc != 0) {7052		pr_err("error %d\n", rc);7053		goto rw_error;7054	}7055	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);7056	if (rc != 0) {7057		pr_err("error %d\n", rc);7058		goto rw_error;7059	}7060	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);7061	if (rc != 0) {7062		pr_err("error %d\n", rc);7063		goto rw_error;7064	}7065	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);7066	if (rc != 0) {7067		pr_err("error %d\n", rc);7068		goto rw_error;7069	}7070	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);7071	if (rc != 0) {7072		pr_err("error %d\n", rc);7073		goto rw_error;7074	}7075	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);7076	if (rc != 0) {7077		pr_err("error %d\n", rc);7078		goto rw_error;7079	}7080	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);7081	if (rc != 0) {7082		pr_err("error %d\n", rc);7083		goto rw_error;7084	}7085	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);7086	if (rc != 0) {7087		pr_err("error %d\n", rc);7088		goto rw_error;7089	}7090	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);7091	if (rc != 0) {7092		pr_err("error %d\n", rc);7093		goto rw_error;7094	}7095	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);7096	if (rc != 0) {7097		pr_err("error %d\n", rc);7098		goto rw_error;7099	}7100	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);7101	if (rc != 0) {7102		pr_err("error %d\n", rc);7103		goto rw_error;7104	}7105	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);7106	if (rc != 0) {7107		pr_err("error %d\n", rc);7108		goto rw_error;7109	}7110	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);7111	if (rc != 0) {7112		pr_err("error %d\n", rc);7113		goto rw_error;7114	}7115 7116	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);7117	if (rc != 0) {7118		pr_err("error %d\n", rc);7119		goto rw_error;7120	}7121 7122	return 0;7123rw_error:7124	return rc;7125}7126 7127/*============================================================================*/7128 7129/*7130* \fn int set_qam64 ()7131* \brief QAM64 specific setup7132* \param demod instance of demod.7133* \return int.7134*/7135static int set_qam64(struct drx_demod_instance *demod)7136{7137	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;7138	int rc;7139	static const u8 qam_dq_qual_fun[] = {7140		/* this is hw reset value. no necessary to re-write */7141		DRXJ_16TO8(4),	/* fun0  */7142		DRXJ_16TO8(4),	/* fun1  */7143		DRXJ_16TO8(4),	/* fun2  */7144		DRXJ_16TO8(4),	/* fun3  */7145		DRXJ_16TO8(6),	/* fun4  */7146		DRXJ_16TO8(6),	/* fun5  */7147	};7148	static const u8 qam_eq_cma_rad[] = {7149		DRXJ_16TO8(13336),	/* RAD0  */7150		DRXJ_16TO8(12618),	/* RAD1  */7151		DRXJ_16TO8(11988),	/* RAD2  */7152		DRXJ_16TO8(13809),	/* RAD3  */7153		DRXJ_16TO8(13809),	/* RAD4  */7154		DRXJ_16TO8(15609),	/* RAD5  */7155	};7156 7157	rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);7158	if (rc != 0) {7159		pr_err("error %d\n", rc);7160		goto rw_error;7161	}7162	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);7163	if (rc != 0) {7164		pr_err("error %d\n", rc);7165		goto rw_error;7166	}7167 7168	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);7169	if (rc != 0) {7170		pr_err("error %d\n", rc);7171		goto rw_error;7172	}7173	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);7174	if (rc != 0) {7175		pr_err("error %d\n", rc);7176		goto rw_error;7177	}7178	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);7179	if (rc != 0) {7180		pr_err("error %d\n", rc);7181		goto rw_error;7182	}7183	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);7184	if (rc != 0) {7185		pr_err("error %d\n", rc);7186		goto rw_error;7187	}7188	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);7189	if (rc != 0) {7190		pr_err("error %d\n", rc);7191		goto rw_error;7192	}7193	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);7194	if (rc != 0) {7195		pr_err("error %d\n", rc);7196		goto rw_error;7197	}7198 7199	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);7200	if (rc != 0) {7201		pr_err("error %d\n", rc);7202		goto rw_error;7203	}7204	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);7205	if (rc != 0) {7206		pr_err("error %d\n", rc);7207		goto rw_error;7208	}7209	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);7210	if (rc != 0) {7211		pr_err("error %d\n", rc);7212		goto rw_error;7213	}7214 7215	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);7216	if (rc != 0) {7217		pr_err("error %d\n", rc);7218		goto rw_error;7219	}7220	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);7221	if (rc != 0) {7222		pr_err("error %d\n", rc);7223		goto rw_error;7224	}7225	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);7226	if (rc != 0) {7227		pr_err("error %d\n", rc);7228		goto rw_error;7229	}7230	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);7231	if (rc != 0) {7232		pr_err("error %d\n", rc);7233		goto rw_error;7234	}7235	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);7236	if (rc != 0) {7237		pr_err("error %d\n", rc);7238		goto rw_error;7239	}7240	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);7241	if (rc != 0) {7242		pr_err("error %d\n", rc);7243		goto rw_error;7244	}7245	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);7246	if (rc != 0) {7247		pr_err("error %d\n", rc);7248		goto rw_error;7249	}7250 7251	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);7252	if (rc != 0) {7253		pr_err("error %d\n", rc);7254		goto rw_error;7255	}7256	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);7257	if (rc != 0) {7258		pr_err("error %d\n", rc);7259		goto rw_error;7260	}7261	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);7262	if (rc != 0) {7263		pr_err("error %d\n", rc);7264		goto rw_error;7265	}7266	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);7267	if (rc != 0) {7268		pr_err("error %d\n", rc);7269		goto rw_error;7270	}7271	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);7272	if (rc != 0) {7273		pr_err("error %d\n", rc);7274		goto rw_error;7275	}7276	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);7277	if (rc != 0) {7278		pr_err("error %d\n", rc);7279		goto rw_error;7280	}7281	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);7282	if (rc != 0) {7283		pr_err("error %d\n", rc);7284		goto rw_error;7285	}7286	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);7287	if (rc != 0) {7288		pr_err("error %d\n", rc);7289		goto rw_error;7290	}7291	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);7292	if (rc != 0) {7293		pr_err("error %d\n", rc);7294		goto rw_error;7295	}7296	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);7297	if (rc != 0) {7298		pr_err("error %d\n", rc);7299		goto rw_error;7300	}7301	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);7302	if (rc != 0) {7303		pr_err("error %d\n", rc);7304		goto rw_error;7305	}7306	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);7307	if (rc != 0) {7308		pr_err("error %d\n", rc);7309		goto rw_error;7310	}7311	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);7312	if (rc != 0) {7313		pr_err("error %d\n", rc);7314		goto rw_error;7315	}7316	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);7317	if (rc != 0) {7318		pr_err("error %d\n", rc);7319		goto rw_error;7320	}7321	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);7322	if (rc != 0) {7323		pr_err("error %d\n", rc);7324		goto rw_error;7325	}7326	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);7327	if (rc != 0) {7328		pr_err("error %d\n", rc);7329		goto rw_error;7330	}7331	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);7332	if (rc != 0) {7333		pr_err("error %d\n", rc);7334		goto rw_error;7335	}7336	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);7337	if (rc != 0) {7338		pr_err("error %d\n", rc);7339		goto rw_error;7340	}7341	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);7342	if (rc != 0) {7343		pr_err("error %d\n", rc);7344		goto rw_error;7345	}7346	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);7347	if (rc != 0) {7348		pr_err("error %d\n", rc);7349		goto rw_error;7350	}7351 7352	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);7353	if (rc != 0) {7354		pr_err("error %d\n", rc);7355		goto rw_error;7356	}7357 7358	return 0;7359rw_error:7360	return rc;7361}7362 7363/*============================================================================*/7364 7365/*7366* \fn int set_qam128 ()7367* \brief QAM128 specific setup7368* \param demod: instance of demod.7369* \return int.7370*/7371static int set_qam128(struct drx_demod_instance *demod)7372{7373	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;7374	int rc;7375	static const u8 qam_dq_qual_fun[] = {7376		DRXJ_16TO8(6),	/* fun0  */7377		DRXJ_16TO8(6),	/* fun1  */7378		DRXJ_16TO8(6),	/* fun2  */7379		DRXJ_16TO8(6),	/* fun3  */7380		DRXJ_16TO8(9),	/* fun4  */7381		DRXJ_16TO8(9),	/* fun5  */7382	};7383	static const u8 qam_eq_cma_rad[] = {7384		DRXJ_16TO8(6164),	/* RAD0  */7385		DRXJ_16TO8(6598),	/* RAD1  */7386		DRXJ_16TO8(6394),	/* RAD2  */7387		DRXJ_16TO8(6409),	/* RAD3  */7388		DRXJ_16TO8(6656),	/* RAD4  */7389		DRXJ_16TO8(7238),	/* RAD5  */7390	};7391 7392	rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);7393	if (rc != 0) {7394		pr_err("error %d\n", rc);7395		goto rw_error;7396	}7397	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);7398	if (rc != 0) {7399		pr_err("error %d\n", rc);7400		goto rw_error;7401	}7402 7403	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);7404	if (rc != 0) {7405		pr_err("error %d\n", rc);7406		goto rw_error;7407	}7408	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);7409	if (rc != 0) {7410		pr_err("error %d\n", rc);7411		goto rw_error;7412	}7413	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);7414	if (rc != 0) {7415		pr_err("error %d\n", rc);7416		goto rw_error;7417	}7418	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);7419	if (rc != 0) {7420		pr_err("error %d\n", rc);7421		goto rw_error;7422	}7423	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);7424	if (rc != 0) {7425		pr_err("error %d\n", rc);7426		goto rw_error;7427	}7428	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);7429	if (rc != 0) {7430		pr_err("error %d\n", rc);7431		goto rw_error;7432	}7433 7434	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);7435	if (rc != 0) {7436		pr_err("error %d\n", rc);7437		goto rw_error;7438	}7439	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);7440	if (rc != 0) {7441		pr_err("error %d\n", rc);7442		goto rw_error;7443	}7444	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);7445	if (rc != 0) {7446		pr_err("error %d\n", rc);7447		goto rw_error;7448	}7449 7450	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);7451	if (rc != 0) {7452		pr_err("error %d\n", rc);7453		goto rw_error;7454	}7455	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);7456	if (rc != 0) {7457		pr_err("error %d\n", rc);7458		goto rw_error;7459	}7460	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);7461	if (rc != 0) {7462		pr_err("error %d\n", rc);7463		goto rw_error;7464	}7465	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);7466	if (rc != 0) {7467		pr_err("error %d\n", rc);7468		goto rw_error;7469	}7470	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);7471	if (rc != 0) {7472		pr_err("error %d\n", rc);7473		goto rw_error;7474	}7475	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);7476	if (rc != 0) {7477		pr_err("error %d\n", rc);7478		goto rw_error;7479	}7480	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);7481	if (rc != 0) {7482		pr_err("error %d\n", rc);7483		goto rw_error;7484	}7485 7486	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);7487	if (rc != 0) {7488		pr_err("error %d\n", rc);7489		goto rw_error;7490	}7491	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);7492	if (rc != 0) {7493		pr_err("error %d\n", rc);7494		goto rw_error;7495	}7496	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);7497	if (rc != 0) {7498		pr_err("error %d\n", rc);7499		goto rw_error;7500	}7501	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);7502	if (rc != 0) {7503		pr_err("error %d\n", rc);7504		goto rw_error;7505	}7506	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);7507	if (rc != 0) {7508		pr_err("error %d\n", rc);7509		goto rw_error;7510	}7511	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);7512	if (rc != 0) {7513		pr_err("error %d\n", rc);7514		goto rw_error;7515	}7516	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);7517	if (rc != 0) {7518		pr_err("error %d\n", rc);7519		goto rw_error;7520	}7521	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);7522	if (rc != 0) {7523		pr_err("error %d\n", rc);7524		goto rw_error;7525	}7526	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);7527	if (rc != 0) {7528		pr_err("error %d\n", rc);7529		goto rw_error;7530	}7531	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);7532	if (rc != 0) {7533		pr_err("error %d\n", rc);7534		goto rw_error;7535	}7536	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);7537	if (rc != 0) {7538		pr_err("error %d\n", rc);7539		goto rw_error;7540	}7541	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);7542	if (rc != 0) {7543		pr_err("error %d\n", rc);7544		goto rw_error;7545	}7546	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);7547	if (rc != 0) {7548		pr_err("error %d\n", rc);7549		goto rw_error;7550	}7551	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);7552	if (rc != 0) {7553		pr_err("error %d\n", rc);7554		goto rw_error;7555	}7556	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);7557	if (rc != 0) {7558		pr_err("error %d\n", rc);7559		goto rw_error;7560	}7561	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);7562	if (rc != 0) {7563		pr_err("error %d\n", rc);7564		goto rw_error;7565	}7566	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);7567	if (rc != 0) {7568		pr_err("error %d\n", rc);7569		goto rw_error;7570	}7571	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);7572	if (rc != 0) {7573		pr_err("error %d\n", rc);7574		goto rw_error;7575	}7576	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);7577	if (rc != 0) {7578		pr_err("error %d\n", rc);7579		goto rw_error;7580	}7581	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);7582	if (rc != 0) {7583		pr_err("error %d\n", rc);7584		goto rw_error;7585	}7586 7587	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);7588	if (rc != 0) {7589		pr_err("error %d\n", rc);7590		goto rw_error;7591	}7592 7593	return 0;7594rw_error:7595	return rc;7596}7597 7598/*============================================================================*/7599 7600/*7601* \fn int set_qam256 ()7602* \brief QAM256 specific setup7603* \param demod: instance of demod.7604* \return int.7605*/7606static int set_qam256(struct drx_demod_instance *demod)7607{7608	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;7609	int rc;7610	static const u8 qam_dq_qual_fun[] = {7611		DRXJ_16TO8(8),	/* fun0  */7612		DRXJ_16TO8(8),	/* fun1  */7613		DRXJ_16TO8(8),	/* fun2  */7614		DRXJ_16TO8(8),	/* fun3  */7615		DRXJ_16TO8(12),	/* fun4  */7616		DRXJ_16TO8(12),	/* fun5  */7617	};7618	static const u8 qam_eq_cma_rad[] = {7619		DRXJ_16TO8(12345),	/* RAD0  */7620		DRXJ_16TO8(12345),	/* RAD1  */7621		DRXJ_16TO8(13626),	/* RAD2  */7622		DRXJ_16TO8(12931),	/* RAD3  */7623		DRXJ_16TO8(14719),	/* RAD4  */7624		DRXJ_16TO8(15356),	/* RAD5  */7625	};7626 7627	rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);7628	if (rc != 0) {7629		pr_err("error %d\n", rc);7630		goto rw_error;7631	}7632	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);7633	if (rc != 0) {7634		pr_err("error %d\n", rc);7635		goto rw_error;7636	}7637 7638	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);7639	if (rc != 0) {7640		pr_err("error %d\n", rc);7641		goto rw_error;7642	}7643	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);7644	if (rc != 0) {7645		pr_err("error %d\n", rc);7646		goto rw_error;7647	}7648	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);7649	if (rc != 0) {7650		pr_err("error %d\n", rc);7651		goto rw_error;7652	}7653	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);7654	if (rc != 0) {7655		pr_err("error %d\n", rc);7656		goto rw_error;7657	}7658	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);7659	if (rc != 0) {7660		pr_err("error %d\n", rc);7661		goto rw_error;7662	}7663	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);7664	if (rc != 0) {7665		pr_err("error %d\n", rc);7666		goto rw_error;7667	}7668 7669	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);7670	if (rc != 0) {7671		pr_err("error %d\n", rc);7672		goto rw_error;7673	}7674	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);7675	if (rc != 0) {7676		pr_err("error %d\n", rc);7677		goto rw_error;7678	}7679	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);7680	if (rc != 0) {7681		pr_err("error %d\n", rc);7682		goto rw_error;7683	}7684 7685	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);7686	if (rc != 0) {7687		pr_err("error %d\n", rc);7688		goto rw_error;7689	}7690	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);7691	if (rc != 0) {7692		pr_err("error %d\n", rc);7693		goto rw_error;7694	}7695	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);7696	if (rc != 0) {7697		pr_err("error %d\n", rc);7698		goto rw_error;7699	}7700	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);7701	if (rc != 0) {7702		pr_err("error %d\n", rc);7703		goto rw_error;7704	}7705	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);7706	if (rc != 0) {7707		pr_err("error %d\n", rc);7708		goto rw_error;7709	}7710	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);7711	if (rc != 0) {7712		pr_err("error %d\n", rc);7713		goto rw_error;7714	}7715	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);7716	if (rc != 0) {7717		pr_err("error %d\n", rc);7718		goto rw_error;7719	}7720 7721	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);7722	if (rc != 0) {7723		pr_err("error %d\n", rc);7724		goto rw_error;7725	}7726	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);7727	if (rc != 0) {7728		pr_err("error %d\n", rc);7729		goto rw_error;7730	}7731	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);7732	if (rc != 0) {7733		pr_err("error %d\n", rc);7734		goto rw_error;7735	}7736	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);7737	if (rc != 0) {7738		pr_err("error %d\n", rc);7739		goto rw_error;7740	}7741	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);7742	if (rc != 0) {7743		pr_err("error %d\n", rc);7744		goto rw_error;7745	}7746	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);7747	if (rc != 0) {7748		pr_err("error %d\n", rc);7749		goto rw_error;7750	}7751	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);7752	if (rc != 0) {7753		pr_err("error %d\n", rc);7754		goto rw_error;7755	}7756	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);7757	if (rc != 0) {7758		pr_err("error %d\n", rc);7759		goto rw_error;7760	}7761	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);7762	if (rc != 0) {7763		pr_err("error %d\n", rc);7764		goto rw_error;7765	}7766	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);7767	if (rc != 0) {7768		pr_err("error %d\n", rc);7769		goto rw_error;7770	}7771	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);7772	if (rc != 0) {7773		pr_err("error %d\n", rc);7774		goto rw_error;7775	}7776	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);7777	if (rc != 0) {7778		pr_err("error %d\n", rc);7779		goto rw_error;7780	}7781	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);7782	if (rc != 0) {7783		pr_err("error %d\n", rc);7784		goto rw_error;7785	}7786	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);7787	if (rc != 0) {7788		pr_err("error %d\n", rc);7789		goto rw_error;7790	}7791	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);7792	if (rc != 0) {7793		pr_err("error %d\n", rc);7794		goto rw_error;7795	}7796	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);7797	if (rc != 0) {7798		pr_err("error %d\n", rc);7799		goto rw_error;7800	}7801	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);7802	if (rc != 0) {7803		pr_err("error %d\n", rc);7804		goto rw_error;7805	}7806	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);7807	if (rc != 0) {7808		pr_err("error %d\n", rc);7809		goto rw_error;7810	}7811	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);7812	if (rc != 0) {7813		pr_err("error %d\n", rc);7814		goto rw_error;7815	}7816	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);7817	if (rc != 0) {7818		pr_err("error %d\n", rc);7819		goto rw_error;7820	}7821 7822	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);7823	if (rc != 0) {7824		pr_err("error %d\n", rc);7825		goto rw_error;7826	}7827 7828	return 0;7829rw_error:7830	return rc;7831}7832 7833/*============================================================================*/7834#define QAM_SET_OP_ALL 0x17835#define QAM_SET_OP_CONSTELLATION 0x27836#define QAM_SET_OP_SPECTRUM 0X47837 7838/*7839* \fn int set_qam ()7840* \brief Set QAM demod.7841* \param demod:   instance of demod.7842* \param channel: pointer to channel data.7843* \return int.7844*/7845static int7846set_qam(struct drx_demod_instance *demod,7847	struct drx_channel *channel, s32 tuner_freq_offset, u32 op)7848{7849	struct i2c_device_addr *dev_addr = NULL;7850	struct drxj_data *ext_attr = NULL;7851	struct drx_common_attr *common_attr = NULL;7852	int rc;7853	u32 adc_frequency = 0;7854	u32 iqm_rc_rate = 0;7855	u16 cmd_result = 0;7856	u16 lc_symbol_freq = 0;7857	u16 iqm_rc_stretch = 0;7858	u16 set_env_parameters = 0;7859	u16 set_param_parameters[2] = { 0 };7860	struct drxjscu_cmd cmd_scu = { /* command      */ 0,7861		/* parameter_len */ 0,7862		/* result_len    */ 0,7863		/* parameter    */ NULL,7864		/* result       */ NULL7865	};7866	static const u8 qam_a_taps[] = {7867		DRXJ_16TO8(-1),	/* re0  */7868		DRXJ_16TO8(1),	/* re1  */7869		DRXJ_16TO8(1),	/* re2  */7870		DRXJ_16TO8(-1),	/* re3  */7871		DRXJ_16TO8(-1),	/* re4  */7872		DRXJ_16TO8(2),	/* re5  */7873		DRXJ_16TO8(1),	/* re6  */7874		DRXJ_16TO8(-2),	/* re7  */7875		DRXJ_16TO8(0),	/* re8  */7876		DRXJ_16TO8(3),	/* re9  */7877		DRXJ_16TO8(-1),	/* re10 */7878		DRXJ_16TO8(-3),	/* re11 */7879		DRXJ_16TO8(4),	/* re12 */7880		DRXJ_16TO8(1),	/* re13 */7881		DRXJ_16TO8(-8),	/* re14 */7882		DRXJ_16TO8(4),	/* re15 */7883		DRXJ_16TO8(13),	/* re16 */7884		DRXJ_16TO8(-13),	/* re17 */7885		DRXJ_16TO8(-19),	/* re18 */7886		DRXJ_16TO8(28),	/* re19 */7887		DRXJ_16TO8(25),	/* re20 */7888		DRXJ_16TO8(-53),	/* re21 */7889		DRXJ_16TO8(-31),	/* re22 */7890		DRXJ_16TO8(96),	/* re23 */7891		DRXJ_16TO8(37),	/* re24 */7892		DRXJ_16TO8(-190),	/* re25 */7893		DRXJ_16TO8(-40),	/* re26 */7894		DRXJ_16TO8(619)	/* re27 */7895	};7896	static const u8 qam_b64_taps[] = {7897		DRXJ_16TO8(0),	/* re0  */7898		DRXJ_16TO8(-2),	/* re1  */7899		DRXJ_16TO8(1),	/* re2  */7900		DRXJ_16TO8(2),	/* re3  */7901		DRXJ_16TO8(-2),	/* re4  */7902		DRXJ_16TO8(0),	/* re5  */7903		DRXJ_16TO8(4),	/* re6  */7904		DRXJ_16TO8(-2),	/* re7  */7905		DRXJ_16TO8(-4),	/* re8  */7906		DRXJ_16TO8(4),	/* re9  */7907		DRXJ_16TO8(3),	/* re10 */7908		DRXJ_16TO8(-6),	/* re11 */7909		DRXJ_16TO8(0),	/* re12 */7910		DRXJ_16TO8(6),	/* re13 */7911		DRXJ_16TO8(-5),	/* re14 */7912		DRXJ_16TO8(-3),	/* re15 */7913		DRXJ_16TO8(11),	/* re16 */7914		DRXJ_16TO8(-4),	/* re17 */7915		DRXJ_16TO8(-19),	/* re18 */7916		DRXJ_16TO8(19),	/* re19 */7917		DRXJ_16TO8(28),	/* re20 */7918		DRXJ_16TO8(-45),	/* re21 */7919		DRXJ_16TO8(-36),	/* re22 */7920		DRXJ_16TO8(90),	/* re23 */7921		DRXJ_16TO8(42),	/* re24 */7922		DRXJ_16TO8(-185),	/* re25 */7923		DRXJ_16TO8(-46),	/* re26 */7924		DRXJ_16TO8(614)	/* re27 */7925	};7926	static const u8 qam_b256_taps[] = {7927		DRXJ_16TO8(-2),	/* re0  */7928		DRXJ_16TO8(4),	/* re1  */7929		DRXJ_16TO8(1),	/* re2  */7930		DRXJ_16TO8(-4),	/* re3  */7931		DRXJ_16TO8(0),	/* re4  */7932		DRXJ_16TO8(4),	/* re5  */7933		DRXJ_16TO8(-2),	/* re6  */7934		DRXJ_16TO8(-4),	/* re7  */7935		DRXJ_16TO8(5),	/* re8  */7936		DRXJ_16TO8(2),	/* re9  */7937		DRXJ_16TO8(-8),	/* re10 */7938		DRXJ_16TO8(2),	/* re11 */7939		DRXJ_16TO8(11),	/* re12 */7940		DRXJ_16TO8(-8),	/* re13 */7941		DRXJ_16TO8(-15),	/* re14 */7942		DRXJ_16TO8(16),	/* re15 */7943		DRXJ_16TO8(19),	/* re16 */7944		DRXJ_16TO8(-27),	/* re17 */7945		DRXJ_16TO8(-22),	/* re18 */7946		DRXJ_16TO8(44),	/* re19 */7947		DRXJ_16TO8(26),	/* re20 */7948		DRXJ_16TO8(-69),	/* re21 */7949		DRXJ_16TO8(-28),	/* re22 */7950		DRXJ_16TO8(110),	/* re23 */7951		DRXJ_16TO8(31),	/* re24 */7952		DRXJ_16TO8(-201),	/* re25 */7953		DRXJ_16TO8(-32),	/* re26 */7954		DRXJ_16TO8(628)	/* re27 */7955	};7956	static const u8 qam_c_taps[] = {7957		DRXJ_16TO8(-3),	/* re0  */7958		DRXJ_16TO8(3),	/* re1  */7959		DRXJ_16TO8(2),	/* re2  */7960		DRXJ_16TO8(-4),	/* re3  */7961		DRXJ_16TO8(0),	/* re4  */7962		DRXJ_16TO8(4),	/* re5  */7963		DRXJ_16TO8(-1),	/* re6  */7964		DRXJ_16TO8(-4),	/* re7  */7965		DRXJ_16TO8(3),	/* re8  */7966		DRXJ_16TO8(3),	/* re9  */7967		DRXJ_16TO8(-5),	/* re10 */7968		DRXJ_16TO8(0),	/* re11 */7969		DRXJ_16TO8(9),	/* re12 */7970		DRXJ_16TO8(-4),	/* re13 */7971		DRXJ_16TO8(-12),	/* re14 */7972		DRXJ_16TO8(10),	/* re15 */7973		DRXJ_16TO8(16),	/* re16 */7974		DRXJ_16TO8(-21),	/* re17 */7975		DRXJ_16TO8(-20),	/* re18 */7976		DRXJ_16TO8(37),	/* re19 */7977		DRXJ_16TO8(25),	/* re20 */7978		DRXJ_16TO8(-62),	/* re21 */7979		DRXJ_16TO8(-28),	/* re22 */7980		DRXJ_16TO8(105),	/* re23 */7981		DRXJ_16TO8(31),	/* re24 */7982		DRXJ_16TO8(-197),	/* re25 */7983		DRXJ_16TO8(-33),	/* re26 */7984		DRXJ_16TO8(626)	/* re27 */7985	};7986 7987	dev_addr = demod->my_i2c_dev_addr;7988	ext_attr = (struct drxj_data *) demod->my_ext_attr;7989	common_attr = (struct drx_common_attr *) demod->my_common_attr;7990 7991	if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {7992		if (ext_attr->standard == DRX_STANDARD_ITU_B) {7993			switch (channel->constellation) {7994			case DRX_CONSTELLATION_QAM256:7995				iqm_rc_rate = 0x00AE3562;7996				lc_symbol_freq =7997				    QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;7998				channel->symbolrate = 5360537;7999				iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;8000				break;8001			case DRX_CONSTELLATION_QAM64:8002				iqm_rc_rate = 0x00C05A0E;8003				lc_symbol_freq = 409;8004				channel->symbolrate = 5056941;8005				iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;8006				break;8007			default:8008				return -EINVAL;8009			}8010		} else {8011			adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;8012			if (channel->symbolrate == 0) {8013				pr_err("error: channel symbolrate is zero!\n");8014				return -EIO;8015			}8016			iqm_rc_rate =8017			    (adc_frequency / channel->symbolrate) * (1 << 21) +8018			    (frac288019			     ((adc_frequency % channel->symbolrate),8020			      channel->symbolrate) >> 7) - (1 << 23);8021			lc_symbol_freq =8022			    (u16) (frac288023				     (channel->symbolrate +8024				      (adc_frequency >> 13),8025				      adc_frequency) >> 16);8026			if (lc_symbol_freq > 511)8027				lc_symbol_freq = 511;8028 8029			iqm_rc_stretch = 21;8030		}8031 8032		if (ext_attr->standard == DRX_STANDARD_ITU_A) {8033			set_env_parameters = QAM_TOP_ANNEX_A;	/* annex             */8034			set_param_parameters[0] = channel->constellation;	/* constellation     */8035			set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;	/* interleave mode   */8036		} else if (ext_attr->standard == DRX_STANDARD_ITU_B) {8037			set_env_parameters = QAM_TOP_ANNEX_B;	/* annex             */8038			set_param_parameters[0] = channel->constellation;	/* constellation     */8039			set_param_parameters[1] = channel->interleavemode;	/* interleave mode   */8040		} else if (ext_attr->standard == DRX_STANDARD_ITU_C) {8041			set_env_parameters = QAM_TOP_ANNEX_C;	/* annex             */8042			set_param_parameters[0] = channel->constellation;	/* constellation     */8043			set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;	/* interleave mode   */8044		} else {8045			return -EINVAL;8046		}8047	}8048 8049	if (op & QAM_SET_OP_ALL) {8050		/*8051		   STEP 1: reset demodulator8052		   resets IQM, QAM and FEC HW blocks8053		   resets SCU variables8054		 */8055		/* stop all comm_exec */8056		rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);8057		if (rc != 0) {8058			pr_err("error %d\n", rc);8059			goto rw_error;8060		}8061		rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);8062		if (rc != 0) {8063			pr_err("error %d\n", rc);8064			goto rw_error;8065		}8066		rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);8067		if (rc != 0) {8068			pr_err("error %d\n", rc);8069			goto rw_error;8070		}8071		rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);8072		if (rc != 0) {8073			pr_err("error %d\n", rc);8074			goto rw_error;8075		}8076		rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);8077		if (rc != 0) {8078			pr_err("error %d\n", rc);8079			goto rw_error;8080		}8081		rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);8082		if (rc != 0) {8083			pr_err("error %d\n", rc);8084			goto rw_error;8085		}8086		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);8087		if (rc != 0) {8088			pr_err("error %d\n", rc);8089			goto rw_error;8090		}8091 8092		cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |8093		    SCU_RAM_COMMAND_CMD_DEMOD_RESET;8094		cmd_scu.parameter_len = 0;8095		cmd_scu.result_len = 1;8096		cmd_scu.parameter = NULL;8097		cmd_scu.result = &cmd_result;8098		rc = scu_command(dev_addr, &cmd_scu);8099		if (rc != 0) {8100			pr_err("error %d\n", rc);8101			goto rw_error;8102		}8103	}8104 8105	if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {8106		/*8107		   STEP 2: configure demodulator8108		   -set env8109		   -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )8110		 */8111		cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |8112		    SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;8113		cmd_scu.parameter_len = 1;8114		cmd_scu.result_len = 1;8115		cmd_scu.parameter = &set_env_parameters;8116		cmd_scu.result = &cmd_result;8117		rc = scu_command(dev_addr, &cmd_scu);8118		if (rc != 0) {8119			pr_err("error %d\n", rc);8120			goto rw_error;8121		}8122 8123		cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |8124		    SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;8125		cmd_scu.parameter_len = 2;8126		cmd_scu.result_len = 1;8127		cmd_scu.parameter = set_param_parameters;8128		cmd_scu.result = &cmd_result;8129		rc = scu_command(dev_addr, &cmd_scu);8130		if (rc != 0) {8131			pr_err("error %d\n", rc);8132			goto rw_error;8133		}8134		/* set symbol rate */8135		rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);8136		if (rc != 0) {8137			pr_err("error %d\n", rc);8138			goto rw_error;8139		}8140		ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;8141		rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);8142		if (rc != 0) {8143			pr_err("error %d\n", rc);8144			goto rw_error;8145		}8146	}8147	/* STEP 3: enable the system in a mode where the ADC provides valid signal8148	   setup constellation independent registers */8149	/* from qam_cmd.py script (qam_driver_b) */8150	/* TODO: remove re-writes of HW reset values */8151	if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {8152		rc = set_frequency(demod, channel, tuner_freq_offset);8153		if (rc != 0) {8154			pr_err("error %d\n", rc);8155			goto rw_error;8156		}8157	}8158 8159	if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {8160 8161		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);8162		if (rc != 0) {8163			pr_err("error %d\n", rc);8164			goto rw_error;8165		}8166		rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);8167		if (rc != 0) {8168			pr_err("error %d\n", rc);8169			goto rw_error;8170		}8171	}8172 8173	if (op & QAM_SET_OP_ALL) {8174		if (!ext_attr->has_lna) {8175			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);8176			if (rc != 0) {8177				pr_err("error %d\n", rc);8178				goto rw_error;8179			}8180		}8181		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);8182		if (rc != 0) {8183			pr_err("error %d\n", rc);8184			goto rw_error;8185		}8186		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);8187		if (rc != 0) {8188			pr_err("error %d\n", rc);8189			goto rw_error;8190		}8191		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);8192		if (rc != 0) {8193			pr_err("error %d\n", rc);8194			goto rw_error;8195		}8196 8197		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);8198		if (rc != 0) {8199			pr_err("error %d\n", rc);8200			goto rw_error;8201		}	/* scu temporary shut down agc */8202 8203		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);8204		if (rc != 0) {8205			pr_err("error %d\n", rc);8206			goto rw_error;8207		}8208		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);8209		if (rc != 0) {8210			pr_err("error %d\n", rc);8211			goto rw_error;8212		}8213		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);8214		if (rc != 0) {8215			pr_err("error %d\n", rc);8216			goto rw_error;8217		}8218		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);8219		if (rc != 0) {8220			pr_err("error %d\n", rc);8221			goto rw_error;8222		}8223		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);8224		if (rc != 0) {8225			pr_err("error %d\n", rc);8226			goto rw_error;8227		}8228		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);8229		if (rc != 0) {8230			pr_err("error %d\n", rc);8231			goto rw_error;8232		}8233		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);8234		if (rc != 0) {8235			pr_err("error %d\n", rc);8236			goto rw_error;8237		}8238 8239		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);8240		if (rc != 0) {8241			pr_err("error %d\n", rc);8242			goto rw_error;8243		}8244		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);8245		if (rc != 0) {8246			pr_err("error %d\n", rc);8247			goto rw_error;8248		}	/*! reset default val ! */8249 8250		rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);8251		if (rc != 0) {8252			pr_err("error %d\n", rc);8253			goto rw_error;8254		}	/*! reset default val ! */8255		if (ext_attr->standard == DRX_STANDARD_ITU_B) {8256			rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);8257			if (rc != 0) {8258				pr_err("error %d\n", rc);8259				goto rw_error;8260			}	/*! reset default val ! */8261			rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);8262			if (rc != 0) {8263				pr_err("error %d\n", rc);8264				goto rw_error;8265			}	/*! reset default val ! */8266			rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);8267			if (rc != 0) {8268				pr_err("error %d\n", rc);8269				goto rw_error;8270			}	/*! reset default val ! */8271		} else {8272			switch (channel->constellation) {8273			case DRX_CONSTELLATION_QAM16:8274			case DRX_CONSTELLATION_QAM64:8275			case DRX_CONSTELLATION_QAM256:8276				rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);8277				if (rc != 0) {8278					pr_err("error %d\n", rc);8279					goto rw_error;8280				}8281				rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);8282				if (rc != 0) {8283					pr_err("error %d\n", rc);8284					goto rw_error;8285				}8286				rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);8287				if (rc != 0) {8288					pr_err("error %d\n", rc);8289					goto rw_error;8290				}	/*! reset default val ! */8291				break;8292			case DRX_CONSTELLATION_QAM32:8293			case DRX_CONSTELLATION_QAM128:8294				rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);8295				if (rc != 0) {8296					pr_err("error %d\n", rc);8297					goto rw_error;8298				}8299				rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);8300				if (rc != 0) {8301					pr_err("error %d\n", rc);8302					goto rw_error;8303				}8304				rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);8305				if (rc != 0) {8306					pr_err("error %d\n", rc);8307					goto rw_error;8308				}8309				break;8310			default:8311				return -EIO;8312			}	/* switch */8313		}8314 8315		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);8316		if (rc != 0) {8317			pr_err("error %d\n", rc);8318			goto rw_error;8319		}	/*! reset default val ! */8320		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);8321		if (rc != 0) {8322			pr_err("error %d\n", rc);8323			goto rw_error;8324		}8325		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);8326		if (rc != 0) {8327			pr_err("error %d\n", rc);8328			goto rw_error;8329		}8330		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);8331		if (rc != 0) {8332			pr_err("error %d\n", rc);8333			goto rw_error;8334		}8335		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);8336		if (rc != 0) {8337			pr_err("error %d\n", rc);8338			goto rw_error;8339		}8340		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);8341		if (rc != 0) {8342			pr_err("error %d\n", rc);8343			goto rw_error;8344		}8345		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);8346		if (rc != 0) {8347			pr_err("error %d\n", rc);8348			goto rw_error;8349		}8350		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);8351		if (rc != 0) {8352			pr_err("error %d\n", rc);8353			goto rw_error;8354		}8355		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);8356		if (rc != 0) {8357			pr_err("error %d\n", rc);8358			goto rw_error;8359		}8360		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);8361		if (rc != 0) {8362			pr_err("error %d\n", rc);8363			goto rw_error;8364		}8365		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);8366		if (rc != 0) {8367			pr_err("error %d\n", rc);8368			goto rw_error;8369		}8370		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);8371		if (rc != 0) {8372			pr_err("error %d\n", rc);8373			goto rw_error;8374		}8375		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);8376		if (rc != 0) {8377			pr_err("error %d\n", rc);8378			goto rw_error;8379		}8380		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);8381		if (rc != 0) {8382			pr_err("error %d\n", rc);8383			goto rw_error;8384		}8385		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);8386		if (rc != 0) {8387			pr_err("error %d\n", rc);8388			goto rw_error;8389		}8390		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);8391		if (rc != 0) {8392			pr_err("error %d\n", rc);8393			goto rw_error;8394		}8395		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);8396		if (rc != 0) {8397			pr_err("error %d\n", rc);8398			goto rw_error;8399		}8400		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);8401		if (rc != 0) {8402			pr_err("error %d\n", rc);8403			goto rw_error;8404		}8405		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);8406		if (rc != 0) {8407			pr_err("error %d\n", rc);8408			goto rw_error;8409		}8410		rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);8411		if (rc != 0) {8412			pr_err("error %d\n", rc);8413			goto rw_error;8414		}8415 8416		rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);8417		if (rc != 0) {8418			pr_err("error %d\n", rc);8419			goto rw_error;8420		}8421		rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);8422		if (rc != 0) {8423			pr_err("error %d\n", rc);8424			goto rw_error;8425		}8426		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);8427		if (rc != 0) {8428			pr_err("error %d\n", rc);8429			goto rw_error;8430		}8431		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);8432		if (rc != 0) {8433			pr_err("error %d\n", rc);8434			goto rw_error;8435		}8436		rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);8437		if (rc != 0) {8438			pr_err("error %d\n", rc);8439			goto rw_error;8440		}8441 8442		/* No more resets of the IQM, current standard correctly set =>8443		   now AGCs can be configured. */8444		/* turn on IQMAF. It has to be in front of setAgc**() */8445		rc = set_iqm_af(demod, true);8446		if (rc != 0) {8447			pr_err("error %d\n", rc);8448			goto rw_error;8449		}8450		rc = adc_synchronization(demod);8451		if (rc != 0) {8452			pr_err("error %d\n", rc);8453			goto rw_error;8454		}8455 8456		rc = init_agc(demod);8457		if (rc != 0) {8458			pr_err("error %d\n", rc);8459			goto rw_error;8460		}8461		rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);8462		if (rc != 0) {8463			pr_err("error %d\n", rc);8464			goto rw_error;8465		}8466		rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);8467		if (rc != 0) {8468			pr_err("error %d\n", rc);8469			goto rw_error;8470		}8471		{8472			/* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead8473			   of only the gain */8474			struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };8475 8476			qam_pga_cfg.gain = ext_attr->qam_pga_cfg;8477			rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);8478			if (rc != 0) {8479				pr_err("error %d\n", rc);8480				goto rw_error;8481			}8482		}8483		rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));8484		if (rc != 0) {8485			pr_err("error %d\n", rc);8486			goto rw_error;8487		}8488	}8489 8490	if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {8491		if (ext_attr->standard == DRX_STANDARD_ITU_A) {8492			rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);8493			if (rc != 0) {8494				pr_err("error %d\n", rc);8495				goto rw_error;8496			}8497			rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);8498			if (rc != 0) {8499				pr_err("error %d\n", rc);8500				goto rw_error;8501			}8502		} else if (ext_attr->standard == DRX_STANDARD_ITU_B) {8503			switch (channel->constellation) {8504			case DRX_CONSTELLATION_QAM64:8505				rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);8506				if (rc != 0) {8507					pr_err("error %d\n", rc);8508					goto rw_error;8509				}8510				rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);8511				if (rc != 0) {8512					pr_err("error %d\n", rc);8513					goto rw_error;8514				}8515				break;8516			case DRX_CONSTELLATION_QAM256:8517				rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);8518				if (rc != 0) {8519					pr_err("error %d\n", rc);8520					goto rw_error;8521				}8522				rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);8523				if (rc != 0) {8524					pr_err("error %d\n", rc);8525					goto rw_error;8526				}8527				break;8528			default:8529				return -EIO;8530			}8531		} else if (ext_attr->standard == DRX_STANDARD_ITU_C) {8532			rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);8533			if (rc != 0) {8534				pr_err("error %d\n", rc);8535				goto rw_error;8536			}8537			rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);8538			if (rc != 0) {8539				pr_err("error %d\n", rc);8540				goto rw_error;8541			}8542		}8543 8544		/* SETP 4: constellation specific setup */8545		switch (channel->constellation) {8546		case DRX_CONSTELLATION_QAM16:8547			rc = set_qam16(demod);8548			if (rc != 0) {8549				pr_err("error %d\n", rc);8550				goto rw_error;8551			}8552			break;8553		case DRX_CONSTELLATION_QAM32:8554			rc = set_qam32(demod);8555			if (rc != 0) {8556				pr_err("error %d\n", rc);8557				goto rw_error;8558			}8559			break;8560		case DRX_CONSTELLATION_QAM64:8561			rc = set_qam64(demod);8562			if (rc != 0) {8563				pr_err("error %d\n", rc);8564				goto rw_error;8565			}8566			break;8567		case DRX_CONSTELLATION_QAM128:8568			rc = set_qam128(demod);8569			if (rc != 0) {8570				pr_err("error %d\n", rc);8571				goto rw_error;8572			}8573			break;8574		case DRX_CONSTELLATION_QAM256:8575			rc = set_qam256(demod);8576			if (rc != 0) {8577				pr_err("error %d\n", rc);8578				goto rw_error;8579			}8580			break;8581		default:8582			return -EIO;8583		}		/* switch */8584	}8585 8586	if ((op & QAM_SET_OP_ALL)) {8587		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);8588		if (rc != 0) {8589			pr_err("error %d\n", rc);8590			goto rw_error;8591		}8592 8593		/* Mpeg output has to be in front of FEC active */8594		rc = set_mpegtei_handling(demod);8595		if (rc != 0) {8596			pr_err("error %d\n", rc);8597			goto rw_error;8598		}8599		rc = bit_reverse_mpeg_output(demod);8600		if (rc != 0) {8601			pr_err("error %d\n", rc);8602			goto rw_error;8603		}8604		rc = set_mpeg_start_width(demod);8605		if (rc != 0) {8606			pr_err("error %d\n", rc);8607			goto rw_error;8608		}8609		{8610			/* TODO: move to set_standard after hardware reset value problem is solved */8611			/* Configure initial MPEG output */8612			struct drx_cfg_mpeg_output cfg_mpeg_output;8613 8614			memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));8615			cfg_mpeg_output.enable_mpeg_output = true;8616 8617			rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);8618			if (rc != 0) {8619				pr_err("error %d\n", rc);8620				goto rw_error;8621			}8622		}8623	}8624 8625	if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {8626 8627		/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */8628		cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |8629		    SCU_RAM_COMMAND_CMD_DEMOD_START;8630		cmd_scu.parameter_len = 0;8631		cmd_scu.result_len = 1;8632		cmd_scu.parameter = NULL;8633		cmd_scu.result = &cmd_result;8634		rc = scu_command(dev_addr, &cmd_scu);8635		if (rc != 0) {8636			pr_err("error %d\n", rc);8637			goto rw_error;8638		}8639	}8640 8641	rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);8642	if (rc != 0) {8643		pr_err("error %d\n", rc);8644		goto rw_error;8645	}8646	rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);8647	if (rc != 0) {8648		pr_err("error %d\n", rc);8649		goto rw_error;8650	}8651	rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);8652	if (rc != 0) {8653		pr_err("error %d\n", rc);8654		goto rw_error;8655	}8656 8657	return 0;8658rw_error:8659	return rc;8660}8661 8662/*============================================================================*/8663static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);8664 8665static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)8666{8667	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;8668	struct drxj_data *ext_attr = demod->my_ext_attr;8669	int rc;8670	u32 iqm_fs_rate_ofs = 0;8671	u32 iqm_fs_rate_lo = 0;8672	u16 qam_ctl_ena = 0;8673	u16 data = 0;8674	u16 equ_mode = 0;8675	u16 fsm_state = 0;8676	int i = 0;8677	int ofsofs = 0;8678 8679	/* Silence the controlling of lc, equ, and the acquisition state machine */8680	rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);8681	if (rc != 0) {8682		pr_err("error %d\n", rc);8683		goto rw_error;8684	}8685	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);8686	if (rc != 0) {8687		pr_err("error %d\n", rc);8688		goto rw_error;8689	}8690 8691	/* freeze the frequency control loop */8692	rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);8693	if (rc != 0) {8694		pr_err("error %d\n", rc);8695		goto rw_error;8696	}8697	rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);8698	if (rc != 0) {8699		pr_err("error %d\n", rc);8700		goto rw_error;8701	}8702 8703	rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);8704	if (rc != 0) {8705		pr_err("error %d\n", rc);8706		goto rw_error;8707	}8708	rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);8709	if (rc != 0) {8710		pr_err("error %d\n", rc);8711		goto rw_error;8712	}8713	ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;8714	iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;8715	iqm_fs_rate_ofs -= 2 * ofsofs;8716 8717	/* freeze dq/fq updating */8718	rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);8719	if (rc != 0) {8720		pr_err("error %d\n", rc);8721		goto rw_error;8722	}8723	data = (data & 0xfff9);8724	rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);8725	if (rc != 0) {8726		pr_err("error %d\n", rc);8727		goto rw_error;8728	}8729	rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);8730	if (rc != 0) {8731		pr_err("error %d\n", rc);8732		goto rw_error;8733	}8734 8735	/* lc_cp / _ci / _ca */8736	rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);8737	if (rc != 0) {8738		pr_err("error %d\n", rc);8739		goto rw_error;8740	}8741	rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);8742	if (rc != 0) {8743		pr_err("error %d\n", rc);8744		goto rw_error;8745	}8746	rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);8747	if (rc != 0) {8748		pr_err("error %d\n", rc);8749		goto rw_error;8750	}8751 8752	/* flip the spec */8753	rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);8754	if (rc != 0) {8755		pr_err("error %d\n", rc);8756		goto rw_error;8757	}8758	ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;8759	ext_attr->pos_image = !ext_attr->pos_image;8760 8761	/* freeze dq/fq updating */8762	rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);8763	if (rc != 0) {8764		pr_err("error %d\n", rc);8765		goto rw_error;8766	}8767	equ_mode = data;8768	data = (data & 0xfff9);8769	rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);8770	if (rc != 0) {8771		pr_err("error %d\n", rc);8772		goto rw_error;8773	}8774	rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);8775	if (rc != 0) {8776		pr_err("error %d\n", rc);8777		goto rw_error;8778	}8779 8780	for (i = 0; i < 28; i++) {8781		rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);8782		if (rc != 0) {8783			pr_err("error %d\n", rc);8784			goto rw_error;8785		}8786		rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);8787		if (rc != 0) {8788			pr_err("error %d\n", rc);8789			goto rw_error;8790		}8791	}8792 8793	for (i = 0; i < 24; i++) {8794		rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_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		rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);8800		if (rc != 0) {8801			pr_err("error %d\n", rc);8802			goto rw_error;8803		}8804	}8805 8806	data = equ_mode;8807	rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);8808	if (rc != 0) {8809		pr_err("error %d\n", rc);8810		goto rw_error;8811	}8812	rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);8813	if (rc != 0) {8814		pr_err("error %d\n", rc);8815		goto rw_error;8816	}8817 8818	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);8819	if (rc != 0) {8820		pr_err("error %d\n", rc);8821		goto rw_error;8822	}8823 8824	i = 0;8825	while ((fsm_state != 4) && (i++ < 100)) {8826		rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);8827		if (rc != 0) {8828			pr_err("error %d\n", rc);8829			goto rw_error;8830		}8831	}8832	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);8833	if (rc != 0) {8834		pr_err("error %d\n", rc);8835		goto rw_error;8836	}8837 8838	return 0;8839rw_error:8840	return rc;8841 8842}8843 8844#define  NO_LOCK        0x08845#define  DEMOD_LOCKED   0x18846#define  SYNC_FLIPPED   0x28847#define  SPEC_MIRRORED  0x48848/*8849* \fn int qam64auto ()8850* \brief auto do sync pattern switching and mirroring.8851* \param demod:   instance of demod.8852* \param channel: pointer to channel data.8853* \param tuner_freq_offset: tuner frequency offset.8854* \param lock_status: pointer to lock status.8855* \return int.8856*/8857static int8858qam64auto(struct drx_demod_instance *demod,8859	  struct drx_channel *channel,8860	  s32 tuner_freq_offset, enum drx_lock_status *lock_status)8861{8862	struct drxj_data *ext_attr = demod->my_ext_attr;8863	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;8864	struct drx39xxj_state *state = dev_addr->user_data;8865	struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;8866	int rc;8867	u32 lck_state = NO_LOCK;8868	u32 start_time = 0;8869	u32 d_locked_time = 0;8870	u32 timeout_ofs = 0;8871	u16 data = 0;8872 8873	/* external attributes for storing acquired channel constellation */8874	*lock_status = DRX_NOT_LOCKED;8875	start_time = jiffies_to_msecs(jiffies);8876	lck_state = NO_LOCK;8877	do {8878		rc = ctrl_lock_status(demod, lock_status);8879		if (rc != 0) {8880			pr_err("error %d\n", rc);8881			goto rw_error;8882		}8883 8884		switch (lck_state) {8885		case NO_LOCK:8886			if (*lock_status == DRXJ_DEMOD_LOCK) {8887				rc = ctrl_get_qam_sig_quality(demod);8888				if (rc != 0) {8889					pr_err("error %d\n", rc);8890					goto rw_error;8891				}8892				if (p->cnr.stat[0].svalue > 20800) {8893					lck_state = DEMOD_LOCKED;8894					/* some delay to see if fec_lock possible TODO find the right value */8895					timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;	/* see something, waiting longer */8896					d_locked_time = jiffies_to_msecs(jiffies);8897				}8898			}8899			break;8900		case DEMOD_LOCKED:8901			if ((*lock_status == DRXJ_DEMOD_LOCK) &&	/* still demod_lock in 150ms */8902			    ((jiffies_to_msecs(jiffies) - d_locked_time) >8903			     DRXJ_QAM_FEC_LOCK_WAITTIME)) {8904				rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);8905				if (rc != 0) {8906					pr_err("error %d\n", rc);8907					goto rw_error;8908				}8909				rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);8910				if (rc != 0) {8911					pr_err("error %d\n", rc);8912					goto rw_error;8913				}8914				lck_state = SYNC_FLIPPED;8915				msleep(10);8916			}8917			break;8918		case SYNC_FLIPPED:8919			if (*lock_status == DRXJ_DEMOD_LOCK) {8920				if (channel->mirror == DRX_MIRROR_AUTO) {8921					/* flip sync pattern back */8922					rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);8923					if (rc != 0) {8924						pr_err("error %d\n", rc);8925						goto rw_error;8926					}8927					rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);8928					if (rc != 0) {8929						pr_err("error %d\n", rc);8930						goto rw_error;8931					}8932					/* flip spectrum */8933					ext_attr->mirror = DRX_MIRROR_YES;8934					rc = qam_flip_spec(demod, channel);8935					if (rc != 0) {8936						pr_err("error %d\n", rc);8937						goto rw_error;8938					}8939					lck_state = SPEC_MIRRORED;8940					/* reset timer TODO: still need 500ms? */8941					start_time = d_locked_time =8942					    jiffies_to_msecs(jiffies);8943					timeout_ofs = 0;8944				} else {	/* no need to wait lock */8945 8946					start_time =8947					    jiffies_to_msecs(jiffies) -8948					    DRXJ_QAM_MAX_WAITTIME - timeout_ofs;8949				}8950			}8951			break;8952		case SPEC_MIRRORED:8953			if ((*lock_status == DRXJ_DEMOD_LOCK) &&	/* still demod_lock in 150ms */8954			    ((jiffies_to_msecs(jiffies) - d_locked_time) >8955			     DRXJ_QAM_FEC_LOCK_WAITTIME)) {8956				rc = ctrl_get_qam_sig_quality(demod);8957				if (rc != 0) {8958					pr_err("error %d\n", rc);8959					goto rw_error;8960				}8961				if (p->cnr.stat[0].svalue > 20800) {8962					rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);8963					if (rc != 0) {8964						pr_err("error %d\n", rc);8965						goto rw_error;8966					}8967					rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);8968					if (rc != 0) {8969						pr_err("error %d\n", rc);8970						goto rw_error;8971					}8972					/* no need to wait lock */8973					start_time =8974					    jiffies_to_msecs(jiffies) -8975					    DRXJ_QAM_MAX_WAITTIME - timeout_ofs;8976				}8977			}8978			break;8979		default:8980			break;8981		}8982		msleep(10);8983	} while8984	    ((*lock_status != DRX_LOCKED) &&8985	     (*lock_status != DRX_NEVER_LOCK) &&8986	     ((jiffies_to_msecs(jiffies) - start_time) <8987	      (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))8988	    );8989	/* Returning control to application ... */8990 8991	return 0;8992rw_error:8993	return rc;8994}8995 8996/*8997* \fn int qam256auto ()8998* \brief auto do sync pattern switching and mirroring.8999* \param demod:   instance of demod.9000* \param channel: pointer to channel data.9001* \param tuner_freq_offset: tuner frequency offset.9002* \param lock_status: pointer to lock status.9003* \return int.9004*/9005static int9006qam256auto(struct drx_demod_instance *demod,9007	   struct drx_channel *channel,9008	   s32 tuner_freq_offset, enum drx_lock_status *lock_status)9009{9010	struct drxj_data *ext_attr = demod->my_ext_attr;9011	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;9012	struct drx39xxj_state *state = dev_addr->user_data;9013	struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;9014	int rc;9015	u32 lck_state = NO_LOCK;9016	u32 start_time = 0;9017	u32 d_locked_time = 0;9018	u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;9019 9020	/* external attributes for storing acquired channel constellation */9021	*lock_status = DRX_NOT_LOCKED;9022	start_time = jiffies_to_msecs(jiffies);9023	lck_state = NO_LOCK;9024	do {9025		rc = ctrl_lock_status(demod, lock_status);9026		if (rc != 0) {9027			pr_err("error %d\n", rc);9028			goto rw_error;9029		}9030		switch (lck_state) {9031		case NO_LOCK:9032			if (*lock_status == DRXJ_DEMOD_LOCK) {9033				rc = ctrl_get_qam_sig_quality(demod);9034				if (rc != 0) {9035					pr_err("error %d\n", rc);9036					goto rw_error;9037				}9038				if (p->cnr.stat[0].svalue > 26800) {9039					lck_state = DEMOD_LOCKED;9040					timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;	/* see something, wait longer */9041					d_locked_time = jiffies_to_msecs(jiffies);9042				}9043			}9044			break;9045		case DEMOD_LOCKED:9046			if (*lock_status == DRXJ_DEMOD_LOCK) {9047				if ((channel->mirror == DRX_MIRROR_AUTO) &&9048				    ((jiffies_to_msecs(jiffies) - d_locked_time) >9049				     DRXJ_QAM_FEC_LOCK_WAITTIME)) {9050					ext_attr->mirror = DRX_MIRROR_YES;9051					rc = qam_flip_spec(demod, channel);9052					if (rc != 0) {9053						pr_err("error %d\n", rc);9054						goto rw_error;9055					}9056					lck_state = SPEC_MIRRORED;9057					/* reset timer TODO: still need 300ms? */9058					start_time = jiffies_to_msecs(jiffies);9059					timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;9060				}9061			}9062			break;9063		case SPEC_MIRRORED:9064			break;9065		default:9066			break;9067		}9068		msleep(10);9069	} while9070	    ((*lock_status < DRX_LOCKED) &&9071	     (*lock_status != DRX_NEVER_LOCK) &&9072	     ((jiffies_to_msecs(jiffies) - start_time) <9073	      (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));9074 9075	return 0;9076rw_error:9077	return rc;9078}9079 9080/*9081* \fn int set_qam_channel ()9082* \brief Set QAM channel according to the requested constellation.9083* \param demod:   instance of demod.9084* \param channel: pointer to channel data.9085* \return int.9086*/9087static int9088set_qam_channel(struct drx_demod_instance *demod,9089	       struct drx_channel *channel, s32 tuner_freq_offset)9090{9091	struct drxj_data *ext_attr = NULL;9092	int rc;9093	enum drx_lock_status lock_status = DRX_NOT_LOCKED;9094	bool auto_flag = false;9095 9096	/* external attributes for storing acquired channel constellation */9097	ext_attr = (struct drxj_data *) demod->my_ext_attr;9098 9099	/* set QAM channel constellation */9100	switch (channel->constellation) {9101	case DRX_CONSTELLATION_QAM16:9102	case DRX_CONSTELLATION_QAM32:9103	case DRX_CONSTELLATION_QAM128:9104		return -EINVAL;9105	case DRX_CONSTELLATION_QAM64:9106	case DRX_CONSTELLATION_QAM256:9107		if (ext_attr->standard != DRX_STANDARD_ITU_B)9108			return -EINVAL;9109 9110		ext_attr->constellation = channel->constellation;9111		if (channel->mirror == DRX_MIRROR_AUTO)9112			ext_attr->mirror = DRX_MIRROR_NO;9113		else9114			ext_attr->mirror = channel->mirror;9115 9116		rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);9117		if (rc != 0) {9118			pr_err("error %d\n", rc);9119			goto rw_error;9120		}9121 9122		if (channel->constellation == DRX_CONSTELLATION_QAM64)9123			rc = qam64auto(demod, channel, tuner_freq_offset,9124				       &lock_status);9125		else9126			rc = qam256auto(demod, channel, tuner_freq_offset,9127					&lock_status);9128		if (rc != 0) {9129			pr_err("error %d\n", rc);9130			goto rw_error;9131		}9132		break;9133	case DRX_CONSTELLATION_AUTO:	/* for channel scan */9134		if (ext_attr->standard == DRX_STANDARD_ITU_B) {9135			u16 qam_ctl_ena = 0;9136 9137			auto_flag = true;9138 9139			/* try to lock default QAM constellation: QAM256 */9140			channel->constellation = DRX_CONSTELLATION_QAM256;9141			ext_attr->constellation = DRX_CONSTELLATION_QAM256;9142			if (channel->mirror == DRX_MIRROR_AUTO)9143				ext_attr->mirror = DRX_MIRROR_NO;9144			else9145				ext_attr->mirror = channel->mirror;9146			rc = set_qam(demod, channel, tuner_freq_offset,9147				     QAM_SET_OP_ALL);9148			if (rc != 0) {9149				pr_err("error %d\n", rc);9150				goto rw_error;9151			}9152			rc = qam256auto(demod, channel, tuner_freq_offset,9153					&lock_status);9154			if (rc != 0) {9155				pr_err("error %d\n", rc);9156				goto rw_error;9157			}9158 9159			if (lock_status >= DRX_LOCKED) {9160				channel->constellation = DRX_CONSTELLATION_AUTO;9161				break;9162			}9163 9164			/* QAM254 not locked. Try QAM64 constellation */9165			channel->constellation = DRX_CONSTELLATION_QAM64;9166			ext_attr->constellation = DRX_CONSTELLATION_QAM64;9167			if (channel->mirror == DRX_MIRROR_AUTO)9168				ext_attr->mirror = DRX_MIRROR_NO;9169			else9170				ext_attr->mirror = channel->mirror;9171 9172			rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,9173						     SCU_RAM_QAM_CTL_ENA__A,9174						     &qam_ctl_ena, 0);9175			if (rc != 0) {9176				pr_err("error %d\n", rc);9177				goto rw_error;9178			}9179			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,9180						      SCU_RAM_QAM_CTL_ENA__A,9181						      qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);9182			if (rc != 0) {9183				pr_err("error %d\n", rc);9184				goto rw_error;9185			}9186			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,9187						      SCU_RAM_QAM_FSM_STATE_TGT__A,9188						      0x2, 0);9189			if (rc != 0) {9190				pr_err("error %d\n", rc);9191				goto rw_error;9192			}	/* force to rate hunting */9193 9194			rc = set_qam(demod, channel, tuner_freq_offset,9195				     QAM_SET_OP_CONSTELLATION);9196			if (rc != 0) {9197				pr_err("error %d\n", rc);9198				goto rw_error;9199			}9200			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,9201						      SCU_RAM_QAM_CTL_ENA__A,9202						      qam_ctl_ena, 0);9203			if (rc != 0) {9204				pr_err("error %d\n", rc);9205				goto rw_error;9206			}9207 9208			rc = qam64auto(demod, channel, tuner_freq_offset,9209				       &lock_status);9210			if (rc != 0) {9211				pr_err("error %d\n", rc);9212				goto rw_error;9213			}9214 9215			channel->constellation = DRX_CONSTELLATION_AUTO;9216		} else if (ext_attr->standard == DRX_STANDARD_ITU_C) {9217			u16 qam_ctl_ena = 0;9218 9219			channel->constellation = DRX_CONSTELLATION_QAM64;9220			ext_attr->constellation = DRX_CONSTELLATION_QAM64;9221			auto_flag = true;9222 9223			if (channel->mirror == DRX_MIRROR_AUTO)9224				ext_attr->mirror = DRX_MIRROR_NO;9225			else9226				ext_attr->mirror = channel->mirror;9227			rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,9228						     SCU_RAM_QAM_CTL_ENA__A,9229						     &qam_ctl_ena, 0);9230			if (rc != 0) {9231				pr_err("error %d\n", rc);9232				goto rw_error;9233			}9234			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,9235						      SCU_RAM_QAM_CTL_ENA__A,9236						      qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);9237			if (rc != 0) {9238				pr_err("error %d\n", rc);9239				goto rw_error;9240			}9241			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,9242						      SCU_RAM_QAM_FSM_STATE_TGT__A,9243						      0x2, 0);9244			if (rc != 0) {9245				pr_err("error %d\n", rc);9246				goto rw_error;9247			}	/* force to rate hunting */9248 9249			rc = set_qam(demod, channel, tuner_freq_offset,9250				     QAM_SET_OP_CONSTELLATION);9251			if (rc != 0) {9252				pr_err("error %d\n", rc);9253				goto rw_error;9254			}9255			rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,9256						      SCU_RAM_QAM_CTL_ENA__A,9257						      qam_ctl_ena, 0);9258			if (rc != 0) {9259				pr_err("error %d\n", rc);9260				goto rw_error;9261			}9262			rc = qam64auto(demod, channel, tuner_freq_offset,9263				       &lock_status);9264			if (rc != 0) {9265				pr_err("error %d\n", rc);9266				goto rw_error;9267			}9268			channel->constellation = DRX_CONSTELLATION_AUTO;9269		} else {9270			return -EINVAL;9271		}9272		break;9273	default:9274		return -EINVAL;9275	}9276 9277	return 0;9278rw_error:9279	/* restore starting value */9280	if (auto_flag)9281		channel->constellation = DRX_CONSTELLATION_AUTO;9282	return rc;9283}9284 9285/*============================================================================*/9286 9287/*9288* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)9289* \brief Get RS error count in QAM mode (used for post RS BER calculation)9290* \return Error code9291*9292* precondition: measurement period & measurement prescale must be set9293*9294*/9295static int9296get_qamrs_err_count(struct i2c_device_addr *dev_addr,9297		    struct drxjrs_errors *rs_errors)9298{9299	int rc;9300	u16 nr_bit_errors = 0,9301	    nr_symbol_errors = 0,9302	    nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;9303 9304	/* check arguments */9305	if (dev_addr == NULL)9306		return -EINVAL;9307 9308	/* all reported errors are received in the  */9309	/* most recently finished measurement period */9310	/*   no of pre RS bit errors */9311	rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);9312	if (rc != 0) {9313		pr_err("error %d\n", rc);9314		goto rw_error;9315	}9316	/*   no of symbol errors      */9317	rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);9318	if (rc != 0) {9319		pr_err("error %d\n", rc);9320		goto rw_error;9321	}9322	/*   no of packet errors      */9323	rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);9324	if (rc != 0) {9325		pr_err("error %d\n", rc);9326		goto rw_error;9327	}9328	/*   no of failures to decode */9329	rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);9330	if (rc != 0) {9331		pr_err("error %d\n", rc);9332		goto rw_error;9333	}9334	/*   no of post RS bit erros  */9335	rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);9336	if (rc != 0) {9337		pr_err("error %d\n", rc);9338		goto rw_error;9339	}9340	/* TODO: NOTE */9341	/* These register values are fetched in non-atomic fashion           */9342	/* It is possible that the read values contain unrelated information */9343 9344	rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;9345	rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;9346	rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;9347	rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;9348	rs_errors->nr_snc_par_fail_count =9349	    nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;9350 9351	return 0;9352rw_error:9353	return rc;9354}9355 9356/*============================================================================*/9357 9358/*9359 * \fn int get_sig_strength()9360 * \brief Retrieve signal strength for VSB and QAM.9361 * \param demod Pointer to demod instance9362 * \param u16-t Pointer to signal strength data; range 0, .. , 100.9363 * \return int.9364 * \retval 0 sig_strength contains valid data.9365 * \retval -EINVAL sig_strength is NULL.9366 * \retval -EIO Erroneous data, sig_strength contains invalid data.9367 */9368#define DRXJ_AGC_TOP    0x28009369#define DRXJ_AGC_SNS    0x16009370#define DRXJ_RFAGC_MAX  0x3fff9371#define DRXJ_RFAGC_MIN  0x8009372 9373static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)9374{9375	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;9376	int rc;9377	u16 rf_gain = 0;9378	u16 if_gain = 0;9379	u16 if_agc_sns = 0;9380	u16 if_agc_top = 0;9381	u16 rf_agc_max = 0;9382	u16 rf_agc_min = 0;9383 9384	rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);9385	if (rc != 0) {9386		pr_err("error %d\n", rc);9387		goto rw_error;9388	}9389	if_gain &= IQM_AF_AGC_IF__M;9390	rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);9391	if (rc != 0) {9392		pr_err("error %d\n", rc);9393		goto rw_error;9394	}9395	rf_gain &= IQM_AF_AGC_RF__M;9396 9397	if_agc_sns = DRXJ_AGC_SNS;9398	if_agc_top = DRXJ_AGC_TOP;9399	rf_agc_max = DRXJ_RFAGC_MAX;9400	rf_agc_min = DRXJ_RFAGC_MIN;9401 9402	if (if_gain > if_agc_top) {9403		if (rf_gain > rf_agc_max)9404			*sig_strength = 100;9405		else if (rf_gain > rf_agc_min) {9406			if (rf_agc_max == rf_agc_min) {9407				pr_err("error: rf_agc_max == rf_agc_min\n");9408				return -EIO;9409			}9410			*sig_strength =9411			75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -9412								rf_agc_min);9413		} else9414			*sig_strength = 75;9415	} else if (if_gain > if_agc_sns) {9416		if (if_agc_top == if_agc_sns) {9417			pr_err("error: if_agc_top == if_agc_sns\n");9418			return -EIO;9419		}9420		*sig_strength =9421		20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);9422	} else {9423		if (!if_agc_sns) {9424			pr_err("error: if_agc_sns is zero!\n");9425			return -EIO;9426		}9427		*sig_strength = (20 * if_gain / if_agc_sns);9428	}9429 9430	if (*sig_strength <= 7)9431		*sig_strength = 0;9432 9433	return 0;9434rw_error:9435	return rc;9436}9437 9438/*9439* \fn int ctrl_get_qam_sig_quality()9440* \brief Retrieve QAM signal quality from device.9441* \param devmod Pointer to demodulator instance.9442* \param sig_quality Pointer to signal quality data.9443* \return int.9444* \retval 0 sig_quality contains valid data.9445* \retval -EINVAL sig_quality is NULL.9446* \retval -EIO Erroneous data, sig_quality contains invalid data.9447 9448*  Pre-condition: Device must be started and in lock.9449*/9450static int9451ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)9452{9453	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;9454	struct drxj_data *ext_attr = demod->my_ext_attr;9455	struct drx39xxj_state *state = dev_addr->user_data;9456	struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;9457	struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };9458	enum drx_modulation constellation = ext_attr->constellation;9459	int rc;9460 9461	u32 pre_bit_err_rs = 0;	/* pre RedSolomon Bit Error Rate */9462	u32 post_bit_err_rs = 0;	/* post RedSolomon Bit Error Rate */9463	u32 pkt_errs = 0;	/* no of packet errors in RS */9464	u16 qam_sl_err_power = 0;	/* accumulated error between raw and sliced symbols */9465	u16 qsym_err_vd = 0;	/* quadrature symbol errors in QAM_VD */9466	u16 fec_oc_period = 0;	/* SNC sync failure measurement period */9467	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */9468	u16 fec_rs_period = 0;	/* Value for corresponding I2C register */9469	/* calculation constants */9470	u32 rs_bit_cnt = 0;	/* RedSolomon Bit Count */9471	u32 qam_sl_sig_power = 0;	/* used for MER, depends of QAM constellation */9472	/* intermediate results */9473	u32 e = 0;		/* exponent value used for QAM BER/SER */9474	u32 m = 0;		/* mantisa value used for QAM BER/SER */9475	u32 ber_cnt = 0;	/* BER count */9476	/* signal quality info */9477	u32 qam_sl_mer = 0;	/* QAM MER */9478	u32 qam_pre_rs_ber = 0;	/* Pre RedSolomon BER */9479	u32 qam_post_rs_ber = 0;	/* Post RedSolomon BER */9480	u32 qam_vd_ser = 0;	/* ViterbiDecoder SER */9481	u16 qam_vd_prescale = 0;	/* Viterbi Measurement Prescale */9482	u16 qam_vd_period = 0;	/* Viterbi Measurement period */9483	u32 vd_bit_cnt = 0;	/* ViterbiDecoder Bit Count */9484 9485	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;9486 9487	/* read the physical registers */9488	/*   Get the RS error data */9489	rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);9490	if (rc != 0) {9491		pr_err("error %d\n", rc);9492		goto rw_error;9493	}9494	/* get the register value needed for MER */9495	rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);9496	if (rc != 0) {9497		pr_err("error %d\n", rc);9498		goto rw_error;9499	}9500	/* get the register value needed for post RS BER */9501	rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);9502	if (rc != 0) {9503		pr_err("error %d\n", rc);9504		goto rw_error;9505	}9506 9507	/* get constants needed for signal quality calculation */9508	fec_rs_period = ext_attr->fec_rs_period;9509	fec_rs_prescale = ext_attr->fec_rs_prescale;9510	rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;9511	qam_vd_period = ext_attr->qam_vd_period;9512	qam_vd_prescale = ext_attr->qam_vd_prescale;9513	vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;9514 9515	/* DRXJ_QAM_SL_SIG_POWER_QAMxxx  * 4     */9516	switch (constellation) {9517	case DRX_CONSTELLATION_QAM16:9518		qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;9519		break;9520	case DRX_CONSTELLATION_QAM32:9521		qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;9522		break;9523	case DRX_CONSTELLATION_QAM64:9524		qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;9525		break;9526	case DRX_CONSTELLATION_QAM128:9527		qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;9528		break;9529	case DRX_CONSTELLATION_QAM256:9530		qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;9531		break;9532	default:9533		rc = -EIO;9534		goto rw_error;9535	}9536 9537	/* ------------------------------ */9538	/* MER Calculation                */9539	/* ------------------------------ */9540	/* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */9541 9542	/* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */9543	if (qam_sl_err_power == 0)9544		qam_sl_mer = 0;9545	else9546		qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);9547 9548	/* ----------------------------------------- */9549	/* Pre Viterbi Symbol Error Rate Calculation */9550	/* ----------------------------------------- */9551	/* pre viterbi SER is good if it is below 0.025 */9552 9553	/* get the register value */9554	/*   no of quadrature symbol errors */9555	rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);9556	if (rc != 0) {9557		pr_err("error %d\n", rc);9558		goto rw_error;9559	}9560	/* Extract the Exponent and the Mantisa  */9561	/* of number of quadrature symbol errors */9562	e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>9563	    QAM_VD_NR_QSYM_ERRORS_EXP__B;9564	m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>9565	    QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;9566 9567	if ((m << e) >> 3 > 549752)9568		qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;9569	else9570		qam_vd_ser = m << ((e > 2) ? (e - 3) : e);9571 9572	/* --------------------------------------- */9573	/* pre and post RedSolomon BER Calculation */9574	/* --------------------------------------- */9575	/* pre RS BER is good if it is below 3.5e-4 */9576 9577	/* get the register values */9578	pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;9579	pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;9580 9581	/* Extract the Exponent and the Mantisa of the */9582	/* pre Reed-Solomon bit error count            */9583	e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>9584	    FEC_RS_NR_BIT_ERRORS_EXP__B;9585	m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>9586	    FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;9587 9588	ber_cnt = m << e;9589 9590	/*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */9591	if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)9592		qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;9593	else9594		qam_pre_rs_ber = ber_cnt;9595 9596	/* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) /  */9597	/*               (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A)  */9598	/*9599	   => c = (1000000*100*11.17)/1504 =9600	   post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /9601	   (100 * FEC_OC_SNC_FAIL_PERIOD__A)9602	   *100 and /100 is for more precision.9603	   => (20 bits * 12 bits) /(16 bits * 7 bits)  => safe in 32 bits computation9604 9605	   Precision errors still possible.9606	 */9607	if (!fec_oc_period) {9608		qam_post_rs_ber = 0xFFFFFFFF;9609	} else {9610		e = post_bit_err_rs * 742686;9611		m = fec_oc_period * 100;9612		qam_post_rs_ber = e / m;9613	}9614 9615	/* fill signal quality data structure */9616	p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;9617	p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;9618	p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;9619	p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;9620	p->block_error.stat[0].scale = FE_SCALE_COUNTER;9621	p->cnr.stat[0].scale = FE_SCALE_DECIBEL;9622 9623	p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;9624	if (ext_attr->standard == DRX_STANDARD_ITU_B) {9625		p->pre_bit_error.stat[0].uvalue += qam_vd_ser;9626		p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;9627	} else {9628		p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;9629		p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;9630	}9631 9632	p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;9633	p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;9634 9635	p->block_error.stat[0].uvalue += pkt_errs;9636 9637#ifdef DRXJ_SIGNAL_ACCUM_ERR9638	rc = get_acc_pkt_err(demod, &sig_quality->packet_error);9639	if (rc != 0) {9640		pr_err("error %d\n", rc);9641		goto rw_error;9642	}9643#endif9644 9645	return 0;9646rw_error:9647	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;9648	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;9649	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;9650	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;9651	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;9652	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;9653 9654	return rc;9655}9656 9657#endif /* #ifndef DRXJ_VSB_ONLY */9658 9659/*============================================================================*/9660/*==                     END QAM DATAPATH FUNCTIONS                         ==*/9661/*============================================================================*/9662 9663/*============================================================================*/9664/*============================================================================*/9665/*==                       ATV DATAPATH FUNCTIONS                           ==*/9666/*============================================================================*/9667/*============================================================================*/9668 9669/*9670   Implementation notes.9671 9672   NTSC/FM AGCs9673 9674      Four AGCs are used for NTSC:9675      (1) RF (used to attenuate the input signal in case of to much power)9676      (2) IF (used to attenuate the input signal in case of to much power)9677      (3) Video AGC (used to amplify the output signal in case input to low)9678      (4) SIF AGC (used to amplify the output signal in case input to low)9679 9680      Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed9681      that the coupling between Video AGC and the RF and IF AGCs also works in9682      favor of the SIF AGC.9683 9684      Three AGCs are used for FM:9685      (1) RF (used to attenuate the input signal in case of to much power)9686      (2) IF (used to attenuate the input signal in case of to much power)9687      (3) SIF AGC (used to amplify the output signal in case input to low)9688 9689      The SIF AGC is now coupled to the RF/IF AGCs.9690      The SIF AGC is needed for both SIF output and the internal SIF signal to9691      the AUD block.9692 9693      RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of9694      the ATV block. The AGC control algorithms are all implemented in9695      microcode.9696 9697   ATV SETTINGS9698 9699      (Shadow settings will not be used for now, they will be implemented9700       later on because of the schedule)9701 9702      Several HW/SCU "settings" can be used for ATV. The standard selection9703      will reset most of these settings. To avoid that the end user application9704      has to perform these settings each time the ATV or FM standards is9705      selected the driver will shadow these settings. This enables the end user9706      to perform the settings only once after a drx_open(). The driver must9707      write the shadow settings to HW/SCU in case:9708	 ( setstandard FM/ATV) ||9709	 ( settings have changed && FM/ATV standard is active)9710      The shadow settings will be stored in the device specific data container.9711      A set of flags will be defined to flag changes in shadow settings.9712      A routine will be implemented to write all changed shadow settings to9713      HW/SCU.9714 9715      The "settings" will consist of: AGC settings, filter settings etc.9716 9717      Disadvantage of use of shadow settings:9718      Direct changes in HW/SCU registers will not be reflected in the9719      shadow settings and these changes will be overwritten during a next9720      update. This can happen during evaluation. This will not be a problem9721      for normal customer usage.9722*/9723/* -------------------------------------------------------------------------- */9724 9725/*9726* \fn int power_down_atv ()9727* \brief Power down ATV.9728* \param demod instance of demodulator9729* \param standard either NTSC or FM (sub strandard for ATV )9730* \return int.9731*9732*  Stops and thus resets ATV and IQM block9733*  SIF and CVBS ADC are powered down9734*  Calls audio power down9735*/9736static int9737power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)9738{9739	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;9740	struct drxjscu_cmd cmd_scu = { /* command      */ 0,9741		/* parameter_len */ 0,9742		/* result_len    */ 0,9743		/* *parameter   */ NULL,9744		/* *result      */ NULL9745	};9746	int rc;9747	u16 cmd_result = 0;9748 9749	/* ATV NTSC */9750 9751	/* Stop ATV SCU (will reset ATV and IQM hardware */9752	cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |9753	    SCU_RAM_COMMAND_CMD_DEMOD_STOP;9754	cmd_scu.parameter_len = 0;9755	cmd_scu.result_len = 1;9756	cmd_scu.parameter = NULL;9757	cmd_scu.result = &cmd_result;9758	rc = scu_command(dev_addr, &cmd_scu);9759	if (rc != 0) {9760		pr_err("error %d\n", rc);9761		goto rw_error;9762	}9763	/* Disable ATV outputs (ATV reset enables CVBS, undo this) */9764	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);9765	if (rc != 0) {9766		pr_err("error %d\n", rc);9767		goto rw_error;9768	}9769 9770	rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);9771	if (rc != 0) {9772		pr_err("error %d\n", rc);9773		goto rw_error;9774	}9775	if (primary) {9776		rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);9777		if (rc != 0) {9778			pr_err("error %d\n", rc);9779			goto rw_error;9780		}9781		rc = set_iqm_af(demod, false);9782		if (rc != 0) {9783			pr_err("error %d\n", rc);9784			goto rw_error;9785		}9786	} else {9787		rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);9788		if (rc != 0) {9789			pr_err("error %d\n", rc);9790			goto rw_error;9791		}9792		rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);9793		if (rc != 0) {9794			pr_err("error %d\n", rc);9795			goto rw_error;9796		}9797		rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);9798		if (rc != 0) {9799			pr_err("error %d\n", rc);9800			goto rw_error;9801		}9802		rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);9803		if (rc != 0) {9804			pr_err("error %d\n", rc);9805			goto rw_error;9806		}9807		rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);9808		if (rc != 0) {9809			pr_err("error %d\n", rc);9810			goto rw_error;9811		}9812	}9813	rc = power_down_aud(demod);9814	if (rc != 0) {9815		pr_err("error %d\n", rc);9816		goto rw_error;9817	}9818 9819	return 0;9820rw_error:9821	return rc;9822}9823 9824/*============================================================================*/9825 9826/*9827* \brief Power up AUD.9828* \param demod instance of demodulator9829* \return int.9830*9831*/9832static int power_down_aud(struct drx_demod_instance *demod)9833{9834	struct i2c_device_addr *dev_addr = NULL;9835	struct drxj_data *ext_attr = NULL;9836	int rc;9837 9838	dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;9839	ext_attr = (struct drxj_data *) demod->my_ext_attr;9840 9841	rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);9842	if (rc != 0) {9843		pr_err("error %d\n", rc);9844		goto rw_error;9845	}9846 9847	ext_attr->aud_data.audio_is_active = false;9848 9849	return 0;9850rw_error:9851	return rc;9852}9853 9854/*9855* \fn int set_orx_nsu_aox()9856* \brief Configure OrxNsuAox for OOB9857* \param demod instance of demodulator.9858* \param active9859* \return int.9860*/9861static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)9862{9863	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;9864	int rc;9865	u16 data = 0;9866 9867	/* Configure NSU_AOX */9868	rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);9869	if (rc != 0) {9870		pr_err("error %d\n", rc);9871		goto rw_error;9872	}9873	if (!active)9874		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));9875	else9876		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);9877	rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);9878	if (rc != 0) {9879		pr_err("error %d\n", rc);9880		goto rw_error;9881	}9882 9883	return 0;9884rw_error:9885	return rc;9886}9887 9888/*9889* \fn int ctrl_set_oob()9890* \brief Set OOB channel to be used.9891* \param demod instance of demodulator9892* \param oob_param OOB parameters for channel setting.9893* \frequency should be in KHz9894* \return int.9895*9896* Accepts  only. Returns error otherwise.9897* Demapper value is written after scu_command START9898* because START command causes COMM_EXEC transition9899* from 0 to 1 which causes all registers to be9900* overwritten with initial value9901*9902*/9903 9904/* Nyquist filter impulse response */9905#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 */9906#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 */9907#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) */9908 9909/* Coefficients for the nyquist filter (total: 27 taps) */9910#define NYQFILTERLEN 279911 9912static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)9913{9914	int rc;9915	s32 freq = 0;	/* KHz */9916	struct i2c_device_addr *dev_addr = NULL;9917	struct drxj_data *ext_attr = NULL;9918	u16 i = 0;9919	bool mirror_freq_spect_oob = false;9920	u16 trk_filter_value = 0;9921	struct drxjscu_cmd scu_cmd;9922	u16 set_param_parameters[3];9923	u16 cmd_result[2] = { 0, 0 };9924	s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {9925		IMPULSE_COSINE_ALPHA_0_3,	/* Target Mode 0 */9926		IMPULSE_COSINE_ALPHA_0_3,	/* Target Mode 1 */9927		IMPULSE_COSINE_ALPHA_0_5,	/* Target Mode 2 */9928		IMPULSE_COSINE_ALPHA_RO_0_5	/* Target Mode 3 */9929	};9930	u8 mode_val[4] = { 2, 2, 0, 1 };9931	u8 pfi_coeffs[4][6] = {9932		{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) */9933		{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) */9934		{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) */9935		{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) */9936	};9937	u16 mode_index;9938 9939	dev_addr = demod->my_i2c_dev_addr;9940	ext_attr = (struct drxj_data *) demod->my_ext_attr;9941	mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;9942 9943	/* Check parameters */9944	if (oob_param == NULL) {9945		/* power off oob module  */9946		scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB9947		    | SCU_RAM_COMMAND_CMD_DEMOD_STOP;9948		scu_cmd.parameter_len = 0;9949		scu_cmd.result_len = 1;9950		scu_cmd.result = cmd_result;9951		rc = scu_command(dev_addr, &scu_cmd);9952		if (rc != 0) {9953			pr_err("error %d\n", rc);9954			goto rw_error;9955		}9956		rc = set_orx_nsu_aox(demod, false);9957		if (rc != 0) {9958			pr_err("error %d\n", rc);9959			goto rw_error;9960		}9961		rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);9962		if (rc != 0) {9963			pr_err("error %d\n", rc);9964			goto rw_error;9965		}9966 9967		ext_attr->oob_power_on = false;9968		return 0;9969	}9970 9971	freq = oob_param->frequency;9972	if ((freq < 70000) || (freq > 130000))9973		return -EIO;9974	freq = (freq - 50000) / 50;9975 9976	{9977		u16 index = 0;9978		u16 remainder = 0;9979		u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;9980 9981		index = (u16) ((freq - 400) / 200);9982		remainder = (u16) ((freq - 400) % 200);9983		trk_filter_value =9984		    trk_filtercfg[index] - (trk_filtercfg[index] -9985					   trk_filtercfg[index +9986							1]) / 10 * remainder /9987		    20;9988	}9989 9990   /********/9991	/* Stop  */9992   /********/9993	rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);9994	if (rc != 0) {9995		pr_err("error %d\n", rc);9996		goto rw_error;9997	}9998	scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB9999	    | SCU_RAM_COMMAND_CMD_DEMOD_STOP;10000	scu_cmd.parameter_len = 0;10001	scu_cmd.result_len = 1;10002	scu_cmd.result = cmd_result;10003	rc = scu_command(dev_addr, &scu_cmd);10004	if (rc != 0) {10005		pr_err("error %d\n", rc);10006		goto rw_error;10007	}10008   /********/10009	/* Reset */10010   /********/10011	scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB10012	    | SCU_RAM_COMMAND_CMD_DEMOD_RESET;10013	scu_cmd.parameter_len = 0;10014	scu_cmd.result_len = 1;10015	scu_cmd.result = cmd_result;10016	rc = scu_command(dev_addr, &scu_cmd);10017	if (rc != 0) {10018		pr_err("error %d\n", rc);10019		goto rw_error;10020	}10021   /**********/10022	/* SET_ENV */10023   /**********/10024	/* set frequency, spectrum inversion and data rate */10025	scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB10026	    | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;10027	scu_cmd.parameter_len = 3;10028	/* 1-data rate;2-frequency */10029	switch (oob_param->standard) {10030	case DRX_OOB_MODE_A:10031		if (10032			   /* signal is transmitted inverted */10033			   ((oob_param->spectrum_inverted == true) &&10034			    /* and tuner is not mirroring the signal */10035			    (!mirror_freq_spect_oob)) |10036			   /* or */10037			   /* signal is transmitted noninverted */10038			   ((oob_param->spectrum_inverted == false) &&10039			    /* and tuner is mirroring the signal */10040			    (mirror_freq_spect_oob))10041		    )10042			set_param_parameters[0] =10043			    SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;10044		else10045			set_param_parameters[0] =10046			    SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;10047		break;10048	case DRX_OOB_MODE_B_GRADE_A:10049		if (10050			   /* signal is transmitted inverted */10051			   ((oob_param->spectrum_inverted == true) &&10052			    /* and tuner is not mirroring the signal */10053			    (!mirror_freq_spect_oob)) |10054			   /* or */10055			   /* signal is transmitted noninverted */10056			   ((oob_param->spectrum_inverted == false) &&10057			    /* and tuner is mirroring the signal */10058			    (mirror_freq_spect_oob))10059		    )10060			set_param_parameters[0] =10061			    SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;10062		else10063			set_param_parameters[0] =10064			    SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;10065		break;10066	case DRX_OOB_MODE_B_GRADE_B:10067	default:10068		if (10069			   /* signal is transmitted inverted */10070			   ((oob_param->spectrum_inverted == true) &&10071			    /* and tuner is not mirroring the signal */10072			    (!mirror_freq_spect_oob)) |10073			   /* or */10074			   /* signal is transmitted noninverted */10075			   ((oob_param->spectrum_inverted == false) &&10076			    /* and tuner is mirroring the signal */10077			    (mirror_freq_spect_oob))10078		    )10079			set_param_parameters[0] =10080			    SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;10081		else10082			set_param_parameters[0] =10083			    SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;10084		break;10085	}10086	set_param_parameters[1] = (u16) (freq & 0xFFFF);10087	set_param_parameters[2] = trk_filter_value;10088	scu_cmd.parameter = set_param_parameters;10089	scu_cmd.result_len = 1;10090	scu_cmd.result = cmd_result;10091	mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];10092	rc = scu_command(dev_addr, &scu_cmd);10093	if (rc != 0) {10094		pr_err("error %d\n", rc);10095		goto rw_error;10096	}10097 10098	rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);10099	if (rc != 0) {10100		pr_err("error %d\n", rc);10101		goto rw_error;10102	}	/*  Write magic word to enable pdr reg write  */10103	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);10104	if (rc != 0) {10105		pr_err("error %d\n", rc);10106		goto rw_error;10107	}10108	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);10109	if (rc != 0) {10110		pr_err("error %d\n", rc);10111		goto rw_error;10112	}10113	rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);10114	if (rc != 0) {10115		pr_err("error %d\n", rc);10116		goto rw_error;10117	}	/*  Write magic word to disable pdr reg write */10118 10119	rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);10120	if (rc != 0) {10121		pr_err("error %d\n", rc);10122		goto rw_error;10123	}10124	rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);10125	if (rc != 0) {10126		pr_err("error %d\n", rc);10127		goto rw_error;10128	}10129	rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);10130	if (rc != 0) {10131		pr_err("error %d\n", rc);10132		goto rw_error;10133	}10134 10135	/* ddc */10136	rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);10137	if (rc != 0) {10138		pr_err("error %d\n", rc);10139		goto rw_error;10140	}10141 10142	/* nsu */10143	rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);10144	if (rc != 0) {10145		pr_err("error %d\n", rc);10146		goto rw_error;10147	}10148 10149	/* initialization for target mode */10150	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);10151	if (rc != 0) {10152		pr_err("error %d\n", rc);10153		goto rw_error;10154	}10155	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);10156	if (rc != 0) {10157		pr_err("error %d\n", rc);10158		goto rw_error;10159	}10160 10161	/* Reset bits for timing and freq. recovery */10162	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);10163	if (rc != 0) {10164		pr_err("error %d\n", rc);10165		goto rw_error;10166	}10167	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);10168	if (rc != 0) {10169		pr_err("error %d\n", rc);10170		goto rw_error;10171	}10172	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);10173	if (rc != 0) {10174		pr_err("error %d\n", rc);10175		goto rw_error;10176	}10177	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);10178	if (rc != 0) {10179		pr_err("error %d\n", rc);10180		goto rw_error;10181	}10182 10183	/* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */10184	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);10185	if (rc != 0) {10186		pr_err("error %d\n", rc);10187		goto rw_error;10188	}10189	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);10190	if (rc != 0) {10191		pr_err("error %d\n", rc);10192		goto rw_error;10193	}10194	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);10195	if (rc != 0) {10196		pr_err("error %d\n", rc);10197		goto rw_error;10198	}10199	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);10200	if (rc != 0) {10201		pr_err("error %d\n", rc);10202		goto rw_error;10203	}10204	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);10205	if (rc != 0) {10206		pr_err("error %d\n", rc);10207		goto rw_error;10208	}10209 10210	/* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */10211	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);10212	if (rc != 0) {10213		pr_err("error %d\n", rc);10214		goto rw_error;10215	}10216	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);10217	if (rc != 0) {10218		pr_err("error %d\n", rc);10219		goto rw_error;10220	}10221	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);10222	if (rc != 0) {10223		pr_err("error %d\n", rc);10224		goto rw_error;10225	}10226	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);10227	if (rc != 0) {10228		pr_err("error %d\n", rc);10229		goto rw_error;10230	}10231	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);10232	if (rc != 0) {10233		pr_err("error %d\n", rc);10234		goto rw_error;10235	}10236 10237	/* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */10238	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);10239	if (rc != 0) {10240		pr_err("error %d\n", rc);10241		goto rw_error;10242	}10243	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);10244	if (rc != 0) {10245		pr_err("error %d\n", rc);10246		goto rw_error;10247	}10248	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);10249	if (rc != 0) {10250		pr_err("error %d\n", rc);10251		goto rw_error;10252	}10253	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);10254	if (rc != 0) {10255		pr_err("error %d\n", rc);10256		goto rw_error;10257	}10258	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);10259	if (rc != 0) {10260		pr_err("error %d\n", rc);10261		goto rw_error;10262	}10263 10264	/* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */10265	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);10266	if (rc != 0) {10267		pr_err("error %d\n", rc);10268		goto rw_error;10269	}10270	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);10271	if (rc != 0) {10272		pr_err("error %d\n", rc);10273		goto rw_error;10274	}10275	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);10276	if (rc != 0) {10277		pr_err("error %d\n", rc);10278		goto rw_error;10279	}10280	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);10281	if (rc != 0) {10282		pr_err("error %d\n", rc);10283		goto rw_error;10284	}10285	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);10286	if (rc != 0) {10287		pr_err("error %d\n", rc);10288		goto rw_error;10289	}10290 10291	/* TIM_LOCK = {300,      -2048, 8, -8, 0, 1<<4}; */10292	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);10293	if (rc != 0) {10294		pr_err("error %d\n", rc);10295		goto rw_error;10296	}10297	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);10298	if (rc != 0) {10299		pr_err("error %d\n", rc);10300		goto rw_error;10301	}10302	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);10303	if (rc != 0) {10304		pr_err("error %d\n", rc);10305		goto rw_error;10306	}10307	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);10308	if (rc != 0) {10309		pr_err("error %d\n", rc);10310		goto rw_error;10311	}10312	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);10313	if (rc != 0) {10314		pr_err("error %d\n", rc);10315		goto rw_error;10316	}10317 10318	/* EQU_LOCK = {20,      -2048, 8, -8, 0, 1<<5}; */10319	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);10320	if (rc != 0) {10321		pr_err("error %d\n", rc);10322		goto rw_error;10323	}10324	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);10325	if (rc != 0) {10326		pr_err("error %d\n", rc);10327		goto rw_error;10328	}10329	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);10330	if (rc != 0) {10331		pr_err("error %d\n", rc);10332		goto rw_error;10333	}10334	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);10335	if (rc != 0) {10336		pr_err("error %d\n", rc);10337		goto rw_error;10338	}10339	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);10340	if (rc != 0) {10341		pr_err("error %d\n", rc);10342		goto rw_error;10343	}10344 10345	/* PRE-Filter coefficients (PFI) */10346	rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);10347	if (rc != 0) {10348		pr_err("error %d\n", rc);10349		goto rw_error;10350	}10351	rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);10352	if (rc != 0) {10353		pr_err("error %d\n", rc);10354		goto rw_error;10355	}10356 10357	/* NYQUIST-Filter coefficients (NYQ) */10358	for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {10359		rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);10360		if (rc != 0) {10361			pr_err("error %d\n", rc);10362			goto rw_error;10363		}10364		rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);10365		if (rc != 0) {10366			pr_err("error %d\n", rc);10367			goto rw_error;10368		}10369	}10370	rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);10371	if (rc != 0) {10372		pr_err("error %d\n", rc);10373		goto rw_error;10374	}10375	rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);10376	if (rc != 0) {10377		pr_err("error %d\n", rc);10378		goto rw_error;10379	}10380	/********/10381	/* Start */10382	/********/10383	scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB10384	    | SCU_RAM_COMMAND_CMD_DEMOD_START;10385	scu_cmd.parameter_len = 0;10386	scu_cmd.result_len = 1;10387	scu_cmd.result = cmd_result;10388	rc = scu_command(dev_addr, &scu_cmd);10389	if (rc != 0) {10390		pr_err("error %d\n", rc);10391		goto rw_error;10392	}10393 10394	rc = set_orx_nsu_aox(demod, true);10395	if (rc != 0) {10396		pr_err("error %d\n", rc);10397		goto rw_error;10398	}10399	rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);10400	if (rc != 0) {10401		pr_err("error %d\n", rc);10402		goto rw_error;10403	}10404 10405	ext_attr->oob_power_on = true;10406 10407	return 0;10408rw_error:10409	return rc;10410}10411 10412/*============================================================================*/10413/*==                     END OOB DATAPATH FUNCTIONS                         ==*/10414/*============================================================================*/10415 10416/*=============================================================================10417  ===== MC command related functions ==========================================10418  ===========================================================================*/10419 10420/*=============================================================================10421  ===== ctrl_set_channel() ==========================================================10422  ===========================================================================*/10423/*10424* \fn int ctrl_set_channel()10425* \brief Select a new transmission channel.10426* \param demod instance of demod.10427* \param channel Pointer to channel data.10428* \return int.10429*10430* In case the tuner module is not used and in case of NTSC/FM the pogrammer10431* must tune the tuner to the centre frequency of the NTSC/FM channel.10432*10433*/10434static int10435ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)10436{10437	int rc;10438	s32 tuner_freq_offset = 0;10439	struct drxj_data *ext_attr = NULL;10440	struct i2c_device_addr *dev_addr = NULL;10441	enum drx_standard standard = DRX_STANDARD_UNKNOWN;10442#ifndef DRXJ_VSB_ONLY10443	u32 min_symbol_rate = 0;10444	u32 max_symbol_rate = 0;10445	int bandwidth_temp = 0;10446	int bandwidth = 0;10447#endif10448   /*== check arguments ======================================================*/10449	if ((demod == NULL) || (channel == NULL))10450		return -EINVAL;10451 10452	dev_addr = demod->my_i2c_dev_addr;10453	ext_attr = (struct drxj_data *) demod->my_ext_attr;10454	standard = ext_attr->standard;10455 10456	/* check valid standards */10457	switch (standard) {10458	case DRX_STANDARD_8VSB:10459#ifndef DRXJ_VSB_ONLY10460	case DRX_STANDARD_ITU_A:10461	case DRX_STANDARD_ITU_B:10462	case DRX_STANDARD_ITU_C:10463#endif /* DRXJ_VSB_ONLY */10464		break;10465	case DRX_STANDARD_UNKNOWN:10466	default:10467		return -EINVAL;10468	}10469 10470	/* check bandwidth QAM annex B, NTSC and 8VSB */10471	if ((standard == DRX_STANDARD_ITU_B) ||10472	    (standard == DRX_STANDARD_8VSB) ||10473	    (standard == DRX_STANDARD_NTSC)) {10474		switch (channel->bandwidth) {10475		case DRX_BANDWIDTH_6MHZ:10476		case DRX_BANDWIDTH_UNKNOWN:10477			channel->bandwidth = DRX_BANDWIDTH_6MHZ;10478			break;10479		case DRX_BANDWIDTH_8MHZ:10480		case DRX_BANDWIDTH_7MHZ:10481		default:10482			return -EINVAL;10483		}10484	}10485 10486	/* For QAM annex A and annex C:10487	   -check symbolrate and constellation10488	   -derive bandwidth from symbolrate (input bandwidth is ignored)10489	 */10490#ifndef DRXJ_VSB_ONLY10491	if ((standard == DRX_STANDARD_ITU_A) ||10492	    (standard == DRX_STANDARD_ITU_C)) {10493		struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };10494		int bw_rolloff_factor = 0;10495 10496		bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;10497		min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;10498		max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;10499		/* config SMA_TX pin to SAW switch mode */10500		rc = ctrl_set_uio_cfg(demod, &uio_cfg);10501		if (rc != 0) {10502			pr_err("error %d\n", rc);10503			goto rw_error;10504		}10505 10506		if (channel->symbolrate < min_symbol_rate ||10507		    channel->symbolrate > max_symbol_rate) {10508			return -EINVAL;10509		}10510 10511		switch (channel->constellation) {10512		case DRX_CONSTELLATION_QAM16:10513		case DRX_CONSTELLATION_QAM32:10514		case DRX_CONSTELLATION_QAM64:10515		case DRX_CONSTELLATION_QAM128:10516		case DRX_CONSTELLATION_QAM256:10517			bandwidth_temp = channel->symbolrate * bw_rolloff_factor;10518			bandwidth = bandwidth_temp / 100;10519 10520			if ((bandwidth_temp % 100) >= 50)10521				bandwidth++;10522 10523			if (bandwidth <= 6100000) {10524				channel->bandwidth = DRX_BANDWIDTH_6MHZ;10525			} else if ((bandwidth > 6100000)10526				   && (bandwidth <= 7100000)) {10527				channel->bandwidth = DRX_BANDWIDTH_7MHZ;10528			} else if (bandwidth > 7100000) {10529				channel->bandwidth = DRX_BANDWIDTH_8MHZ;10530			}10531			break;10532		default:10533			return -EINVAL;10534		}10535	}10536 10537	/* For QAM annex B:10538	   -check constellation10539	 */10540	if (standard == DRX_STANDARD_ITU_B) {10541		switch (channel->constellation) {10542		case DRX_CONSTELLATION_AUTO:10543		case DRX_CONSTELLATION_QAM256:10544		case DRX_CONSTELLATION_QAM64:10545			break;10546		default:10547			return -EINVAL;10548		}10549 10550		switch (channel->interleavemode) {10551		case DRX_INTERLEAVEMODE_I128_J1:10552		case DRX_INTERLEAVEMODE_I128_J1_V2:10553		case DRX_INTERLEAVEMODE_I128_J2:10554		case DRX_INTERLEAVEMODE_I64_J2:10555		case DRX_INTERLEAVEMODE_I128_J3:10556		case DRX_INTERLEAVEMODE_I32_J4:10557		case DRX_INTERLEAVEMODE_I128_J4:10558		case DRX_INTERLEAVEMODE_I16_J8:10559		case DRX_INTERLEAVEMODE_I128_J5:10560		case DRX_INTERLEAVEMODE_I8_J16:10561		case DRX_INTERLEAVEMODE_I128_J6:10562		case DRX_INTERLEAVEMODE_I128_J7:10563		case DRX_INTERLEAVEMODE_I128_J8:10564		case DRX_INTERLEAVEMODE_I12_J17:10565		case DRX_INTERLEAVEMODE_I5_J4:10566		case DRX_INTERLEAVEMODE_B52_M240:10567		case DRX_INTERLEAVEMODE_B52_M720:10568		case DRX_INTERLEAVEMODE_UNKNOWN:10569		case DRX_INTERLEAVEMODE_AUTO:10570			break;10571		default:10572			return -EINVAL;10573		}10574	}10575 10576	if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {10577		/* SAW SW, user UIO is used for switchable SAW */10578		struct drxuio_data uio1 = { DRX_UIO1, false };10579 10580		switch (channel->bandwidth) {10581		case DRX_BANDWIDTH_8MHZ:10582			uio1.value = true;10583			break;10584		case DRX_BANDWIDTH_7MHZ:10585			uio1.value = false;10586			break;10587		case DRX_BANDWIDTH_6MHZ:10588			uio1.value = false;10589			break;10590		case DRX_BANDWIDTH_UNKNOWN:10591		default:10592			return -EINVAL;10593		}10594 10595		rc = ctrl_uio_write(demod, &uio1);10596		if (rc != 0) {10597			pr_err("error %d\n", rc);10598			goto rw_error;10599		}10600	}10601#endif /* DRXJ_VSB_ONLY */10602	rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);10603	if (rc != 0) {10604		pr_err("error %d\n", rc);10605		goto rw_error;10606	}10607 10608	tuner_freq_offset = 0;10609 10610   /*== Setup demod for specific standard ====================================*/10611	switch (standard) {10612	case DRX_STANDARD_8VSB:10613		if (channel->mirror == DRX_MIRROR_AUTO)10614			ext_attr->mirror = DRX_MIRROR_NO;10615		else10616			ext_attr->mirror = channel->mirror;10617		rc = set_vsb(demod);10618		if (rc != 0) {10619			pr_err("error %d\n", rc);10620			goto rw_error;10621		}10622		rc = set_frequency(demod, channel, tuner_freq_offset);10623		if (rc != 0) {10624			pr_err("error %d\n", rc);10625			goto rw_error;10626		}10627		break;10628#ifndef DRXJ_VSB_ONLY10629	case DRX_STANDARD_ITU_A:10630	case DRX_STANDARD_ITU_B:10631	case DRX_STANDARD_ITU_C:10632		rc = set_qam_channel(demod, channel, tuner_freq_offset);10633		if (rc != 0) {10634			pr_err("error %d\n", rc);10635			goto rw_error;10636		}10637		break;10638#endif10639	case DRX_STANDARD_UNKNOWN:10640	default:10641		return -EIO;10642	}10643 10644	/* flag the packet error counter reset */10645	ext_attr->reset_pkt_err_acc = true;10646 10647	return 0;10648rw_error:10649	return rc;10650}10651 10652/*=============================================================================10653  ===== SigQuality() ==========================================================10654  ===========================================================================*/10655 10656/*10657* \fn int ctrl_sig_quality()10658* \brief Retrieve signal quality form device.10659* \param devmod Pointer to demodulator instance.10660* \param sig_quality Pointer to signal quality data.10661* \return int.10662* \retval 0 sig_quality contains valid data.10663* \retval -EINVAL sig_quality is NULL.10664* \retval -EIO Erroneous data, sig_quality contains invalid data.10665 10666*/10667static int10668ctrl_sig_quality(struct drx_demod_instance *demod,10669		 enum drx_lock_status lock_status)10670{10671	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;10672	struct drxj_data *ext_attr = demod->my_ext_attr;10673	struct drx39xxj_state *state = dev_addr->user_data;10674	struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;10675	enum drx_standard standard = ext_attr->standard;10676	int rc;10677	u32 ber, cnt, err, pkt;10678	u16 mer, strength = 0;10679 10680	rc = get_sig_strength(demod, &strength);10681	if (rc < 0) {10682		pr_err("error getting signal strength %d\n", rc);10683		p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10684	} else {10685		p->strength.stat[0].scale = FE_SCALE_RELATIVE;10686		p->strength.stat[0].uvalue = 65535UL *  strength/ 100;10687	}10688 10689	switch (standard) {10690	case DRX_STANDARD_8VSB:10691#ifdef DRXJ_SIGNAL_ACCUM_ERR10692		rc = get_acc_pkt_err(demod, &pkt);10693		if (rc != 0) {10694			pr_err("error %d\n", rc);10695			goto rw_error;10696		}10697#endif10698		if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {10699			p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10700			p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10701			p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10702			p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10703			p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10704			p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10705			p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10706		} else {10707			rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);10708			if (rc != 0) {10709				pr_err("error %d getting UCB\n", rc);10710				p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10711			} else {10712				p->block_error.stat[0].scale = FE_SCALE_COUNTER;10713				p->block_error.stat[0].uvalue += err;10714				p->block_count.stat[0].scale = FE_SCALE_COUNTER;10715				p->block_count.stat[0].uvalue += pkt;10716			}10717 10718			/* PostViterbi is compute in steps of 10^(-6) */10719			rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);10720			if (rc != 0) {10721				pr_err("error %d getting pre-ber\n", rc);10722				p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10723			} else {10724				p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;10725				p->pre_bit_error.stat[0].uvalue += ber;10726				p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;10727				p->pre_bit_count.stat[0].uvalue += cnt;10728			}10729 10730			rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);10731			if (rc != 0) {10732				pr_err("error %d getting post-ber\n", rc);10733				p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10734			} else {10735				p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;10736				p->post_bit_error.stat[0].uvalue += ber;10737				p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;10738				p->post_bit_count.stat[0].uvalue += cnt;10739			}10740			rc = get_vsbmer(dev_addr, &mer);10741			if (rc != 0) {10742				pr_err("error %d getting MER\n", rc);10743				p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;10744			} else {10745				p->cnr.stat[0].svalue = mer * 100;10746				p->cnr.stat[0].scale = FE_SCALE_DECIBEL;10747			}10748		}10749		break;10750#ifndef DRXJ_VSB_ONLY10751	case DRX_STANDARD_ITU_A:10752	case DRX_STANDARD_ITU_B:10753	case DRX_STANDARD_ITU_C:10754		rc = ctrl_get_qam_sig_quality(demod);10755		if (rc != 0) {10756			pr_err("error %d\n", rc);10757			goto rw_error;10758		}10759		break;10760#endif10761	default:10762		return -EIO;10763	}10764 10765	return 0;10766rw_error:10767	return rc;10768}10769 10770/*============================================================================*/10771 10772/*10773* \fn int ctrl_lock_status()10774* \brief Retrieve lock status .10775* \param dev_addr Pointer to demodulator device address.10776* \param lock_stat Pointer to lock status structure.10777* \return int.10778*10779*/10780static int10781ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)10782{10783	enum drx_standard standard = DRX_STANDARD_UNKNOWN;10784	struct drxj_data *ext_attr = NULL;10785	struct i2c_device_addr *dev_addr = NULL;10786	struct drxjscu_cmd cmd_scu = { /* command      */ 0,10787		/* parameter_len */ 0,10788		/* result_len    */ 0,10789		/* *parameter   */ NULL,10790		/* *result      */ NULL10791	};10792	int rc;10793	u16 cmd_result[2] = { 0, 0 };10794	u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;10795 10796	/* check arguments */10797	if ((demod == NULL) || (lock_stat == NULL))10798		return -EINVAL;10799 10800	dev_addr = demod->my_i2c_dev_addr;10801	ext_attr = (struct drxj_data *) demod->my_ext_attr;10802	standard = ext_attr->standard;10803 10804	*lock_stat = DRX_NOT_LOCKED;10805 10806	/* define the SCU command code */10807	switch (standard) {10808	case DRX_STANDARD_8VSB:10809		cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |10810		    SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;10811		demod_lock |= 0x6;10812		break;10813#ifndef DRXJ_VSB_ONLY10814	case DRX_STANDARD_ITU_A:10815	case DRX_STANDARD_ITU_B:10816	case DRX_STANDARD_ITU_C:10817		cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |10818		    SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;10819		break;10820#endif10821	case DRX_STANDARD_UNKNOWN:10822	default:10823		return -EIO;10824	}10825 10826	/* define the SCU command parameters and execute the command */10827	cmd_scu.parameter_len = 0;10828	cmd_scu.result_len = 2;10829	cmd_scu.parameter = NULL;10830	cmd_scu.result = cmd_result;10831	rc = scu_command(dev_addr, &cmd_scu);10832	if (rc != 0) {10833		pr_err("error %d\n", rc);10834		goto rw_error;10835	}10836 10837	/* set the lock status */10838	if (cmd_scu.result[1] < demod_lock) {10839		/* 0x0000 NOT LOCKED */10840		*lock_stat = DRX_NOT_LOCKED;10841	} else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {10842		*lock_stat = DRXJ_DEMOD_LOCK;10843	} else if (cmd_scu.result[1] <10844		   SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {10845		/* 0x8000 DEMOD + FEC LOCKED (system lock) */10846		*lock_stat = DRX_LOCKED;10847	} else {10848		/* 0xC000 NEVER LOCKED */10849		/* (system will never be able to lock to the signal) */10850		*lock_stat = DRX_NEVER_LOCK;10851	}10852 10853	return 0;10854rw_error:10855	return rc;10856}10857 10858/*============================================================================*/10859 10860/*10861* \fn int ctrl_set_standard()10862* \brief Set modulation standard to be used.10863* \param standard Modulation standard.10864* \return int.10865*10866* Setup stuff for the desired demodulation standard.10867* Disable and power down the previous selected demodulation standard10868*10869*/10870static int10871ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)10872{10873	struct drxj_data *ext_attr = NULL;10874	int rc;10875	enum drx_standard prev_standard;10876 10877	/* check arguments */10878	if ((standard == NULL) || (demod == NULL))10879		return -EINVAL;10880 10881	ext_attr = (struct drxj_data *) demod->my_ext_attr;10882	prev_standard = ext_attr->standard;10883 10884	/*10885	   Stop and power down previous standard10886	 */10887	switch (prev_standard) {10888#ifndef DRXJ_VSB_ONLY10889	case DRX_STANDARD_ITU_A:10890	case DRX_STANDARD_ITU_B:10891	case DRX_STANDARD_ITU_C:10892		rc = power_down_qam(demod, false);10893		if (rc != 0) {10894			pr_err("error %d\n", rc);10895			goto rw_error;10896		}10897		break;10898#endif10899	case DRX_STANDARD_8VSB:10900		rc = power_down_vsb(demod, false);10901		if (rc != 0) {10902			pr_err("error %d\n", rc);10903			goto rw_error;10904		}10905		break;10906	case DRX_STANDARD_UNKNOWN:10907		/* Do nothing */10908		break;10909	case DRX_STANDARD_AUTO:10910	default:10911		rc = -EINVAL;10912		goto rw_error;10913	}10914 10915	/*10916	   Initialize channel independent registers10917	   Power up new standard10918	 */10919	ext_attr->standard = *standard;10920 10921	switch (*standard) {10922#ifndef DRXJ_VSB_ONLY10923	case DRX_STANDARD_ITU_A:10924	case DRX_STANDARD_ITU_B:10925	case DRX_STANDARD_ITU_C:10926		do {10927			u16 dummy;10928			rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);10929			if (rc != 0) {10930				pr_err("error %d\n", rc);10931				goto rw_error;10932			}10933		} while (0);10934		break;10935#endif10936	case DRX_STANDARD_8VSB:10937		rc = set_vsb_leak_n_gain(demod);10938		if (rc != 0) {10939			pr_err("error %d\n", rc);10940			goto rw_error;10941		}10942		break;10943	default:10944		ext_attr->standard = DRX_STANDARD_UNKNOWN;10945		return -EINVAL;10946	}10947 10948	return 0;10949rw_error:10950	/* Don't know what the standard is now ... try again */10951	ext_attr->standard = DRX_STANDARD_UNKNOWN;10952	return rc;10953}10954 10955/*============================================================================*/10956 10957static void drxj_reset_mode(struct drxj_data *ext_attr)10958{10959	/* Initialize default AFE configuration for QAM */10960	if (ext_attr->has_lna) {10961		/* IF AGC off, PGA active */10962#ifndef DRXJ_VSB_ONLY10963		ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;10964		ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;10965		ext_attr->qam_pga_cfg = 140 + (11 * 13);10966#endif10967		ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;10968		ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;10969		ext_attr->vsb_pga_cfg = 140 + (11 * 13);10970	} else {10971		/* IF AGC on, PGA not active */10972#ifndef DRXJ_VSB_ONLY10973		ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;10974		ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;10975		ext_attr->qam_if_agc_cfg.min_output_level = 0;10976		ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;10977		ext_attr->qam_if_agc_cfg.speed = 3;10978		ext_attr->qam_if_agc_cfg.top = 1297;10979		ext_attr->qam_pga_cfg = 140;10980#endif10981		ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;10982		ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;10983		ext_attr->vsb_if_agc_cfg.min_output_level = 0;10984		ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;10985		ext_attr->vsb_if_agc_cfg.speed = 3;10986		ext_attr->vsb_if_agc_cfg.top = 1024;10987		ext_attr->vsb_pga_cfg = 140;10988	}10989	/* TODO: remove min_output_level and max_output_level for both QAM and VSB after */10990	/* mc has not used them */10991#ifndef DRXJ_VSB_ONLY10992	ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;10993	ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;10994	ext_attr->qam_rf_agc_cfg.min_output_level = 0;10995	ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;10996	ext_attr->qam_rf_agc_cfg.speed = 3;10997	ext_attr->qam_rf_agc_cfg.top = 9500;10998	ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;10999	ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;11000	ext_attr->qam_pre_saw_cfg.reference = 0x07;11001	ext_attr->qam_pre_saw_cfg.use_pre_saw = true;11002#endif11003	/* Initialize default AFE configuration for VSB */11004	ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;11005	ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;11006	ext_attr->vsb_rf_agc_cfg.min_output_level = 0;11007	ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;11008	ext_attr->vsb_rf_agc_cfg.speed = 3;11009	ext_attr->vsb_rf_agc_cfg.top = 9500;11010	ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;11011	ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;11012	ext_attr->vsb_pre_saw_cfg.reference = 0x07;11013	ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;11014}11015 11016/*11017* \fn int ctrl_power_mode()11018* \brief Set the power mode of the device to the specified power mode11019* \param demod Pointer to demodulator instance.11020* \param mode  Pointer to new power mode.11021* \return int.11022* \retval 0          Success11023* \retval -EIO       I2C error or other failure11024* \retval -EINVAL Invalid mode argument.11025*11026*11027*/11028static int11029ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)11030{11031	struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;11032	struct drxj_data *ext_attr = (struct drxj_data *) NULL;11033	struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;11034	int rc;11035	u16 sio_cc_pwd_mode = 0;11036 11037	common_attr = (struct drx_common_attr *) demod->my_common_attr;11038	ext_attr = (struct drxj_data *) demod->my_ext_attr;11039	dev_addr = demod->my_i2c_dev_addr;11040 11041	/* Check arguments */11042	if (mode == NULL)11043		return -EINVAL;11044 11045	/* If already in requested power mode, do nothing */11046	if (common_attr->current_power_mode == *mode)11047		return 0;11048 11049	switch (*mode) {11050	case DRX_POWER_UP:11051	case DRXJ_POWER_DOWN_MAIN_PATH:11052		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;11053		break;11054	case DRXJ_POWER_DOWN_CORE:11055		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;11056		break;11057	case DRXJ_POWER_DOWN_PLL:11058		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;11059		break;11060	case DRX_POWER_DOWN:11061		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;11062		break;11063	default:11064		/* Unknown sleep mode */11065		return -EINVAL;11066	}11067 11068	/* Check if device needs to be powered up */11069	if ((common_attr->current_power_mode != DRX_POWER_UP)) {11070		rc = power_up_device(demod);11071		if (rc != 0) {11072			pr_err("error %d\n", rc);11073			goto rw_error;11074		}11075	}11076 11077	if (*mode == DRX_POWER_UP) {11078		/* Restore analog & pin configuration */11079 11080		/* Initialize default AFE configuration for VSB */11081		drxj_reset_mode(ext_attr);11082	} else {11083		/* Power down to requested mode */11084		/* Backup some register settings */11085		/* Set pins with possible pull-ups connected to them in input mode */11086		/* Analog power down */11087		/* ADC power down */11088		/* Power down device */11089		/* stop all comm_exec */11090		/*11091		   Stop and power down previous standard11092		 */11093 11094		switch (ext_attr->standard) {11095		case DRX_STANDARD_ITU_A:11096		case DRX_STANDARD_ITU_B:11097		case DRX_STANDARD_ITU_C:11098			rc = power_down_qam(demod, true);11099			if (rc != 0) {11100				pr_err("error %d\n", rc);11101				goto rw_error;11102			}11103			break;11104		case DRX_STANDARD_8VSB:11105			rc = power_down_vsb(demod, true);11106			if (rc != 0) {11107				pr_err("error %d\n", rc);11108				goto rw_error;11109			}11110			break;11111		case DRX_STANDARD_PAL_SECAM_BG:11112		case DRX_STANDARD_PAL_SECAM_DK:11113		case DRX_STANDARD_PAL_SECAM_I:11114		case DRX_STANDARD_PAL_SECAM_L:11115		case DRX_STANDARD_PAL_SECAM_LP:11116		case DRX_STANDARD_NTSC:11117		case DRX_STANDARD_FM:11118			rc = power_down_atv(demod, ext_attr->standard, true);11119			if (rc != 0) {11120				pr_err("error %d\n", rc);11121				goto rw_error;11122			}11123			break;11124		case DRX_STANDARD_UNKNOWN:11125			/* Do nothing */11126			break;11127		case DRX_STANDARD_AUTO:11128		default:11129			return -EIO;11130		}11131		ext_attr->standard = DRX_STANDARD_UNKNOWN;11132	}11133 11134	if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {11135		rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);11136		if (rc != 0) {11137			pr_err("error %d\n", rc);11138			goto rw_error;11139		}11140		rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);11141		if (rc != 0) {11142			pr_err("error %d\n", rc);11143			goto rw_error;11144		}11145 11146		if ((*mode != DRX_POWER_UP)) {11147			/* Initialize HI, wakeup key especially before put IC to sleep */11148			rc = init_hi(demod);11149			if (rc != 0) {11150				pr_err("error %d\n", rc);11151				goto rw_error;11152			}11153 11154			ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;11155			rc = hi_cfg_command(demod);11156			if (rc != 0) {11157				pr_err("error %d\n", rc);11158				goto rw_error;11159			}11160		}11161	}11162 11163	common_attr->current_power_mode = *mode;11164 11165	return 0;11166rw_error:11167	return rc;11168}11169 11170/*============================================================================*/11171/*== CTRL Set/Get Config related functions ===================================*/11172/*============================================================================*/11173 11174/*11175* \fn int ctrl_set_cfg_pre_saw()11176* \brief Set Pre-saw reference.11177* \param demod demod instance11178* \param u16 *11179* \return int.11180*11181* Check arguments11182* Dispatch handling to standard specific function.11183*11184*/11185static int11186ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)11187{11188	struct i2c_device_addr *dev_addr = NULL;11189	struct drxj_data *ext_attr = NULL;11190	int rc;11191 11192	dev_addr = demod->my_i2c_dev_addr;11193	ext_attr = (struct drxj_data *) demod->my_ext_attr;11194 11195	/* check arguments */11196	if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)11197	    ) {11198		return -EINVAL;11199	}11200 11201	/* Only if standard is currently active */11202	if ((ext_attr->standard == pre_saw->standard) ||11203	    (DRXJ_ISQAMSTD(ext_attr->standard) &&11204	     DRXJ_ISQAMSTD(pre_saw->standard)) ||11205	    (DRXJ_ISATVSTD(ext_attr->standard) &&11206	     DRXJ_ISATVSTD(pre_saw->standard))) {11207		rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);11208		if (rc != 0) {11209			pr_err("error %d\n", rc);11210			goto rw_error;11211		}11212	}11213 11214	/* Store pre-saw settings */11215	switch (pre_saw->standard) {11216	case DRX_STANDARD_8VSB:11217		ext_attr->vsb_pre_saw_cfg = *pre_saw;11218		break;11219#ifndef DRXJ_VSB_ONLY11220	case DRX_STANDARD_ITU_A:11221	case DRX_STANDARD_ITU_B:11222	case DRX_STANDARD_ITU_C:11223		ext_attr->qam_pre_saw_cfg = *pre_saw;11224		break;11225#endif11226	default:11227		return -EINVAL;11228	}11229 11230	return 0;11231rw_error:11232	return rc;11233}11234 11235/*============================================================================*/11236 11237/*11238* \fn int ctrl_set_cfg_afe_gain()11239* \brief Set AFE Gain.11240* \param demod demod instance11241* \param u16 *11242* \return int.11243*11244* Check arguments11245* Dispatch handling to standard specific function.11246*11247*/11248static int11249ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)11250{11251	struct i2c_device_addr *dev_addr = NULL;11252	struct drxj_data *ext_attr = NULL;11253	int rc;11254	u8 gain = 0;11255 11256	/* check arguments */11257	if (afe_gain == NULL)11258		return -EINVAL;11259 11260	dev_addr = demod->my_i2c_dev_addr;11261	ext_attr = (struct drxj_data *) demod->my_ext_attr;11262 11263	switch (afe_gain->standard) {11264	case DRX_STANDARD_8VSB:	fallthrough;11265#ifndef DRXJ_VSB_ONLY11266	case DRX_STANDARD_ITU_A:11267	case DRX_STANDARD_ITU_B:11268	case DRX_STANDARD_ITU_C:11269#endif11270		/* Do nothing */11271		break;11272	default:11273		return -EINVAL;11274	}11275 11276	/* TODO PGA gain is also written by microcode (at least by QAM and VSB)11277	   So I (PJ) think interface requires choice between auto, user mode */11278 11279	if (afe_gain->gain >= 329)11280		gain = 15;11281	else if (afe_gain->gain <= 147)11282		gain = 0;11283	else11284		gain = (afe_gain->gain - 140 + 6) / 13;11285 11286	/* Only if standard is currently active */11287	if (ext_attr->standard == afe_gain->standard) {11288			rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);11289			if (rc != 0) {11290				pr_err("error %d\n", rc);11291				goto rw_error;11292			}11293		}11294 11295	/* Store AFE Gain settings */11296	switch (afe_gain->standard) {11297	case DRX_STANDARD_8VSB:11298		ext_attr->vsb_pga_cfg = gain * 13 + 140;11299		break;11300#ifndef DRXJ_VSB_ONLY11301	case DRX_STANDARD_ITU_A:11302	case DRX_STANDARD_ITU_B:11303	case DRX_STANDARD_ITU_C:11304		ext_attr->qam_pga_cfg = gain * 13 + 140;11305		break;11306#endif11307	default:11308		return -EIO;11309	}11310 11311	return 0;11312rw_error:11313	return rc;11314}11315 11316/*============================================================================*/11317 11318 11319/*=============================================================================11320===== EXPORTED FUNCTIONS ====================================================*/11321 11322static int drx_ctrl_u_code(struct drx_demod_instance *demod,11323		       struct drxu_code_info *mc_info,11324		       enum drxu_code_action action);11325static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);11326 11327/*11328* \fn drxj_open()11329* \brief Open the demod instance, configure device, configure drxdriver11330* \return Status_t Return status.11331*11332* drxj_open() can be called with a NULL ucode image => no ucode upload.11333* This means that drxj_open() must NOT contain SCU commands or, in general,11334* rely on SCU or AUD ucode to be present.11335*11336*/11337 11338static int drxj_open(struct drx_demod_instance *demod)11339{11340	struct i2c_device_addr *dev_addr = NULL;11341	struct drxj_data *ext_attr = NULL;11342	struct drx_common_attr *common_attr = NULL;11343	u32 driver_version = 0;11344	struct drxu_code_info ucode_info;11345	struct drx_cfg_mpeg_output cfg_mpeg_output;11346	int rc;11347	enum drx_power_mode power_mode = DRX_POWER_UP;11348 11349	if ((demod == NULL) ||11350	    (demod->my_common_attr == NULL) ||11351	    (demod->my_ext_attr == NULL) ||11352	    (demod->my_i2c_dev_addr == NULL) ||11353	    (demod->my_common_attr->is_opened)) {11354		return -EINVAL;11355	}11356 11357	/* Check arguments */11358	if (demod->my_ext_attr == NULL)11359		return -EINVAL;11360 11361	dev_addr = demod->my_i2c_dev_addr;11362	ext_attr = (struct drxj_data *) demod->my_ext_attr;11363	common_attr = (struct drx_common_attr *) demod->my_common_attr;11364 11365	rc = ctrl_power_mode(demod, &power_mode);11366	if (rc != 0) {11367		pr_err("error %d\n", rc);11368		goto rw_error;11369	}11370	if (power_mode != DRX_POWER_UP) {11371		rc = -EINVAL;11372		pr_err("failed to powerup device\n");11373		goto rw_error;11374	}11375 11376	/* has to be in front of setIqmAf and setOrxNsuAox */11377	rc = get_device_capabilities(demod);11378	if (rc != 0) {11379		pr_err("error %d\n", rc);11380		goto rw_error;11381	}11382 11383	/*11384	 * Soft reset of sys- and osc-clockdomain11385	 *11386	 * HACK: On windows, it writes a 0x07 here, instead of just 0x03.11387	 * As we didn't load the firmware here yet, we should do the same.11388	 * Btw, this is coherent with DRX-K, where we send reset codes11389	 * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.11390	 */11391	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);11392	if (rc != 0) {11393		pr_err("error %d\n", rc);11394		goto rw_error;11395	}11396	rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);11397	if (rc != 0) {11398		pr_err("error %d\n", rc);11399		goto rw_error;11400	}11401	msleep(1);11402 11403	/* TODO first make sure that everything keeps working before enabling this */11404	/* PowerDownAnalogBlocks() */11405	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);11406	if (rc != 0) {11407		pr_err("error %d\n", rc);11408		goto rw_error;11409	}11410 11411	rc = set_iqm_af(demod, false);11412	if (rc != 0) {11413		pr_err("error %d\n", rc);11414		goto rw_error;11415	}11416	rc = set_orx_nsu_aox(demod, false);11417	if (rc != 0) {11418		pr_err("error %d\n", rc);11419		goto rw_error;11420	}11421 11422	rc = init_hi(demod);11423	if (rc != 0) {11424		pr_err("error %d\n", rc);11425		goto rw_error;11426	}11427 11428	/* disable mpegoutput pins */11429	memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));11430	cfg_mpeg_output.enable_mpeg_output = false;11431 11432	rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);11433	if (rc != 0) {11434		pr_err("error %d\n", rc);11435		goto rw_error;11436	}11437	/* Stop AUD Inform SetAudio it will need to do all setting */11438	rc = power_down_aud(demod);11439	if (rc != 0) {11440		pr_err("error %d\n", rc);11441		goto rw_error;11442	}11443	/* Stop SCU */11444	rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);11445	if (rc != 0) {11446		pr_err("error %d\n", rc);11447		goto rw_error;11448	}11449 11450	/* Upload microcode */11451	if (common_attr->microcode_file != NULL) {11452		/* Dirty trick to use common ucode upload & verify,11453		   pretend device is already open */11454		common_attr->is_opened = true;11455		ucode_info.mc_file = common_attr->microcode_file;11456 11457		if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {11458			pr_err("Should powerup before loading the firmware.");11459			rc = -EINVAL;11460			goto rw_error;11461		}11462 11463		rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);11464		if (rc != 0) {11465			pr_err("error %d while uploading the firmware\n", rc);11466			goto rw_error;11467		}11468		if (common_attr->verify_microcode == true) {11469			rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);11470			if (rc != 0) {11471				pr_err("error %d while verifying the firmware\n",11472				       rc);11473				goto rw_error;11474			}11475		}11476		common_attr->is_opened = false;11477	}11478 11479	/* Run SCU for a little while to initialize microcode version numbers */11480	rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);11481	if (rc != 0) {11482		pr_err("error %d\n", rc);11483		goto rw_error;11484	}11485 11486	/* Initialize scan timeout */11487	common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;11488	common_attr->scan_desired_lock = DRX_LOCKED;11489 11490	drxj_reset_mode(ext_attr);11491	ext_attr->standard = DRX_STANDARD_UNKNOWN;11492 11493	rc = smart_ant_init(demod);11494	if (rc != 0) {11495		pr_err("error %d\n", rc);11496		goto rw_error;11497	}11498 11499	/* Stamp driver version number in SCU data RAM in BCD code11500	   Done to enable field application engineers to retrieve drxdriver version11501	   via I2C from SCU RAM11502	 */11503	driver_version = (VERSION_MAJOR / 100) % 10;11504	driver_version <<= 4;11505	driver_version += (VERSION_MAJOR / 10) % 10;11506	driver_version <<= 4;11507	driver_version += (VERSION_MAJOR % 10);11508	driver_version <<= 4;11509	driver_version += (VERSION_MINOR % 10);11510	driver_version <<= 4;11511	driver_version += (VERSION_PATCH / 1000) % 10;11512	driver_version <<= 4;11513	driver_version += (VERSION_PATCH / 100) % 10;11514	driver_version <<= 4;11515	driver_version += (VERSION_PATCH / 10) % 10;11516	driver_version <<= 4;11517	driver_version += (VERSION_PATCH % 10);11518	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);11519	if (rc != 0) {11520		pr_err("error %d\n", rc);11521		goto rw_error;11522	}11523	rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);11524	if (rc != 0) {11525		pr_err("error %d\n", rc);11526		goto rw_error;11527	}11528 11529	rc = ctrl_set_oob(demod, NULL);11530	if (rc != 0) {11531		pr_err("error %d\n", rc);11532		goto rw_error;11533	}11534 11535	/* refresh the audio data structure with default */11536	ext_attr->aud_data = drxj_default_aud_data_g;11537 11538	demod->my_common_attr->is_opened = true;11539	drxj_set_lna_state(demod, false);11540	return 0;11541rw_error:11542	common_attr->is_opened = false;11543	return rc;11544}11545 11546/*============================================================================*/11547/*11548* \fn drxj_close()11549* \brief Close the demod instance, power down the device11550* \return Status_t Return status.11551*11552*/11553static int drxj_close(struct drx_demod_instance *demod)11554{11555	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;11556	int rc;11557	enum drx_power_mode power_mode = DRX_POWER_UP;11558 11559	if ((demod->my_common_attr == NULL) ||11560	    (demod->my_ext_attr == NULL) ||11561	    (demod->my_i2c_dev_addr == NULL) ||11562	    (!demod->my_common_attr->is_opened)) {11563		return -EINVAL;11564	}11565 11566	/* power up */11567	rc = ctrl_power_mode(demod, &power_mode);11568	if (rc != 0) {11569		pr_err("error %d\n", rc);11570		goto rw_error;11571	}11572 11573	rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);11574	if (rc != 0) {11575		pr_err("error %d\n", rc);11576		goto rw_error;11577	}11578	power_mode = DRX_POWER_DOWN;11579	rc = ctrl_power_mode(demod, &power_mode);11580	if (rc != 0) {11581		pr_err("error %d\n", rc);11582		goto rw_error;11583	}11584 11585	DRX_ATTR_ISOPENED(demod) = false;11586 11587	return 0;11588rw_error:11589	DRX_ATTR_ISOPENED(demod) = false;11590 11591	return rc;11592}11593 11594/*11595 * Microcode related functions11596 */11597 11598/*11599 * drx_u_code_compute_crc	- Compute CRC of block of microcode data.11600 * @block_data: Pointer to microcode data.11601 * @nr_words:   Size of microcode block (number of 16 bits words).11602 *11603 * returns The computed CRC residue.11604 */11605static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)11606{11607	u16 i = 0;11608	u16 j = 0;11609	u32 crc_word = 0;11610	u32 carry = 0;11611 11612	while (i < nr_words) {11613		crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));11614		for (j = 0; j < 16; j++) {11615			crc_word <<= 1;11616			if (carry != 0)11617				crc_word ^= 0x80050000UL;11618			carry = crc_word & 0x80000000UL;11619		}11620		i++;11621		block_data += (sizeof(u16));11622	}11623	return (u16)(crc_word >> 16);11624}11625 11626/*11627 * drx_check_firmware - checks if the loaded firmware is valid11628 *11629 * @demod:	demod structure11630 * @mc_data:	pointer to the start of the firmware11631 * @size:	firmware size11632 */11633static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,11634			  unsigned size)11635{11636	struct drxu_code_block_hdr block_hdr;11637	int i;11638	unsigned count = 2 * sizeof(u16);11639	u32 mc_dev_type, mc_version, mc_base_version;11640	u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));11641 11642	/*11643	 * Scan microcode blocks first for version info11644	 * and firmware check11645	 */11646 11647	/* Clear version block */11648	DRX_ATTR_MCRECORD(demod).aux_type = 0;11649	DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;11650	DRX_ATTR_MCRECORD(demod).mc_version = 0;11651	DRX_ATTR_MCRECORD(demod).mc_base_version = 0;11652 11653	for (i = 0; i < mc_nr_of_blks; i++) {11654		if (count + 3 * sizeof(u16) + sizeof(u32) > size)11655			goto eof;11656 11657		/* Process block header */11658		block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));11659		count += sizeof(u32);11660		block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));11661		count += sizeof(u16);11662		block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));11663		count += sizeof(u16);11664		block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));11665		count += sizeof(u16);11666 11667		pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",11668			count, block_hdr.addr, block_hdr.size, block_hdr.flags,11669			block_hdr.CRC);11670 11671		if (block_hdr.flags & 0x8) {11672			u8 *auxblk = ((void *)mc_data) + block_hdr.addr;11673			u16 auxtype;11674 11675			if (block_hdr.addr + sizeof(u16) > size)11676				goto eof;11677 11678			auxtype = be16_to_cpu(*(__be16 *)(auxblk));11679 11680			/* Aux block. Check type */11681			if (DRX_ISMCVERTYPE(auxtype)) {11682				if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)11683					goto eof;11684 11685				auxblk += sizeof(u16);11686				mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));11687				auxblk += sizeof(u32);11688				mc_version = be32_to_cpu(*(__be32 *)(auxblk));11689				auxblk += sizeof(u32);11690				mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));11691 11692				DRX_ATTR_MCRECORD(demod).aux_type = auxtype;11693				DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;11694				DRX_ATTR_MCRECORD(demod).mc_version = mc_version;11695				DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;11696 11697				pr_info("Firmware dev %x, ver %x, base ver %x\n",11698					mc_dev_type, mc_version, mc_base_version);11699 11700			}11701		} else if (count + block_hdr.size * sizeof(u16) > size)11702			goto eof;11703 11704		count += block_hdr.size * sizeof(u16);11705	}11706	return 0;11707eof:11708	pr_err("Firmware is truncated at pos %u/%u\n", count, size);11709	return -EINVAL;11710}11711 11712/*11713 * drx_ctrl_u_code - Handle microcode upload or verify.11714 * @dev_addr: Address of device.11715 * @mc_info:  Pointer to information about microcode data.11716 * @action:  Either UCODE_UPLOAD or UCODE_VERIFY11717 *11718 * This function returns:11719 *	0:11720 *		- In case of UCODE_UPLOAD: code is successfully uploaded.11721 *               - In case of UCODE_VERIFY: image on device is equal to11722 *		  image provided to this control function.11723 *	-EIO:11724 *		- In case of UCODE_UPLOAD: I2C error.11725 *		- In case of UCODE_VERIFY: I2C error or image on device11726 *		  is not equal to image provided to this control function.11727 *	-EINVAL:11728 *		- Invalid arguments.11729 *		- Provided image is corrupt11730 */11731static int drx_ctrl_u_code(struct drx_demod_instance *demod,11732		       struct drxu_code_info *mc_info,11733		       enum drxu_code_action action)11734{11735	struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;11736	int rc;11737	u16 i = 0;11738	u16 mc_nr_of_blks = 0;11739	u16 mc_magic_word = 0;11740	const u8 *mc_data_init = NULL;11741	u8 *mc_data = NULL;11742	unsigned size;11743	char *mc_file;11744	const struct firmware *fw;11745 11746	/* Check arguments */11747	if (!mc_info || !mc_info->mc_file)11748		return -EINVAL;11749 11750	mc_file = mc_info->mc_file;11751 11752	rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);11753	if (rc < 0) {11754		pr_err("Couldn't read firmware %s\n", mc_file);11755		return rc;11756	}11757 11758	if (fw->size < 2 * sizeof(u16)) {11759		rc = -EINVAL;11760		pr_err("Firmware is too short!\n");11761		goto release;11762	}11763 11764	pr_info("Firmware %s, size %zu\n", mc_file, fw->size);11765 11766	mc_data_init = fw->data;11767	size = fw->size;11768 11769	mc_data = (void *)mc_data_init;11770	/* Check data */11771	mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));11772	mc_data += sizeof(u16);11773	mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));11774	mc_data += sizeof(u16);11775 11776	if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {11777		rc = -EINVAL;11778		pr_err("Firmware magic word doesn't match\n");11779		goto release;11780	}11781 11782	if (action == UCODE_UPLOAD) {11783		rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);11784		if (rc)11785			goto release;11786		pr_info("Uploading firmware %s\n", mc_file);11787	} else {11788		pr_info("Verifying if firmware upload was ok.\n");11789	}11790 11791	/* Process microcode blocks */11792	for (i = 0; i < mc_nr_of_blks; i++) {11793		struct drxu_code_block_hdr block_hdr;11794		u16 mc_block_nr_bytes = 0;11795 11796		/* Process block header */11797		block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));11798		mc_data += sizeof(u32);11799		block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));11800		mc_data += sizeof(u16);11801		block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));11802		mc_data += sizeof(u16);11803		block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));11804		mc_data += sizeof(u16);11805 11806		pr_debug("%zd: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",11807			(mc_data - mc_data_init), block_hdr.addr,11808			 block_hdr.size, block_hdr.flags, block_hdr.CRC);11809 11810		/* Check block header on:11811		   - data larger than 64Kb11812		   - if CRC enabled check CRC11813		 */11814		if ((block_hdr.size > 0x7FFF) ||11815		    (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&11816		     (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))11817		    ) {11818			/* Wrong data ! */11819			rc = -EINVAL;11820			pr_err("firmware CRC is wrong\n");11821			goto release;11822		}11823 11824		if (!block_hdr.size)11825			continue;11826 11827		mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));11828 11829		/* Perform the desired action */11830		switch (action) {11831		case UCODE_UPLOAD:	/* Upload microcode */11832			if (drxdap_fasi_write_block(dev_addr,11833							block_hdr.addr,11834							mc_block_nr_bytes,11835							mc_data, 0x0000)) {11836				rc = -EIO;11837				pr_err("error writing firmware at pos %zd\n",11838				       mc_data - mc_data_init);11839				goto release;11840			}11841			break;11842		case UCODE_VERIFY: {	/* Verify uploaded microcode */11843			int result = 0;11844			u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];11845			u32 bytes_to_comp = 0;11846			u32 bytes_left = mc_block_nr_bytes;11847			u32 curr_addr = block_hdr.addr;11848			u8 *curr_ptr = mc_data;11849 11850			while (bytes_left != 0) {11851				if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)11852					bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;11853				else11854					bytes_to_comp = bytes_left;11855 11856				if (drxdap_fasi_read_block(dev_addr,11857						    curr_addr,11858						    (u16)bytes_to_comp,11859						    (u8 *)mc_data_buffer,11860						    0x0000)) {11861					pr_err("error reading firmware at pos %zd\n",11862					       mc_data - mc_data_init);11863					rc = -EIO;11864					goto release;11865				}11866 11867				result = memcmp(curr_ptr, mc_data_buffer,11868						bytes_to_comp);11869 11870				if (result) {11871					pr_err("error verifying firmware at pos %zd\n",11872					       mc_data - mc_data_init);11873					rc = -EIO;11874					goto release;11875				}11876 11877				curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));11878				curr_ptr =&(curr_ptr[bytes_to_comp]);11879				bytes_left -=((u32) bytes_to_comp);11880			}11881			break;11882		}11883		default:11884			rc = -EINVAL;11885			goto release;11886 11887		}11888		mc_data += mc_block_nr_bytes;11889	}11890 11891	rc = 0;11892 11893release:11894	release_firmware(fw);11895 11896	return rc;11897}11898 11899/* caller is expected to check if lna is supported before enabling */11900static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)11901{11902	struct drxuio_cfg uio_cfg;11903	struct drxuio_data uio_data;11904	int result;11905 11906	uio_cfg.uio = DRX_UIO1;11907	uio_cfg.mode = DRX_UIO_MODE_READWRITE;11908	/* Configure user-I/O #3: enable read/write */11909	result = ctrl_set_uio_cfg(demod, &uio_cfg);11910	if (result) {11911		pr_err("Failed to setup LNA GPIO!\n");11912		return result;11913	}11914 11915	uio_data.uio = DRX_UIO1;11916	uio_data.value = state;11917	result = ctrl_uio_write(demod, &uio_data);11918	if (result != 0) {11919		pr_err("Failed to %sable LNA!\n",11920		       state ? "en" : "dis");11921		return result;11922	}11923	return 0;11924}11925 11926/*11927 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)11928 *11929 * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>11930 */11931 11932static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)11933{11934	struct drx39xxj_state *state = fe->demodulator_priv;11935	struct drx_demod_instance *demod = state->demod;11936	int result;11937	enum drx_power_mode power_mode;11938 11939	if (enable)11940		power_mode = DRX_POWER_UP;11941	else11942		power_mode = DRX_POWER_DOWN;11943 11944	result = ctrl_power_mode(demod, &power_mode);11945	if (result != 0) {11946		pr_err("Power state change failed\n");11947		return 0;11948	}11949 11950	return 0;11951}11952 11953static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)11954{11955	struct drx39xxj_state *state = fe->demodulator_priv;11956	struct drx_demod_instance *demod = state->demod;11957	int result;11958	enum drx_lock_status lock_status;11959 11960	*status = 0;11961 11962	result = ctrl_lock_status(demod, &lock_status);11963	if (result != 0) {11964		pr_err("drx39xxj: could not get lock status!\n");11965		*status = 0;11966	}11967 11968	switch (lock_status) {11969	case DRX_NEVER_LOCK:11970		*status = 0;11971		pr_err("drx says NEVER_LOCK\n");11972		break;11973	case DRX_NOT_LOCKED:11974		*status = 0;11975		break;11976	case DRX_LOCK_STATE_1:11977	case DRX_LOCK_STATE_2:11978	case DRX_LOCK_STATE_3:11979	case DRX_LOCK_STATE_4:11980	case DRX_LOCK_STATE_5:11981	case DRX_LOCK_STATE_6:11982	case DRX_LOCK_STATE_7:11983	case DRX_LOCK_STATE_8:11984	case DRX_LOCK_STATE_9:11985		*status = FE_HAS_SIGNAL11986		    | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;11987		break;11988	case DRX_LOCKED:11989		*status = FE_HAS_SIGNAL11990		    | FE_HAS_CARRIER11991		    | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;11992		break;11993	default:11994		pr_err("Lock state unknown %d\n", lock_status);11995	}11996	ctrl_sig_quality(demod, lock_status);11997 11998	return 0;11999}12000 12001static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)12002{12003	struct dtv_frontend_properties *p = &fe->dtv_property_cache;12004 12005	if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {12006		*ber = 0;12007		return 0;12008	}12009 12010	if (!p->pre_bit_count.stat[0].uvalue) {12011		if (!p->pre_bit_error.stat[0].uvalue)12012			*ber = 0;12013		else12014			*ber = 1000000;12015	} else {12016		*ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,12017				     p->pre_bit_count.stat[0].uvalue);12018	}12019	return 0;12020}12021 12022static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,12023					 u16 *strength)12024{12025	struct dtv_frontend_properties *p = &fe->dtv_property_cache;12026 12027	if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {12028		*strength = 0;12029		return 0;12030	}12031 12032	*strength = p->strength.stat[0].uvalue;12033	return 0;12034}12035 12036static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)12037{12038	struct dtv_frontend_properties *p = &fe->dtv_property_cache;12039	u64 tmp64;12040 12041	if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {12042		*snr = 0;12043		return 0;12044	}12045 12046	tmp64 = p->cnr.stat[0].svalue;12047	do_div(tmp64, 10);12048	*snr = tmp64;12049	return 0;12050}12051 12052static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)12053{12054	struct dtv_frontend_properties *p = &fe->dtv_property_cache;12055 12056	if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {12057		*ucb = 0;12058		return 0;12059	}12060 12061	*ucb = p->block_error.stat[0].uvalue;12062	return 0;12063}12064 12065static int drx39xxj_set_frontend(struct dvb_frontend *fe)12066{12067#ifdef DJH_DEBUG12068	int i;12069#endif12070	struct dtv_frontend_properties *p = &fe->dtv_property_cache;12071	struct drx39xxj_state *state = fe->demodulator_priv;12072	struct drx_demod_instance *demod = state->demod;12073	enum drx_standard standard = DRX_STANDARD_8VSB;12074	struct drx_channel channel;12075	int result;12076	static const struct drx_channel def_channel = {12077		/* frequency      */ 0,12078		/* bandwidth      */ DRX_BANDWIDTH_6MHZ,12079		/* mirror         */ DRX_MIRROR_NO,12080		/* constellation  */ DRX_CONSTELLATION_AUTO,12081		/* hierarchy      */ DRX_HIERARCHY_UNKNOWN,12082		/* priority       */ DRX_PRIORITY_UNKNOWN,12083		/* coderate       */ DRX_CODERATE_UNKNOWN,12084		/* guard          */ DRX_GUARD_UNKNOWN,12085		/* fftmode        */ DRX_FFTMODE_UNKNOWN,12086		/* classification */ DRX_CLASSIFICATION_AUTO,12087		/* symbolrate     */ 5057000,12088		/* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,12089		/* ldpc           */ DRX_LDPC_UNKNOWN,12090		/* carrier        */ DRX_CARRIER_UNKNOWN,12091		/* frame mode     */ DRX_FRAMEMODE_UNKNOWN12092	};12093	u32 constellation = DRX_CONSTELLATION_AUTO;12094 12095	/* Bring the demod out of sleep */12096	drx39xxj_set_powerstate(fe, 1);12097 12098	if (fe->ops.tuner_ops.set_params) {12099		u32 int_freq;12100 12101		if (fe->ops.i2c_gate_ctrl)12102			fe->ops.i2c_gate_ctrl(fe, 1);12103 12104		/* Set tuner to desired frequency and standard */12105		fe->ops.tuner_ops.set_params(fe);12106 12107		/* Use the tuner's IF */12108		if (fe->ops.tuner_ops.get_if_frequency) {12109			fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);12110			demod->my_common_attr->intermediate_freq = int_freq / 1000;12111		}12112 12113		if (fe->ops.i2c_gate_ctrl)12114			fe->ops.i2c_gate_ctrl(fe, 0);12115	}12116 12117	switch (p->delivery_system) {12118	case SYS_ATSC:12119		standard = DRX_STANDARD_8VSB;12120		break;12121	case SYS_DVBC_ANNEX_B:12122		standard = DRX_STANDARD_ITU_B;12123 12124		switch (p->modulation) {12125		case QAM_64:12126			constellation = DRX_CONSTELLATION_QAM64;12127			break;12128		case QAM_256:12129			constellation = DRX_CONSTELLATION_QAM256;12130			break;12131		default:12132			constellation = DRX_CONSTELLATION_AUTO;12133			break;12134		}12135		break;12136	default:12137		return -EINVAL;12138	}12139	/* Set the standard (will be powered up if necessary */12140	result = ctrl_set_standard(demod, &standard);12141	if (result != 0) {12142		pr_err("Failed to set standard! result=%02x\n",12143			result);12144		return -EINVAL;12145	}12146 12147	/* set channel parameters */12148	channel = def_channel;12149	channel.frequency = p->frequency / 1000;12150	channel.bandwidth = DRX_BANDWIDTH_6MHZ;12151	channel.constellation = constellation;12152 12153	/* program channel */12154	result = ctrl_set_channel(demod, &channel);12155	if (result != 0) {12156		pr_err("Failed to set channel!\n");12157		return -EINVAL;12158	}12159	/* Just for giggles, let's shut off the LNA again.... */12160	drxj_set_lna_state(demod, false);12161 12162	/* After set_frontend, except for strength, stats aren't available */12163	p->strength.stat[0].scale = FE_SCALE_RELATIVE;12164 12165	return 0;12166}12167 12168static int drx39xxj_sleep(struct dvb_frontend *fe)12169{12170	/* power-down the demodulator */12171	return drx39xxj_set_powerstate(fe, 0);12172}12173 12174static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)12175{12176	struct drx39xxj_state *state = fe->demodulator_priv;12177	struct drx_demod_instance *demod = state->demod;12178	bool i2c_gate_state;12179	int result;12180 12181#ifdef DJH_DEBUG12182	pr_debug("i2c gate call: enable=%d state=%d\n", enable,12183	       state->i2c_gate_open);12184#endif12185 12186	if (enable)12187		i2c_gate_state = true;12188	else12189		i2c_gate_state = false;12190 12191	if (state->i2c_gate_open == enable) {12192		/* We're already in the desired state */12193		return 0;12194	}12195 12196	result = ctrl_i2c_bridge(demod, &i2c_gate_state);12197	if (result != 0) {12198		pr_err("drx39xxj: could not open i2c gate [%d]\n",12199		       result);12200		dump_stack();12201	} else {12202		state->i2c_gate_open = enable;12203	}12204	return 0;12205}12206 12207static int drx39xxj_init(struct dvb_frontend *fe)12208{12209	struct drx39xxj_state *state = fe->demodulator_priv;12210	struct drx_demod_instance *demod = state->demod;12211	int rc = 0;12212 12213	if (fe->exit == DVB_FE_DEVICE_RESUME) {12214		/* so drxj_open() does what it needs to do */12215		demod->my_common_attr->is_opened = false;12216		rc = drxj_open(demod);12217		if (rc != 0)12218			pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);12219	} else12220		drx39xxj_set_powerstate(fe, 1);12221 12222	return rc;12223}12224 12225static int drx39xxj_set_lna(struct dvb_frontend *fe)12226{12227	struct dtv_frontend_properties *c = &fe->dtv_property_cache;12228	struct drx39xxj_state *state = fe->demodulator_priv;12229	struct drx_demod_instance *demod = state->demod;12230	struct drxj_data *ext_attr = demod->my_ext_attr;12231 12232	if (c->lna) {12233		if (!ext_attr->has_lna) {12234			pr_err("LNA is not supported on this device!\n");12235			return -EINVAL;12236 12237		}12238	}12239 12240	return drxj_set_lna_state(demod, c->lna);12241}12242 12243static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,12244				      struct dvb_frontend_tune_settings *tune)12245{12246	tune->min_delay_ms = 1000;12247	return 0;12248}12249 12250static void drx39xxj_release(struct dvb_frontend *fe)12251{12252	struct drx39xxj_state *state = fe->demodulator_priv;12253	struct drx_demod_instance *demod = state->demod;12254 12255	/* if device is removed don't access it */12256	if (fe->exit != DVB_FE_DEVICE_REMOVED)12257		drxj_close(demod);12258 12259	kfree(demod->my_ext_attr);12260	kfree(demod->my_common_attr);12261	kfree(demod->my_i2c_dev_addr);12262	kfree(demod);12263	kfree(state);12264}12265 12266static const struct dvb_frontend_ops drx39xxj_ops;12267 12268struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)12269{12270	struct drx39xxj_state *state = NULL;12271	struct i2c_device_addr *demod_addr = NULL;12272	struct drx_common_attr *demod_comm_attr = NULL;12273	struct drxj_data *demod_ext_attr = NULL;12274	struct drx_demod_instance *demod = NULL;12275	struct dtv_frontend_properties *p;12276	int result;12277 12278	/* allocate memory for the internal state */12279	state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);12280	if (state == NULL)12281		goto error;12282 12283	demod = kmemdup(&drxj_default_demod_g,12284			sizeof(struct drx_demod_instance), GFP_KERNEL);12285	if (demod == NULL)12286		goto error;12287 12288	demod_addr = kmemdup(&drxj_default_addr_g,12289			     sizeof(struct i2c_device_addr), GFP_KERNEL);12290	if (demod_addr == NULL)12291		goto error;12292 12293	demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,12294				  sizeof(struct drx_common_attr), GFP_KERNEL);12295	if (demod_comm_attr == NULL)12296		goto error;12297 12298	demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),12299				 GFP_KERNEL);12300	if (demod_ext_attr == NULL)12301		goto error;12302 12303	/* setup the state */12304	state->i2c = i2c;12305	state->demod = demod;12306 12307	/* setup the demod data */12308	demod->my_i2c_dev_addr = demod_addr;12309	demod->my_common_attr = demod_comm_attr;12310	demod->my_i2c_dev_addr->user_data = state;12311	demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;12312	demod->my_common_attr->verify_microcode = true;12313	demod->my_common_attr->intermediate_freq = 5000;12314	demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;12315	demod->my_ext_attr = demod_ext_attr;12316	((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;12317	demod->i2c = i2c;12318 12319	result = drxj_open(demod);12320	if (result != 0) {12321		pr_err("DRX open failed!  Aborting\n");12322		goto error;12323	}12324 12325	/* create dvb_frontend */12326	memcpy(&state->frontend.ops, &drx39xxj_ops,12327	       sizeof(struct dvb_frontend_ops));12328 12329	state->frontend.demodulator_priv = state;12330 12331	/* Initialize stats - needed for DVBv5 stats to work */12332	p = &state->frontend.dtv_property_cache;12333	p->strength.len = 1;12334	p->pre_bit_count.len = 1;12335	p->pre_bit_error.len = 1;12336	p->post_bit_count.len = 1;12337	p->post_bit_error.len = 1;12338	p->block_count.len = 1;12339	p->block_error.len = 1;12340	p->cnr.len = 1;12341 12342	p->strength.stat[0].scale = FE_SCALE_RELATIVE;12343	p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;12344	p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;12345	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;12346	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;12347	p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;12348	p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;12349	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;12350 12351	return &state->frontend;12352 12353error:12354	kfree(demod_ext_attr);12355	kfree(demod_comm_attr);12356	kfree(demod_addr);12357	kfree(demod);12358	kfree(state);12359 12360	return NULL;12361}12362EXPORT_SYMBOL_GPL(drx39xxj_attach);12363 12364static const struct dvb_frontend_ops drx39xxj_ops = {12365	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },12366	.info = {12367		 .name = "Micronas DRX39xxj family Frontend",12368		 .frequency_min_hz =  51 * MHz,12369		 .frequency_max_hz = 858 * MHz,12370		 .frequency_stepsize_hz = 62500,12371		 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB12372	},12373 12374	.init = drx39xxj_init,12375	.i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,12376	.sleep = drx39xxj_sleep,12377	.set_frontend = drx39xxj_set_frontend,12378	.get_tune_settings = drx39xxj_get_tune_settings,12379	.read_status = drx39xxj_read_status,12380	.read_ber = drx39xxj_read_ber,12381	.read_signal_strength = drx39xxj_read_signal_strength,12382	.read_snr = drx39xxj_read_snr,12383	.read_ucblocks = drx39xxj_read_ucblocks,12384	.release = drx39xxj_release,12385	.set_lna = drx39xxj_set_lna,12386};12387 12388MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");12389MODULE_AUTHOR("Devin Heitmueller");12390MODULE_LICENSE("GPL");12391MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);12392