linux/drivers/media/dvb-frontends/drx39xyj/drxj.c
<<
>>
Prefs
   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 without
   6  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 documentation
  12        and/or other materials provided with the distribution.
  13  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
  14    nor the names of its contributors may be used to endorse or promote
  15        products derived from this software without specific prior written
  16        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, THE
  20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  22  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26  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 THE
  28  POSSIBILITY OF SUCH DAMAGE.
  29
  30  DRXJ specific implementation of DRX driver
  31  authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
  32
  33  The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
  34  written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
  35
  36  This program is free software; you can redistribute it and/or modify
  37  it under the terms of the GNU General Public License as published by
  38  the Free Software Foundation; either version 2 of the License, or
  39  (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 of
  43  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  44
  45  GNU General Public License for more details.
  46
  47  You should have received a copy of the GNU General Public License
  48  along with this program; if not, write to the Free Software
  49  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  50*/
  51
  52/*-----------------------------------------------------------------------------
  53INCLUDE FILES
  54----------------------------------------------------------------------------*/
  55
  56#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
  57
  58#include <linux/module.h>
  59#include <linux/init.h>
  60#include <linux/string.h>
  61#include <linux/slab.h>
  62#include <asm/div64.h>
  63
  64#include <media/dvb_frontend.h>
  65#include "drx39xxj.h"
  66
  67#include "drxj.h"
  68#include "drxj_map.h"
  69
  70/*============================================================================*/
  71/*=== DEFINES ================================================================*/
  72/*============================================================================*/
  73
  74#define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
  75
  76/*
  77* \brief Maximum u32 value.
  78*/
  79#ifndef MAX_U32
  80#define MAX_U32  ((u32) (0xFFFFFFFFL))
  81#endif
  82
  83/* Customer configurable hardware settings, etc */
  84#ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
  85#define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
  86#endif
  87
  88#ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
  89#define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
  90#endif
  91
  92#ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
  93#define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
  94#endif
  95
  96#ifndef OOB_CRX_DRIVE_STRENGTH
  97#define OOB_CRX_DRIVE_STRENGTH 0x02
  98#endif
  99
 100#ifndef OOB_DRX_DRIVE_STRENGTH
 101#define OOB_DRX_DRIVE_STRENGTH 0x02
 102#endif
 103/*** START DJCOMBO patches to DRXJ registermap constants *********************/
 104/*** registermap 200706071303 from drxj **************************************/
 105#define   ATV_TOP_CR_AMP_TH_FM                                              0x0
 106#define   ATV_TOP_CR_AMP_TH_L                                               0xA
 107#define   ATV_TOP_CR_AMP_TH_LP                                              0xA
 108#define   ATV_TOP_CR_AMP_TH_BG                                              0x8
 109#define   ATV_TOP_CR_AMP_TH_DK                                              0x8
 110#define   ATV_TOP_CR_AMP_TH_I                                               0x8
 111#define     ATV_TOP_CR_CONT_CR_D_MN                                         0x18
 112#define     ATV_TOP_CR_CONT_CR_D_FM                                         0x0
 113#define     ATV_TOP_CR_CONT_CR_D_L                                          0x20
 114#define     ATV_TOP_CR_CONT_CR_D_LP                                         0x20
 115#define     ATV_TOP_CR_CONT_CR_D_BG                                         0x18
 116#define     ATV_TOP_CR_CONT_CR_D_DK                                         0x18
 117#define     ATV_TOP_CR_CONT_CR_D_I                                          0x18
 118#define     ATV_TOP_CR_CONT_CR_I_MN                                         0x80
 119#define     ATV_TOP_CR_CONT_CR_I_FM                                         0x0
 120#define     ATV_TOP_CR_CONT_CR_I_L                                          0x80
 121#define     ATV_TOP_CR_CONT_CR_I_LP                                         0x80
 122#define     ATV_TOP_CR_CONT_CR_I_BG                                         0x80
 123#define     ATV_TOP_CR_CONT_CR_I_DK                                         0x80
 124#define     ATV_TOP_CR_CONT_CR_I_I                                          0x80
 125#define     ATV_TOP_CR_CONT_CR_P_MN                                         0x4
 126#define     ATV_TOP_CR_CONT_CR_P_FM                                         0x0
 127#define     ATV_TOP_CR_CONT_CR_P_L                                          0x4
 128#define     ATV_TOP_CR_CONT_CR_P_LP                                         0x4
 129#define     ATV_TOP_CR_CONT_CR_P_BG                                         0x4
 130#define     ATV_TOP_CR_CONT_CR_P_DK                                         0x4
 131#define     ATV_TOP_CR_CONT_CR_P_I                                          0x4
 132#define   ATV_TOP_CR_OVM_TH_MN                                              0xA0
 133#define   ATV_TOP_CR_OVM_TH_FM                                              0x0
 134#define   ATV_TOP_CR_OVM_TH_L                                               0xA0
 135#define   ATV_TOP_CR_OVM_TH_LP                                              0xA0
 136#define   ATV_TOP_CR_OVM_TH_BG                                              0xA0
 137#define   ATV_TOP_CR_OVM_TH_DK                                              0xA0
 138#define   ATV_TOP_CR_OVM_TH_I                                               0xA0
 139#define     ATV_TOP_EQU0_EQU_C0_FM                                          0x0
 140#define     ATV_TOP_EQU0_EQU_C0_L                                           0x3
 141#define     ATV_TOP_EQU0_EQU_C0_LP                                          0x3
 142#define     ATV_TOP_EQU0_EQU_C0_BG                                          0x7
 143#define     ATV_TOP_EQU0_EQU_C0_DK                                          0x0
 144#define     ATV_TOP_EQU0_EQU_C0_I                                           0x3
 145#define     ATV_TOP_EQU1_EQU_C1_FM                                          0x0
 146#define     ATV_TOP_EQU1_EQU_C1_L                                           0x1F6
 147#define     ATV_TOP_EQU1_EQU_C1_LP                                          0x1F6
 148#define     ATV_TOP_EQU1_EQU_C1_BG                                          0x197
 149#define     ATV_TOP_EQU1_EQU_C1_DK                                          0x198
 150#define     ATV_TOP_EQU1_EQU_C1_I                                           0x1F6
 151#define     ATV_TOP_EQU2_EQU_C2_FM                                          0x0
 152#define     ATV_TOP_EQU2_EQU_C2_L                                           0x28
 153#define     ATV_TOP_EQU2_EQU_C2_LP                                          0x28
 154#define     ATV_TOP_EQU2_EQU_C2_BG                                          0xC5
 155#define     ATV_TOP_EQU2_EQU_C2_DK                                          0xB0
 156#define     ATV_TOP_EQU2_EQU_C2_I                                           0x28
 157#define     ATV_TOP_EQU3_EQU_C3_FM                                          0x0
 158#define     ATV_TOP_EQU3_EQU_C3_L                                           0x192
 159#define     ATV_TOP_EQU3_EQU_C3_LP                                          0x192
 160#define     ATV_TOP_EQU3_EQU_C3_BG                                          0x12E
 161#define     ATV_TOP_EQU3_EQU_C3_DK                                          0x18E
 162#define     ATV_TOP_EQU3_EQU_C3_I                                           0x192
 163#define     ATV_TOP_STD_MODE_MN                                             0x0
 164#define     ATV_TOP_STD_MODE_FM                                             0x1
 165#define     ATV_TOP_STD_MODE_L                                              0x0
 166#define     ATV_TOP_STD_MODE_LP                                             0x0
 167#define     ATV_TOP_STD_MODE_BG                                             0x0
 168#define     ATV_TOP_STD_MODE_DK                                             0x0
 169#define     ATV_TOP_STD_MODE_I                                              0x0
 170#define     ATV_TOP_STD_VID_POL_MN                                          0x0
 171#define     ATV_TOP_STD_VID_POL_FM                                          0x0
 172#define     ATV_TOP_STD_VID_POL_L                                           0x2
 173#define     ATV_TOP_STD_VID_POL_LP                                          0x2
 174#define     ATV_TOP_STD_VID_POL_BG                                          0x0
 175#define     ATV_TOP_STD_VID_POL_DK                                          0x0
 176#define     ATV_TOP_STD_VID_POL_I                                           0x0
 177#define   ATV_TOP_VID_AMP_MN                                                0x380
 178#define   ATV_TOP_VID_AMP_FM                                                0x0
 179#define   ATV_TOP_VID_AMP_L                                                 0xF50
 180#define   ATV_TOP_VID_AMP_LP                                                0xF50
 181#define   ATV_TOP_VID_AMP_BG                                                0x380
 182#define   ATV_TOP_VID_AMP_DK                                                0x394
 183#define   ATV_TOP_VID_AMP_I                                                 0x3D8
 184#define   IQM_CF_OUT_ENA_OFDM__M                                            0x4
 185#define     IQM_FS_ADJ_SEL_B_QAM                                            0x1
 186#define     IQM_FS_ADJ_SEL_B_OFF                                            0x0
 187#define     IQM_FS_ADJ_SEL_B_VSB                                            0x2
 188#define     IQM_RC_ADJ_SEL_B_OFF                                            0x0
 189#define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
 190#define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
 191/*** END DJCOMBO patches to DRXJ registermap *********************************/
 192
 193#include "drx_driver_version.h"
 194
 195/* #define DRX_DEBUG */
 196#ifdef DRX_DEBUG
 197#include <stdio.h>
 198#endif
 199
 200/*-----------------------------------------------------------------------------
 201ENUMS
 202----------------------------------------------------------------------------*/
 203
 204/*-----------------------------------------------------------------------------
 205DEFINES
 206----------------------------------------------------------------------------*/
 207#ifndef DRXJ_WAKE_UP_KEY
 208#define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
 209#endif
 210
 211/*
 212* \def DRXJ_DEF_I2C_ADDR
 213* \brief Default I2C address of a demodulator instance.
 214*/
 215#define DRXJ_DEF_I2C_ADDR (0x52)
 216
 217/*
 218* \def DRXJ_DEF_DEMOD_DEV_ID
 219* \brief Default device identifier of a demodultor instance.
 220*/
 221#define DRXJ_DEF_DEMOD_DEV_ID      (1)
 222
 223/*
 224* \def DRXJ_SCAN_TIMEOUT
 225* \brief Timeout value for waiting on demod lock during channel scan (millisec).
 226*/
 227#define DRXJ_SCAN_TIMEOUT    1000
 228
 229/*
 230* \def HI_I2C_DELAY
 231* \brief HI timing delay for I2C timing (in nano seconds)
 232*
 233*  Used to compute HI_CFG_DIV
 234*/
 235#define HI_I2C_DELAY    42
 236
 237/*
 238* \def HI_I2C_BRIDGE_DELAY
 239* \brief HI timing delay for I2C timing (in nano seconds)
 240*
 241*  Used to compute HI_CFG_BDL
 242*/
 243#define HI_I2C_BRIDGE_DELAY   750
 244
 245/*
 246* \brief Time Window for MER and SER Measurement in Units of Segment duration.
 247*/
 248#define VSB_TOP_MEASUREMENT_PERIOD  64
 249#define SYMBOLS_PER_SEGMENT         832
 250
 251/*
 252* \brief bit rate and segment rate constants used for SER and BER.
 253*/
 254/* values taken from the QAM microcode */
 255#define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
 256#define DRXJ_QAM_SL_SIG_POWER_QPSK        32768
 257#define DRXJ_QAM_SL_SIG_POWER_QAM8        24576
 258#define DRXJ_QAM_SL_SIG_POWER_QAM16       40960
 259#define DRXJ_QAM_SL_SIG_POWER_QAM32       20480
 260#define DRXJ_QAM_SL_SIG_POWER_QAM64       43008
 261#define DRXJ_QAM_SL_SIG_POWER_QAM128      20992
 262#define DRXJ_QAM_SL_SIG_POWER_QAM256      43520
 263/*
 264* \brief Min supported symbolrates.
 265*/
 266#ifndef DRXJ_QAM_SYMBOLRATE_MIN
 267#define DRXJ_QAM_SYMBOLRATE_MIN          (520000)
 268#endif
 269
 270/*
 271* \brief Max supported symbolrates.
 272*/
 273#ifndef DRXJ_QAM_SYMBOLRATE_MAX
 274#define DRXJ_QAM_SYMBOLRATE_MAX         (7233000)
 275#endif
 276
 277/*
 278* \def DRXJ_QAM_MAX_WAITTIME
 279* \brief Maximal wait time for QAM auto constellation in ms
 280*/
 281#ifndef DRXJ_QAM_MAX_WAITTIME
 282#define DRXJ_QAM_MAX_WAITTIME 900
 283#endif
 284
 285#ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
 286#define DRXJ_QAM_FEC_LOCK_WAITTIME 150
 287#endif
 288
 289#ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
 290#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
 291#endif
 292
 293/*
 294* \def SCU status and results
 295* \brief SCU
 296*/
 297#define DRX_SCU_READY               0
 298#define DRXJ_MAX_WAITTIME           100 /* ms */
 299#define FEC_RS_MEASUREMENT_PERIOD   12894       /* 1 sec */
 300#define FEC_RS_MEASUREMENT_PRESCALE 1   /* n sec */
 301
 302/*
 303* \def DRX_AUD_MAX_DEVIATION
 304* \brief Needed for calculation of prescale feature in AUD
 305*/
 306#ifndef DRXJ_AUD_MAX_FM_DEVIATION
 307#define DRXJ_AUD_MAX_FM_DEVIATION  100  /* kHz */
 308#endif
 309
 310/*
 311* \brief Needed for calculation of NICAM prescale feature in AUD
 312*/
 313#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
 314#define DRXJ_AUD_MAX_NICAM_PRESCALE  (9)        /* dB */
 315#endif
 316
 317/*
 318* \brief Needed for calculation of NICAM prescale feature in AUD
 319*/
 320#ifndef DRXJ_AUD_MAX_WAITTIME
 321#define DRXJ_AUD_MAX_WAITTIME  250      /* ms */
 322#endif
 323
 324/* ATV config changed flags */
 325#define DRXJ_ATV_CHANGED_COEF          (0x00000001UL)
 326#define DRXJ_ATV_CHANGED_PEAK_FLT      (0x00000008UL)
 327#define DRXJ_ATV_CHANGED_NOISE_FLT     (0x00000010UL)
 328#define DRXJ_ATV_CHANGED_OUTPUT        (0x00000020UL)
 329#define DRXJ_ATV_CHANGED_SIF_ATT       (0x00000040UL)
 330
 331/* UIO define */
 332#define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
 333#define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
 334
 335/*
 336 * MICROCODE RELATED DEFINES
 337 */
 338
 339/* Magic word for checking correct Endianness of microcode data */
 340#define DRX_UCODE_MAGIC_WORD         ((((u16)'H')<<8)+((u16)'L'))
 341
 342/* CRC flag in ucode header, flags field. */
 343#define DRX_UCODE_CRC_FLAG           (0x0001)
 344
 345/*
 346 * Maximum size of buffer used to verify the microcode.
 347 * Must be an even number
 348 */
 349#define DRX_UCODE_MAX_BUF_SIZE       (DRXDAP_MAX_RCHUNKSIZE)
 350
 351#if DRX_UCODE_MAX_BUF_SIZE & 1
 352#error DRX_UCODE_MAX_BUF_SIZE must be an even number
 353#endif
 354
 355/*
 356 * Power mode macros
 357 */
 358
 359#define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
 360                                       (mode == DRX_POWER_MODE_10) || \
 361                                       (mode == DRX_POWER_MODE_11) || \
 362                                       (mode == DRX_POWER_MODE_12) || \
 363                                       (mode == DRX_POWER_MODE_13) || \
 364                                       (mode == DRX_POWER_MODE_14) || \
 365                                       (mode == DRX_POWER_MODE_15) || \
 366                                       (mode == DRX_POWER_MODE_16) || \
 367                                       (mode == DRX_POWER_DOWN))
 368
 369/* Pin safe mode macro */
 370#define DRXJ_PIN_SAFE_MODE 0x0000
 371/*============================================================================*/
 372/*=== GLOBAL VARIABLEs =======================================================*/
 373/*============================================================================*/
 374/*
 375*/
 376
 377/*
 378* \brief Temporary register definitions.
 379*        (register definitions that are not yet available in register master)
 380*/
 381
 382/*****************************************************************************/
 383/* Audio block 0x103 is write only. To avoid shadowing in driver accessing   */
 384/* RAM addresses directly. This must be READ ONLY to avoid problems.         */
 385/* Writing to the interface addresses are more than only writing the RAM     */
 386/* locations                                                                 */
 387/*****************************************************************************/
 388/*
 389* \brief RAM location of MODUS registers
 390*/
 391#define AUD_DEM_RAM_MODUS_HI__A              0x10204A3
 392#define AUD_DEM_RAM_MODUS_HI__M              0xF000
 393
 394#define AUD_DEM_RAM_MODUS_LO__A              0x10204A4
 395#define AUD_DEM_RAM_MODUS_LO__M              0x0FFF
 396
 397/*
 398* \brief RAM location of I2S config registers
 399*/
 400#define AUD_DEM_RAM_I2S_CONFIG1__A           0x10204B1
 401#define AUD_DEM_RAM_I2S_CONFIG2__A           0x10204B2
 402
 403/*
 404* \brief RAM location of DCO config registers
 405*/
 406#define AUD_DEM_RAM_DCO_B_HI__A              0x1020461
 407#define AUD_DEM_RAM_DCO_B_LO__A              0x1020462
 408#define AUD_DEM_RAM_DCO_A_HI__A              0x1020463
 409#define AUD_DEM_RAM_DCO_A_LO__A              0x1020464
 410
 411/*
 412* \brief RAM location of Threshold registers
 413*/
 414#define AUD_DEM_RAM_NICAM_THRSHLD__A         0x102045A
 415#define AUD_DEM_RAM_A2_THRSHLD__A            0x10204BB
 416#define AUD_DEM_RAM_BTSC_THRSHLD__A          0x10204A6
 417
 418/*
 419* \brief RAM location of Carrier Threshold registers
 420*/
 421#define AUD_DEM_RAM_CM_A_THRSHLD__A          0x10204AF
 422#define AUD_DEM_RAM_CM_B_THRSHLD__A          0x10204B0
 423
 424/*
 425* \brief FM Matrix register fix
 426*/
 427#ifdef AUD_DEM_WR_FM_MATRIX__A
 428#undef  AUD_DEM_WR_FM_MATRIX__A
 429#endif
 430#define AUD_DEM_WR_FM_MATRIX__A              0x105006F
 431
 432/*============================================================================*/
 433/*
 434* \brief Defines required for audio
 435*/
 436#define AUD_VOLUME_ZERO_DB                      115
 437#define AUD_VOLUME_DB_MIN                       -60
 438#define AUD_VOLUME_DB_MAX                       12
 439#define AUD_CARRIER_STRENGTH_QP_0DB             0x4000
 440#define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100   421
 441#define AUD_MAX_AVC_REF_LEVEL                   15
 442#define AUD_I2S_FREQUENCY_MAX                   48000UL
 443#define AUD_I2S_FREQUENCY_MIN                   12000UL
 444#define AUD_RDS_ARRAY_SIZE                      18
 445
 446/*
 447* \brief Needed for calculation of prescale feature in AUD
 448*/
 449#ifndef DRX_AUD_MAX_FM_DEVIATION
 450#define DRX_AUD_MAX_FM_DEVIATION  (100) /* kHz */
 451#endif
 452
 453/*
 454* \brief Needed for calculation of NICAM prescale feature in AUD
 455*/
 456#ifndef DRX_AUD_MAX_NICAM_PRESCALE
 457#define DRX_AUD_MAX_NICAM_PRESCALE  (9) /* dB */
 458#endif
 459
 460/*============================================================================*/
 461/* Values for I2S Master/Slave pin configurations */
 462#define SIO_PDR_I2S_CL_CFG_MODE__MASTER      0x0004
 463#define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER     0x0008
 464#define SIO_PDR_I2S_CL_CFG_MODE__SLAVE       0x0004
 465#define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE      0x0000
 466
 467#define SIO_PDR_I2S_DA_CFG_MODE__MASTER      0x0003
 468#define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER     0x0008
 469#define SIO_PDR_I2S_DA_CFG_MODE__SLAVE       0x0003
 470#define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE      0x0008
 471
 472#define SIO_PDR_I2S_WS_CFG_MODE__MASTER      0x0004
 473#define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER     0x0008
 474#define SIO_PDR_I2S_WS_CFG_MODE__SLAVE       0x0004
 475#define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE      0x0000
 476
 477/*============================================================================*/
 478/*=== REGISTER ACCESS MACROS =================================================*/
 479/*============================================================================*/
 480
 481/*
 482* This macro is used to create byte arrays for block writes.
 483* Block writes speed up I2C traffic between host and demod.
 484* The macro takes care of the required byte order in a 16 bits word.
 485* x -> lowbyte(x), highbyte(x)
 486*/
 487#define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
 488                       ((u8)((((u16)x)>>8)&0xFF))
 489/*
 490* This macro is used to convert byte array to 16 bit register value for block read.
 491* Block read speed up I2C traffic between host and demod.
 492* The macro takes care of the required byte order in a 16 bits word.
 493*/
 494#define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
 495
 496/*============================================================================*/
 497/*=== MISC DEFINES ===========================================================*/
 498/*============================================================================*/
 499
 500/*============================================================================*/
 501/*=== HI COMMAND RELATED DEFINES =============================================*/
 502/*============================================================================*/
 503
 504/*
 505* \brief General maximum number of retries for ucode command interfaces
 506*/
 507#define DRXJ_MAX_RETRIES (100)
 508
 509/*============================================================================*/
 510/*=== STANDARD RELATED MACROS ================================================*/
 511/*============================================================================*/
 512
 513#define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
 514                               (std == DRX_STANDARD_PAL_SECAM_DK) || \
 515                               (std == DRX_STANDARD_PAL_SECAM_I) || \
 516                               (std == DRX_STANDARD_PAL_SECAM_L) || \
 517                               (std == DRX_STANDARD_PAL_SECAM_LP) || \
 518                               (std == DRX_STANDARD_NTSC) || \
 519                               (std == DRX_STANDARD_FM))
 520
 521#define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
 522                               (std == DRX_STANDARD_ITU_B) || \
 523                               (std == DRX_STANDARD_ITU_C) || \
 524                               (std == DRX_STANDARD_ITU_D))
 525
 526/*-----------------------------------------------------------------------------
 527GLOBAL VARIABLES
 528----------------------------------------------------------------------------*/
 529/*
 530 * DRXJ DAP structures
 531 */
 532
 533static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
 534                                      u32 addr,
 535                                      u16 datasize,
 536                                      u8 *data, u32 flags);
 537
 538
 539static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
 540                                                 u32 waddr,
 541                                                 u32 raddr,
 542                                                 u16 wdata, u16 *rdata);
 543
 544static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
 545                                      u32 addr,
 546                                      u16 *data, u32 flags);
 547
 548static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
 549                                      u32 addr,
 550                                      u32 *data, u32 flags);
 551
 552static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
 553                                       u32 addr,
 554                                       u16 datasize,
 555                                       u8 *data, u32 flags);
 556
 557static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
 558                                       u32 addr,
 559                                       u16 data, u32 flags);
 560
 561static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
 562                                       u32 addr,
 563                                       u32 data, u32 flags);
 564
 565static struct drxj_data drxj_data_g = {
 566        false,                  /* has_lna : true if LNA (aka PGA) present      */
 567        false,                  /* has_oob : true if OOB supported              */
 568        false,                  /* has_ntsc: true if NTSC supported             */
 569        false,                  /* has_btsc: true if BTSC supported             */
 570        false,                  /* has_smatx: true if SMA_TX pin is available   */
 571        false,                  /* has_smarx: true if SMA_RX pin is available   */
 572        false,                  /* has_gpio : true if GPIO pin is available     */
 573        false,                  /* has_irqn : true if IRQN pin is available     */
 574        0,                      /* mfx A1/A2/A... */
 575
 576        /* tuner settings */
 577        false,                  /* tuner mirrors RF signal    */
 578        /* standard/channel settings */
 579        DRX_STANDARD_UNKNOWN,   /* current standard           */
 580        DRX_CONSTELLATION_AUTO, /* constellation              */
 581        0,                      /* frequency in KHz           */
 582        DRX_BANDWIDTH_UNKNOWN,  /* curr_bandwidth              */
 583        DRX_MIRROR_NO,          /* mirror                     */
 584
 585        /* signal quality information: */
 586        /* default values taken from the QAM Programming guide */
 587        /*   fec_bits_desired should not be less than 4000000    */
 588        4000000,                /* fec_bits_desired    */
 589        5,                      /* fec_vd_plen         */
 590        4,                      /* qam_vd_prescale     */
 591        0xFFFF,                 /* qamVDPeriod       */
 592        204 * 8,                /* fec_rs_plen annex A */
 593        1,                      /* fec_rs_prescale     */
 594        FEC_RS_MEASUREMENT_PERIOD,      /* fec_rs_period     */
 595        true,                   /* reset_pkt_err_acc    */
 596        0,                      /* pkt_err_acc_start    */
 597
 598        /* HI configuration */
 599        0,                      /* hi_cfg_timing_div    */
 600        0,                      /* hi_cfg_bridge_delay  */
 601        0,                      /* hi_cfg_wake_up_key    */
 602        0,                      /* hi_cfg_ctrl         */
 603        0,                      /* HICfgTimeout      */
 604        /* UIO configuration */
 605        DRX_UIO_MODE_DISABLE,   /* uio_sma_rx_mode      */
 606        DRX_UIO_MODE_DISABLE,   /* uio_sma_tx_mode      */
 607        DRX_UIO_MODE_DISABLE,   /* uioASELMode       */
 608        DRX_UIO_MODE_DISABLE,   /* uio_irqn_mode       */
 609        /* FS setting */
 610        0UL,                    /* iqm_fs_rate_ofs      */
 611        false,                  /* pos_image          */
 612        /* RC setting */
 613        0UL,                    /* iqm_rc_rate_ofs      */
 614        /* AUD information */
 615/*   false,                  * flagSetAUDdone    */
 616/*   false,                  * detectedRDS       */
 617/*   true,                   * flagASDRequest    */
 618/*   false,                  * flagHDevClear     */
 619/*   false,                  * flagHDevSet       */
 620/*   (u16) 0xFFF,          * rdsLastCount      */
 621
 622        /* ATV configuration */
 623        0UL,                    /* flags cfg changes */
 624        /* shadow of ATV_TOP_EQU0__A */
 625        {-5,
 626         ATV_TOP_EQU0_EQU_C0_FM,
 627         ATV_TOP_EQU0_EQU_C0_L,
 628         ATV_TOP_EQU0_EQU_C0_LP,
 629         ATV_TOP_EQU0_EQU_C0_BG,
 630         ATV_TOP_EQU0_EQU_C0_DK,
 631         ATV_TOP_EQU0_EQU_C0_I},
 632        /* shadow of ATV_TOP_EQU1__A */
 633        {-50,
 634         ATV_TOP_EQU1_EQU_C1_FM,
 635         ATV_TOP_EQU1_EQU_C1_L,
 636         ATV_TOP_EQU1_EQU_C1_LP,
 637         ATV_TOP_EQU1_EQU_C1_BG,
 638         ATV_TOP_EQU1_EQU_C1_DK,
 639         ATV_TOP_EQU1_EQU_C1_I},
 640        /* shadow of ATV_TOP_EQU2__A */
 641        {210,
 642         ATV_TOP_EQU2_EQU_C2_FM,
 643         ATV_TOP_EQU2_EQU_C2_L,
 644         ATV_TOP_EQU2_EQU_C2_LP,
 645         ATV_TOP_EQU2_EQU_C2_BG,
 646         ATV_TOP_EQU2_EQU_C2_DK,
 647         ATV_TOP_EQU2_EQU_C2_I},
 648        /* shadow of ATV_TOP_EQU3__A */
 649        {-160,
 650         ATV_TOP_EQU3_EQU_C3_FM,
 651         ATV_TOP_EQU3_EQU_C3_L,
 652         ATV_TOP_EQU3_EQU_C3_LP,
 653         ATV_TOP_EQU3_EQU_C3_BG,
 654         ATV_TOP_EQU3_EQU_C3_DK,
 655         ATV_TOP_EQU3_EQU_C3_I},
 656        false,                  /* flag: true=bypass             */
 657        ATV_TOP_VID_PEAK__PRE,  /* shadow of ATV_TOP_VID_PEAK__A */
 658        ATV_TOP_NOISE_TH__PRE,  /* shadow of ATV_TOP_NOISE_TH__A */
 659        true,                   /* flag CVBS output enable       */
 660        false,                  /* flag SIF output enable        */
 661        DRXJ_SIF_ATTENUATION_0DB,       /* current SIF att setting       */
 662        {                       /* qam_rf_agc_cfg */
 663         DRX_STANDARD_ITU_B,    /* standard            */
 664         DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
 665         0,                     /* output_level         */
 666         0,                     /* min_output_level      */
 667         0xFFFF,                /* max_output_level      */
 668         0x0000,                /* speed               */
 669         0x0000,                /* top                 */
 670         0x0000                 /* c.o.c.              */
 671         },
 672        {                       /* qam_if_agc_cfg */
 673         DRX_STANDARD_ITU_B,    /* standard            */
 674         DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
 675         0,                     /* output_level         */
 676         0,                     /* min_output_level      */
 677         0xFFFF,                /* max_output_level      */
 678         0x0000,                /* speed               */
 679         0x0000,                /* top    (don't care) */
 680         0x0000                 /* c.o.c. (don't care) */
 681         },
 682        {                       /* vsb_rf_agc_cfg */
 683         DRX_STANDARD_8VSB,     /* standard       */
 684         DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
 685         0,                     /* output_level    */
 686         0,                     /* min_output_level */
 687         0xFFFF,                /* max_output_level */
 688         0x0000,                /* speed          */
 689         0x0000,                /* top    (don't care) */
 690         0x0000                 /* c.o.c. (don't care) */
 691         },
 692        {                       /* vsb_if_agc_cfg */
 693         DRX_STANDARD_8VSB,     /* standard       */
 694         DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
 695         0,                     /* output_level    */
 696         0,                     /* min_output_level */
 697         0xFFFF,                /* max_output_level */
 698         0x0000,                /* speed          */
 699         0x0000,                /* top    (don't care) */
 700         0x0000                 /* c.o.c. (don't care) */
 701         },
 702        0,                      /* qam_pga_cfg */
 703        0,                      /* vsb_pga_cfg */
 704        {                       /* qam_pre_saw_cfg */
 705         DRX_STANDARD_ITU_B,    /* standard  */
 706         0,                     /* reference */
 707         false                  /* use_pre_saw */
 708         },
 709        {                       /* vsb_pre_saw_cfg */
 710         DRX_STANDARD_8VSB,     /* standard  */
 711         0,                     /* reference */
 712         false                  /* use_pre_saw */
 713         },
 714
 715        /* Version information */
 716#ifndef _CH_
 717        {
 718         "01234567890",         /* human readable version microcode             */
 719         "01234567890"          /* human readable version device specific code  */
 720         },
 721        {
 722         {                      /* struct drx_version for microcode                   */
 723          DRX_MODULE_UNKNOWN,
 724          (char *)(NULL),
 725          0,
 726          0,
 727          0,
 728          (char *)(NULL)
 729          },
 730         {                      /* struct drx_version for device specific code */
 731          DRX_MODULE_UNKNOWN,
 732          (char *)(NULL),
 733          0,
 734          0,
 735          0,
 736          (char *)(NULL)
 737          }
 738         },
 739        {
 740         {                      /* struct drx_version_list for microcode */
 741          (struct drx_version *) (NULL),
 742          (struct drx_version_list *) (NULL)
 743          },
 744         {                      /* struct drx_version_list for device specific code */
 745          (struct drx_version *) (NULL),
 746          (struct drx_version_list *) (NULL)
 747          }
 748         },
 749#endif
 750        false,                  /* smart_ant_inverted */
 751        /* Tracking filter setting for OOB  */
 752        {
 753         12000,
 754         9300,
 755         6600,
 756         5280,
 757         3700,
 758         3000,
 759         2000,
 760         0},
 761        false,                  /* oob_power_on           */
 762        0,                      /* mpeg_ts_static_bitrate  */
 763        false,                  /* disable_te_ihandling   */
 764        false,                  /* bit_reverse_mpeg_outout */
 765        DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,        /* mpeg_output_clock_rate */
 766        DRXJ_MPEG_START_WIDTH_1CLKCYC,  /* mpeg_start_width */
 767
 768        /* Pre SAW & Agc configuration for ATV */
 769        {
 770         DRX_STANDARD_NTSC,     /* standard     */
 771         7,                     /* reference    */
 772         true                   /* use_pre_saw    */
 773         },
 774        {                       /* ATV RF-AGC */
 775         DRX_STANDARD_NTSC,     /* standard              */
 776         DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
 777         0,                     /* output_level           */
 778         0,                     /* min_output_level (d.c.) */
 779         0,                     /* max_output_level (d.c.) */
 780         3,                     /* speed                 */
 781         9500,                  /* top                   */
 782         4000                   /* cut-off current       */
 783         },
 784        {                       /* ATV IF-AGC */
 785         DRX_STANDARD_NTSC,     /* standard              */
 786         DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
 787         0,                     /* output_level           */
 788         0,                     /* min_output_level (d.c.) */
 789         0,                     /* max_output_level (d.c.) */
 790         3,                     /* speed                 */
 791         2400,                  /* top                   */
 792         0                      /* c.o.c.         (d.c.) */
 793         },
 794        140,                    /* ATV PGA config */
 795        0,                      /* curr_symbol_rate */
 796
 797        false,                  /* pdr_safe_mode     */
 798        SIO_PDR_GPIO_CFG__PRE,  /* pdr_safe_restore_val_gpio  */
 799        SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
 800        SIO_PDR_SMA_RX_CFG__PRE,        /* pdr_safe_restore_val_sma_rx */
 801        SIO_PDR_SMA_TX_CFG__PRE,        /* pdr_safe_restore_val_sma_tx */
 802
 803        4,                      /* oob_pre_saw            */
 804        DRXJ_OOB_LO_POW_MINUS10DB,      /* oob_lo_pow             */
 805        {
 806         false                  /* aud_data, only first member */
 807         },
 808};
 809
 810/*
 811* \var drxj_default_addr_g
 812* \brief Default I2C address and device identifier.
 813*/
 814static struct i2c_device_addr drxj_default_addr_g = {
 815        DRXJ_DEF_I2C_ADDR,      /* i2c address */
 816        DRXJ_DEF_DEMOD_DEV_ID   /* device id */
 817};
 818
 819/*
 820* \var drxj_default_comm_attr_g
 821* \brief Default common attributes of a drxj demodulator instance.
 822*/
 823static struct drx_common_attr drxj_default_comm_attr_g = {
 824        NULL,                   /* ucode file           */
 825        true,                   /* ucode verify switch  */
 826        {0},                    /* version record       */
 827
 828        44000,                  /* IF in kHz in case no tuner instance is used  */
 829        (151875 - 0),           /* system clock frequency in kHz                */
 830        0,                      /* oscillator frequency kHz                     */
 831        0,                      /* oscillator deviation in ppm, signed          */
 832        false,                  /* If true mirror frequency spectrum            */
 833        {
 834         /* MPEG output configuration */
 835         true,                  /* If true, enable MPEG output   */
 836         false,                 /* If true, insert RS byte       */
 837         false,                 /* If true, parallel out otherwise serial */
 838         false,                 /* If true, invert DATA signals  */
 839         false,                 /* If true, invert ERR signal    */
 840         false,                 /* If true, invert STR signals   */
 841         false,                 /* If true, invert VAL signals   */
 842         false,                 /* If true, invert CLK signals   */
 843         true,                  /* If true, static MPEG clockrate will
 844                                   be used, otherwise clockrate will
 845                                   adapt to the bitrate of the TS */
 846         19392658UL,            /* Maximum bitrate in b/s in case
 847                                   static clockrate is selected */
 848         DRX_MPEG_STR_WIDTH_1   /* MPEG Start width in clock cycles */
 849         },
 850        /* Initilisations below can be omitted, they require no user input and
 851           are initially 0, NULL or false. The compiler will initialize them to these
 852           values when omitted.  */
 853        false,                  /* is_opened */
 854
 855        /* SCAN */
 856        NULL,                   /* no scan params yet               */
 857        0,                      /* current scan index               */
 858        0,                      /* next scan frequency              */
 859        false,                  /* scan ready flag                  */
 860        0,                      /* max channels to scan             */
 861        0,                      /* nr of channels scanned           */
 862        NULL,                   /* default scan function            */
 863        NULL,                   /* default context pointer          */
 864        0,                      /* millisec to wait for demod lock  */
 865        DRXJ_DEMOD_LOCK,        /* desired lock               */
 866        false,
 867
 868        /* Power management */
 869        DRX_POWER_UP,
 870
 871        /* Tuner */
 872        1,                      /* nr of I2C port to which tuner is    */
 873        0L,                     /* minimum RF input frequency, in kHz  */
 874        0L,                     /* maximum RF input frequency, in kHz  */
 875        false,                  /* Rf Agc Polarity                     */
 876        false,                  /* If Agc Polarity                     */
 877        false,                  /* tuner slow mode                     */
 878
 879        {                       /* current channel (all 0)             */
 880         0UL                    /* channel.frequency */
 881         },
 882        DRX_STANDARD_UNKNOWN,   /* current standard */
 883        DRX_STANDARD_UNKNOWN,   /* previous standard */
 884        DRX_STANDARD_UNKNOWN,   /* di_cache_standard   */
 885        false,                  /* use_bootloader */
 886        0UL,                    /* capabilities */
 887        0                       /* mfx */
 888};
 889
 890/*
 891* \var drxj_default_demod_g
 892* \brief Default drxj demodulator instance.
 893*/
 894static struct drx_demod_instance drxj_default_demod_g = {
 895        &drxj_default_addr_g,   /* i2c address & device id */
 896        &drxj_default_comm_attr_g,      /* demod common attributes */
 897        &drxj_data_g            /* demod device specific attributes */
 898};
 899
 900/*
 901* \brief Default audio data structure for DRK demodulator instance.
 902*
 903* This structure is DRXK specific.
 904*
 905*/
 906static struct drx_aud_data drxj_default_aud_data_g = {
 907        false,                  /* audio_is_active */
 908        DRX_AUD_STANDARD_AUTO,  /* audio_standard  */
 909
 910        /* i2sdata */
 911        {
 912         false,                 /* output_enable   */
 913         48000,                 /* frequency      */
 914         DRX_I2S_MODE_MASTER,   /* mode           */
 915         DRX_I2S_WORDLENGTH_32, /* word_length     */
 916         DRX_I2S_POLARITY_RIGHT,        /* polarity       */
 917         DRX_I2S_FORMAT_WS_WITH_DATA    /* format         */
 918         },
 919        /* volume            */
 920        {
 921         true,                  /* mute;          */
 922         0,                     /* volume         */
 923         DRX_AUD_AVC_OFF,       /* avc_mode        */
 924         0,                     /* avc_ref_level    */
 925         DRX_AUD_AVC_MAX_GAIN_12DB,     /* avc_max_gain     */
 926         DRX_AUD_AVC_MAX_ATTEN_24DB,    /* avc_max_atten    */
 927         0,                     /* strength_left   */
 928         0                      /* strength_right  */
 929         },
 930        DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
 931        /*  ass_thresholds */
 932        {
 933         440,                   /* A2    */
 934         12,                    /* BTSC  */
 935         700,                   /* NICAM */
 936         },
 937        /* carrier */
 938        {
 939         /* a */
 940         {
 941          42,                   /* thres */
 942          DRX_NO_CARRIER_NOISE, /* opt   */
 943          0,                    /* shift */
 944          0                     /* dco   */
 945          },
 946         /* b */
 947         {
 948          42,                   /* thres */
 949          DRX_NO_CARRIER_MUTE,  /* opt   */
 950          0,                    /* shift */
 951          0                     /* dco   */
 952          },
 953
 954         },
 955        /* mixer */
 956        {
 957         DRX_AUD_SRC_STEREO_OR_A,       /* source_i2s */
 958         DRX_AUD_I2S_MATRIX_STEREO,     /* matrix_i2s */
 959         DRX_AUD_FM_MATRIX_SOUND_A      /* matrix_fm  */
 960         },
 961        DRX_AUD_DEVIATION_NORMAL,       /* deviation */
 962        DRX_AUD_AVSYNC_OFF,     /* av_sync */
 963
 964        /* prescale */
 965        {
 966         DRX_AUD_MAX_FM_DEVIATION,      /* fm_deviation */
 967         DRX_AUD_MAX_NICAM_PRESCALE     /* nicam_gain */
 968         },
 969        DRX_AUD_FM_DEEMPH_75US, /* deemph */
 970        DRX_BTSC_STEREO,        /* btsc_detect */
 971        0,                      /* rds_data_counter */
 972        false                   /* rds_data_present */
 973};
 974
 975/*-----------------------------------------------------------------------------
 976STRUCTURES
 977----------------------------------------------------------------------------*/
 978struct drxjeq_stat {
 979        u16 eq_mse;
 980        u8 eq_mode;
 981        u8 eq_ctrl;
 982        u8 eq_stat;
 983};
 984
 985/* HI command */
 986struct drxj_hi_cmd {
 987        u16 cmd;
 988        u16 param1;
 989        u16 param2;
 990        u16 param3;
 991        u16 param4;
 992        u16 param5;
 993        u16 param6;
 994};
 995
 996/*============================================================================*/
 997/*=== MICROCODE RELATED STRUCTURES ===========================================*/
 998/*============================================================================*/
 999
1000/*
1001 * struct drxu_code_block_hdr - Structure of the microcode block headers
1002 *
1003 * @addr:       Destination address of the data in this block
1004 * @size:       Size of the block data following this header counted in
1005 *              16 bits words
1006 * @CRC:        CRC value of the data block, only valid if CRC flag is
1007 *              set.
1008 */
1009struct drxu_code_block_hdr {
1010        u32 addr;
1011        u16 size;
1012        u16 flags;
1013        u16 CRC;
1014};
1015
1016/*-----------------------------------------------------------------------------
1017FUNCTIONS
1018----------------------------------------------------------------------------*/
1019/* Some prototypes */
1020static int
1021hi_command(struct i2c_device_addr *dev_addr,
1022           const struct drxj_hi_cmd *cmd, u16 *result);
1023
1024static int
1025ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1026
1027static int
1028ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1029
1030static int power_down_aud(struct drx_demod_instance *demod);
1031
1032static int
1033ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1034
1035static int
1036ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1037
1038/*============================================================================*/
1039/*============================================================================*/
1040/*==                          HELPER FUNCTIONS                              ==*/
1041/*============================================================================*/
1042/*============================================================================*/
1043
1044
1045/*============================================================================*/
1046
1047/*
1048* \fn u32 frac28(u32 N, u32 D)
1049* \brief Compute: (1<<28)*N/D
1050* \param N 32 bits
1051* \param D 32 bits
1052* \return (1<<28)*N/D
1053* This function is used to avoid floating-point calculations as they may
1054* not be present on the target platform.
1055
1056* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1057* fraction used for setting the Frequency Shifter registers.
1058* N and D can hold numbers up to width: 28-bits.
1059* The 4 bits integer part and the 28 bits fractional part are calculated.
1060
1061* Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1062
1063* N: 0...(1<<28)-1 = 268435454
1064* D: 0...(1<<28)-1
1065* Q: 0...(1<<32)-1
1066*/
1067static u32 frac28(u32 N, u32 D)
1068{
1069        int i = 0;
1070        u32 Q1 = 0;
1071        u32 R0 = 0;
1072
1073        R0 = (N % D) << 4;      /* 32-28 == 4 shifts possible at max */
1074        Q1 = N / D;             /* integer part, only the 4 least significant bits
1075                                   will be visible in the result */
1076
1077        /* division using radix 16, 7 nibbles in the result */
1078        for (i = 0; i < 7; i++) {
1079                Q1 = (Q1 << 4) | R0 / D;
1080                R0 = (R0 % D) << 4;
1081        }
1082        /* rounding */
1083        if ((R0 >> 3) >= D)
1084                Q1++;
1085
1086        return Q1;
1087}
1088
1089/*
1090* \fn u32 log1_times100( u32 x)
1091* \brief Compute: 100*log10(x)
1092* \param x 32 bits
1093* \return 100*log10(x)
1094*
1095* 100*log10(x)
1096* = 100*(log2(x)/log2(10)))
1097* = (100*(2^15)*log2(x))/((2^15)*log2(10))
1098* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1099* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1100* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1101*
1102* where y = 2^k and 1<= (x/y) < 2
1103*/
1104
1105static u32 log1_times100(u32 x)
1106{
1107        static const u8 scale = 15;
1108        static const u8 index_width = 5;
1109        /*
1110           log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1111           0 <= n < ((1<<INDEXWIDTH)+1)
1112         */
1113
1114        static const u32 log2lut[] = {
1115                0,              /* 0.000000 */
1116                290941,         /* 290941.300628 */
1117                573196,         /* 573196.476418 */
1118                847269,         /* 847269.179851 */
1119                1113620,        /* 1113620.489452 */
1120                1372674,        /* 1372673.576986 */
1121                1624818,        /* 1624817.752104 */
1122                1870412,        /* 1870411.981536 */
1123                2109788,        /* 2109787.962654 */
1124                2343253,        /* 2343252.817465 */
1125                2571091,        /* 2571091.461923 */
1126                2793569,        /* 2793568.696416 */
1127                3010931,        /* 3010931.055901 */
1128                3223408,        /* 3223408.452106 */
1129                3431216,        /* 3431215.635215 */
1130                3634553,        /* 3634553.498355 */
1131                3833610,        /* 3833610.244726 */
1132                4028562,        /* 4028562.434393 */
1133                4219576,        /* 4219575.925308 */
1134                4406807,        /* 4406806.721144 */
1135                4590402,        /* 4590401.736809 */
1136                4770499,        /* 4770499.491025 */
1137                4947231,        /* 4947230.734179 */
1138                5120719,        /* 5120719.018555 */
1139                5291081,        /* 5291081.217197 */
1140                5458428,        /* 5458427.996830 */
1141                5622864,        /* 5622864.249668 */
1142                5784489,        /* 5784489.488298 */
1143                5943398,        /* 5943398.207380 */
1144                6099680,        /* 6099680.215452 */
1145                6253421,        /* 6253420.939751 */
1146                6404702,        /* 6404701.706649 */
1147                6553600,        /* 6553600.000000 */
1148        };
1149
1150        u8 i = 0;
1151        u32 y = 0;
1152        u32 d = 0;
1153        u32 k = 0;
1154        u32 r = 0;
1155
1156        if (x == 0)
1157                return 0;
1158
1159        /* Scale x (normalize) */
1160        /* computing y in log(x/y) = log(x) - log(y) */
1161        if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1162                for (k = scale; k > 0; k--) {
1163                        if (x & (((u32) 1) << scale))
1164                                break;
1165                        x <<= 1;
1166                }
1167        } else {
1168                for (k = scale; k < 31; k++) {
1169                        if ((x & (((u32) (-1)) << (scale + 1))) == 0)
1170                                break;
1171                        x >>= 1;
1172                }
1173        }
1174        /*
1175           Now x has binary point between bit[scale] and bit[scale-1]
1176           and 1.0 <= x < 2.0 */
1177
1178        /* correction for division: log(x) = log(x/y)+log(y) */
1179        y = k * ((((u32) 1) << scale) * 200);
1180
1181        /* remove integer part */
1182        x &= ((((u32) 1) << scale) - 1);
1183        /* get index */
1184        i = (u8) (x >> (scale - index_width));
1185        /* compute delta (x-a) */
1186        d = x & ((((u32) 1) << (scale - index_width)) - 1);
1187        /* compute log, multiplication ( d* (.. )) must be within range ! */
1188        y += log2lut[i] +
1189            ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1190        /* Conver to log10() */
1191        y /= 108853;            /* (log2(10) << scale) */
1192        r = (y >> 1);
1193        /* rounding */
1194        if (y & ((u32)1))
1195                r++;
1196
1197        return r;
1198
1199}
1200
1201/*
1202* \fn u32 frac_times1e6( u16 N, u32 D)
1203* \brief Compute: (N/D) * 1000000.
1204* \param N nominator 16-bits.
1205* \param D denominator 32-bits.
1206* \return u32
1207* \retval ((N/D) * 1000000), 32 bits
1208*
1209* No check on D=0!
1210*/
1211static u32 frac_times1e6(u32 N, u32 D)
1212{
1213        u32 remainder = 0;
1214        u32 frac = 0;
1215
1216        /*
1217           frac = (N * 1000000) / D
1218           To let it fit in a 32 bits computation:
1219           frac = (N * (1000000 >> 4)) / (D >> 4)
1220           This would result in a problem in case D < 16 (div by 0).
1221           So we do it more elaborate as shown below.
1222         */
1223        frac = (((u32) N) * (1000000 >> 4)) / D;
1224        frac <<= 4;
1225        remainder = (((u32) N) * (1000000 >> 4)) % D;
1226        remainder <<= 4;
1227        frac += remainder / D;
1228        remainder = remainder % D;
1229        if ((remainder * 2) > D)
1230                frac++;
1231
1232        return frac;
1233}
1234
1235/*============================================================================*/
1236
1237
1238/*
1239* \brief Values for NICAM prescaler gain. Computed from dB to integer
1240*        and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1241*
1242*/
1243#if 0
1244/* Currently, unused as we lack support for analog TV */
1245static const u16 nicam_presc_table_val[43] = {
1246        1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1247        5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1248        18, 20, 23, 25, 28, 32, 36, 40, 45,
1249        51, 57, 64, 71, 80, 90, 101, 113, 127
1250};
1251#endif
1252
1253/*============================================================================*/
1254/*==                        END HELPER FUNCTIONS                            ==*/
1255/*============================================================================*/
1256
1257/*============================================================================*/
1258/*============================================================================*/
1259/*==                      DRXJ DAP FUNCTIONS                                ==*/
1260/*============================================================================*/
1261/*============================================================================*/
1262
1263/*
1264   This layer takes care of some device specific register access protocols:
1265   -conversion to short address format
1266   -access to audio block
1267   This layer is placed between the drx_dap_fasi and the rest of the drxj
1268   specific implementation. This layer can use address map knowledge whereas
1269   dap_fasi may not use memory map knowledge.
1270
1271   * For audio currently only 16 bits read and write register access is
1272     supported. More is not needed. RMW and 32 or 8 bit access on audio
1273     registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1274     single/multi master) will be ignored.
1275
1276   TODO: check ignoring single/multimaster is ok for AUD access ?
1277*/
1278
1279#define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1280#define DRXJ_DAP_AUDTRIF_TIMEOUT 80     /* millisec */
1281/*============================================================================*/
1282
1283/*
1284* \fn bool is_handled_by_aud_tr_if( u32 addr )
1285* \brief Check if this address is handled by the audio token ring interface.
1286* \param addr
1287* \return bool
1288* \retval true  Yes, handled by audio token ring interface
1289* \retval false No, not handled by audio token ring interface
1290*
1291*/
1292static
1293bool is_handled_by_aud_tr_if(u32 addr)
1294{
1295        bool retval = false;
1296
1297        if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1298            (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1299            (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1300                retval = true;
1301        }
1302
1303        return retval;
1304}
1305
1306/*============================================================================*/
1307
1308int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
1309                                 u16 w_count,
1310                                 u8 *wData,
1311                                 struct i2c_device_addr *r_dev_addr,
1312                                 u16 r_count, u8 *r_data)
1313{
1314        struct drx39xxj_state *state;
1315        struct i2c_msg msg[2];
1316        unsigned int num_msgs;
1317
1318        if (w_dev_addr == NULL) {
1319                /* Read only */
1320                state = r_dev_addr->user_data;
1321                msg[0].addr = r_dev_addr->i2c_addr >> 1;
1322                msg[0].flags = I2C_M_RD;
1323                msg[0].buf = r_data;
1324                msg[0].len = r_count;
1325                num_msgs = 1;
1326        } else if (r_dev_addr == NULL) {
1327                /* Write only */
1328                state = w_dev_addr->user_data;
1329                msg[0].addr = w_dev_addr->i2c_addr >> 1;
1330                msg[0].flags = 0;
1331                msg[0].buf = wData;
1332                msg[0].len = w_count;
1333                num_msgs = 1;
1334        } else {
1335                /* Both write and read */
1336                state = w_dev_addr->user_data;
1337                msg[0].addr = w_dev_addr->i2c_addr >> 1;
1338                msg[0].flags = 0;
1339                msg[0].buf = wData;
1340                msg[0].len = w_count;
1341                msg[1].addr = r_dev_addr->i2c_addr >> 1;
1342                msg[1].flags = I2C_M_RD;
1343                msg[1].buf = r_data;
1344                msg[1].len = r_count;
1345                num_msgs = 2;
1346        }
1347
1348        if (state->i2c == NULL) {
1349                pr_err("i2c was zero, aborting\n");
1350                return 0;
1351        }
1352        if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
1353                pr_warn("drx3933: I2C write/read failed\n");
1354                return -EREMOTEIO;
1355        }
1356
1357#ifdef DJH_DEBUG
1358        if (w_dev_addr == NULL || r_dev_addr == NULL)
1359                return 0;
1360
1361        state = w_dev_addr->user_data;
1362
1363        if (state->i2c == NULL)
1364                return 0;
1365
1366        msg[0].addr = w_dev_addr->i2c_addr;
1367        msg[0].flags = 0;
1368        msg[0].buf = wData;
1369        msg[0].len = w_count;
1370        msg[1].addr = r_dev_addr->i2c_addr;
1371        msg[1].flags = I2C_M_RD;
1372        msg[1].buf = r_data;
1373        msg[1].len = r_count;
1374        num_msgs = 2;
1375
1376        pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
1377               w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
1378
1379        if (i2c_transfer(state->i2c, msg, 2) != 2) {
1380                pr_warn("drx3933: I2C write/read failed\n");
1381                return -EREMOTEIO;
1382        }
1383#endif
1384        return 0;
1385}
1386
1387/*============================================================================*/
1388
1389/*****************************
1390*
1391* int drxdap_fasi_read_block (
1392*      struct i2c_device_addr *dev_addr,      -- address of I2C device
1393*      u32 addr,         -- address of chip register/memory
1394*      u16            datasize,     -- number of bytes to read
1395*      u8 *data,         -- data to receive
1396*      u32 flags)        -- special device flags
1397*
1398* Read block data from chip address. Because the chip is word oriented,
1399* the number of bytes to read must be even.
1400*
1401* Make sure that the buffer to receive the data is large enough.
1402*
1403* Although this function expects an even number of bytes, it is still byte
1404* oriented, and the data read back is NOT translated to the endianness of
1405* the target platform.
1406*
1407* Output:
1408* - 0     if reading was successful
1409*                  in that case: data read is in *data.
1410* - -EIO  if anything went wrong
1411*
1412******************************/
1413
1414static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
1415                                         u32 addr,
1416                                         u16 datasize,
1417                                         u8 *data, u32 flags)
1418{
1419        u8 buf[4];
1420        u16 bufx;
1421        int rc;
1422        u16 overhead_size = 0;
1423
1424        /* Check parameters ******************************************************* */
1425        if (dev_addr == NULL)
1426                return -EINVAL;
1427
1428        overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1429            (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1430
1431        if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1432            ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1433             DRXDAP_FASI_LONG_FORMAT(addr)) ||
1434            (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1435            ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
1436                return -EINVAL;
1437        }
1438
1439        /* ReadModifyWrite & mode flag bits are not allowed */
1440        flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
1441#if DRXDAP_SINGLE_MASTER
1442        flags |= DRXDAP_FASI_SINGLE_MASTER;
1443#endif
1444
1445        /* Read block from I2C **************************************************** */
1446        do {
1447                u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
1448                              datasize : DRXDAP_MAX_RCHUNKSIZE);
1449
1450                bufx = 0;
1451
1452                addr &= ~DRXDAP_FASI_FLAGS;
1453                addr |= flags;
1454
1455#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1456                /* short format address preferred but long format otherwise */
1457                if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1458#endif
1459#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1460                        buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1461                        buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1462                        buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1463                        buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1464#endif
1465#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1466                } else {
1467#endif
1468#if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
1469                        buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1470                        buf[bufx++] =
1471                            (u8) (((addr >> 16) & 0x0F) |
1472                                    ((addr >> 18) & 0xF0));
1473#endif
1474#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1475                }
1476#endif
1477
1478#if DRXDAP_SINGLE_MASTER
1479                /*
1480                 * In single master mode, split the read and write actions.
1481                 * No special action is needed for write chunks here.
1482                 */
1483                rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,
1484                                           NULL, 0, NULL);
1485                if (rc == 0)
1486                        rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data);
1487#else
1488                /* In multi master mode, do everything in one RW action */
1489                rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
1490                                          data);
1491#endif
1492                data += todo;
1493                addr += (todo >> 1);
1494                datasize -= todo;
1495        } while (datasize && rc == 0);
1496
1497        return rc;
1498}
1499
1500
1501/*****************************
1502*
1503* int drxdap_fasi_read_reg16 (
1504*     struct i2c_device_addr *dev_addr, -- address of I2C device
1505*     u32 addr,    -- address of chip register/memory
1506*     u16 *data,    -- data to receive
1507*     u32 flags)   -- special device flags
1508*
1509* Read one 16-bit register or memory location. The data received back is
1510* converted back to the target platform's endianness.
1511*
1512* Output:
1513* - 0     if reading was successful
1514*                  in that case: read data is at *data
1515* - -EIO  if anything went wrong
1516*
1517******************************/
1518
1519static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
1520                                         u32 addr,
1521                                         u16 *data, u32 flags)
1522{
1523        u8 buf[sizeof(*data)];
1524        int rc;
1525
1526        if (!data)
1527                return -EINVAL;
1528
1529        rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1530        *data = buf[0] + (((u16) buf[1]) << 8);
1531        return rc;
1532}
1533
1534/*****************************
1535*
1536* int drxdap_fasi_read_reg32 (
1537*     struct i2c_device_addr *dev_addr, -- address of I2C device
1538*     u32 addr,    -- address of chip register/memory
1539*     u32 *data,    -- data to receive
1540*     u32 flags)   -- special device flags
1541*
1542* Read one 32-bit register or memory location. The data received back is
1543* converted back to the target platform's endianness.
1544*
1545* Output:
1546* - 0     if reading was successful
1547*                  in that case: read data is at *data
1548* - -EIO  if anything went wrong
1549*
1550******************************/
1551
1552static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
1553                                         u32 addr,
1554                                         u32 *data, u32 flags)
1555{
1556        u8 buf[sizeof(*data)];
1557        int rc;
1558
1559        if (!data)
1560                return -EINVAL;
1561
1562        rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1563        *data = (((u32) buf[0]) << 0) +
1564            (((u32) buf[1]) << 8) +
1565            (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
1566        return rc;
1567}
1568
1569/*****************************
1570*
1571* int drxdap_fasi_write_block (
1572*      struct i2c_device_addr *dev_addr,    -- address of I2C device
1573*      u32 addr,       -- address of chip register/memory
1574*      u16            datasize,   -- number of bytes to read
1575*      u8 *data,       -- data to receive
1576*      u32 flags)      -- special device flags
1577*
1578* Write block data to chip address. Because the chip is word oriented,
1579* the number of bytes to write must be even.
1580*
1581* Although this function expects an even number of bytes, it is still byte
1582* oriented, and the data being written is NOT translated from the endianness of
1583* the target platform.
1584*
1585* Output:
1586* - 0     if writing was successful
1587* - -EIO  if anything went wrong
1588*
1589******************************/
1590
1591static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
1592                                          u32 addr,
1593                                          u16 datasize,
1594                                          u8 *data, u32 flags)
1595{
1596        u8 buf[DRXDAP_MAX_WCHUNKSIZE];
1597        int st = -EIO;
1598        int first_err = 0;
1599        u16 overhead_size = 0;
1600        u16 block_size = 0;
1601
1602        /* Check parameters ******************************************************* */
1603        if (dev_addr == NULL)
1604                return -EINVAL;
1605
1606        overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1607            (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1608
1609        if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1610            ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1611             DRXDAP_FASI_LONG_FORMAT(addr)) ||
1612            (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1613            ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
1614                return -EINVAL;
1615
1616        flags &= DRXDAP_FASI_FLAGS;
1617        flags &= ~DRXDAP_FASI_MODEFLAGS;
1618#if DRXDAP_SINGLE_MASTER
1619        flags |= DRXDAP_FASI_SINGLE_MASTER;
1620#endif
1621
1622        /* Write block to I2C ***************************************************** */
1623        block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
1624        do {
1625                u16 todo = 0;
1626                u16 bufx = 0;
1627
1628                /* Buffer device address */
1629                addr &= ~DRXDAP_FASI_FLAGS;
1630                addr |= flags;
1631#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1632                /* short format address preferred but long format otherwise */
1633                if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1634#endif
1635#if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
1636                        buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1637                        buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1638                        buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1639                        buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1640#endif
1641#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1642                } else {
1643#endif
1644#if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
1645                        buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1646                        buf[bufx++] =
1647                            (u8) (((addr >> 16) & 0x0F) |
1648                                    ((addr >> 18) & 0xF0));
1649#endif
1650#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1651                }
1652#endif
1653
1654                /*
1655                   In single master mode block_size can be 0. In such a case this I2C
1656                   sequense will be visible: (1) write address {i2c addr,
1657                   4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
1658                   (3) write address (4) write data etc...
1659                   Address must be rewritten because HI is reset after data transport and
1660                   expects an address.
1661                 */
1662                todo = (block_size < datasize ? block_size : datasize);
1663                if (todo == 0) {
1664                        u16 overhead_size_i2c_addr = 0;
1665                        u16 data_block_size = 0;
1666
1667                        overhead_size_i2c_addr =
1668                            (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
1669                        data_block_size =
1670                            (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
1671
1672                        /* write device address */
1673                        st = drxbsp_i2c_write_read(dev_addr,
1674                                                  (u16) (bufx),
1675                                                  buf,
1676                                                  (struct i2c_device_addr *)(NULL),
1677                                                  0, (u8 *)(NULL));
1678
1679                        if ((st != 0) && (first_err == 0)) {
1680                                /* at the end, return the first error encountered */
1681                                first_err = st;
1682                        }
1683                        bufx = 0;
1684                        todo =
1685                            (data_block_size <
1686                             datasize ? data_block_size : datasize);
1687                }
1688                memcpy(&buf[bufx], data, todo);
1689                /* write (address if can do and) data */
1690                st = drxbsp_i2c_write_read(dev_addr,
1691                                          (u16) (bufx + todo),
1692                                          buf,
1693                                          (struct i2c_device_addr *)(NULL),
1694                                          0, (u8 *)(NULL));
1695
1696                if ((st != 0) && (first_err == 0)) {
1697                        /* at the end, return the first error encountered */
1698                        first_err = st;
1699                }
1700                datasize -= todo;
1701                data += todo;
1702                addr += (todo >> 1);
1703        } while (datasize);
1704
1705        return first_err;
1706}
1707
1708/*****************************
1709*
1710* int drxdap_fasi_write_reg16 (
1711*     struct i2c_device_addr *dev_addr, -- address of I2C device
1712*     u32 addr,    -- address of chip register/memory
1713*     u16            data,    -- data to send
1714*     u32 flags)   -- special device flags
1715*
1716* Write one 16-bit register or memory location. The data being written is
1717* converted from the target platform's endianness to little endian.
1718*
1719* Output:
1720* - 0     if writing was successful
1721* - -EIO  if anything went wrong
1722*
1723******************************/
1724
1725static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
1726                                          u32 addr,
1727                                          u16 data, u32 flags)
1728{
1729        u8 buf[sizeof(data)];
1730
1731        buf[0] = (u8) ((data >> 0) & 0xFF);
1732        buf[1] = (u8) ((data >> 8) & 0xFF);
1733
1734        return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1735}
1736
1737/*****************************
1738*
1739* int drxdap_fasi_read_modify_write_reg16 (
1740*      struct i2c_device_addr *dev_addr,   -- address of I2C device
1741*      u32 waddr,     -- address of chip register/memory
1742*      u32 raddr,     -- chip address to read back from
1743*      u16            wdata,     -- data to send
1744*      u16 *rdata)     -- data to receive back
1745*
1746* Write 16-bit data, then read back the original contents of that location.
1747* Requires long addressing format to be allowed.
1748*
1749* Before sending data, the data is converted to little endian. The
1750* data received back is converted back to the target platform's endianness.
1751*
1752* WARNING: This function is only guaranteed to work if there is one
1753* master on the I2C bus.
1754*
1755* Output:
1756* - 0     if reading was successful
1757*                  in that case: read back data is at *rdata
1758* - -EIO  if anything went wrong
1759*
1760******************************/
1761
1762static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1763                                                    u32 waddr,
1764                                                    u32 raddr,
1765                                                    u16 wdata, u16 *rdata)
1766{
1767        int rc = -EIO;
1768
1769#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1770        if (rdata == NULL)
1771                return -EINVAL;
1772
1773        rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
1774        if (rc == 0)
1775                rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
1776#endif
1777
1778        return rc;
1779}
1780
1781/*****************************
1782*
1783* int drxdap_fasi_write_reg32 (
1784*     struct i2c_device_addr *dev_addr, -- address of I2C device
1785*     u32 addr,    -- address of chip register/memory
1786*     u32            data,    -- data to send
1787*     u32 flags)   -- special device flags
1788*
1789* Write one 32-bit register or memory location. The data being written is
1790* converted from the target platform's endianness to little endian.
1791*
1792* Output:
1793* - 0     if writing was successful
1794* - -EIO  if anything went wrong
1795*
1796******************************/
1797
1798static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
1799                                          u32 addr,
1800                                          u32 data, u32 flags)
1801{
1802        u8 buf[sizeof(data)];
1803
1804        buf[0] = (u8) ((data >> 0) & 0xFF);
1805        buf[1] = (u8) ((data >> 8) & 0xFF);
1806        buf[2] = (u8) ((data >> 16) & 0xFF);
1807        buf[3] = (u8) ((data >> 24) & 0xFF);
1808
1809        return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1810}
1811
1812/*============================================================================*/
1813
1814/*
1815* \fn int drxj_dap_rm_write_reg16short
1816* \brief Read modify write 16 bits audio register using short format only.
1817* \param dev_addr
1818* \param waddr    Address to write to
1819* \param raddr    Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1820* \param wdata    Data to write
1821* \param rdata    Buffer for data to read
1822* \return int
1823* \retval 0 Success
1824* \retval -EIO Timeout, I2C error, illegal bank
1825*
1826* 16 bits register read modify write access using short addressing format only.
1827* Requires knowledge of the registermap, thus device dependent.
1828* Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1829*
1830*/
1831
1832/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1833   See comments drxj_dap_read_modify_write_reg16 */
1834#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1835static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1836                                              u32 waddr,
1837                                              u32 raddr,
1838                                              u16 wdata, u16 *rdata)
1839{
1840        int rc;
1841
1842        if (rdata == NULL)
1843                return -EINVAL;
1844
1845        /* Set RMW flag */
1846        rc = drxdap_fasi_write_reg16(dev_addr,
1847                                              SIO_HI_RA_RAM_S0_FLG_ACC__A,
1848                                              SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1849                                              0x0000);
1850        if (rc == 0) {
1851                /* Write new data: triggers RMW */
1852                rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
1853                                                      0x0000);
1854        }
1855        if (rc == 0) {
1856                /* Read old data */
1857                rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
1858                                                     0x0000);
1859        }
1860        if (rc == 0) {
1861                /* Reset RMW flag */
1862                rc = drxdap_fasi_write_reg16(dev_addr,
1863                                                      SIO_HI_RA_RAM_S0_FLG_ACC__A,
1864                                                      0, 0x0000);
1865        }
1866
1867        return rc;
1868}
1869#endif
1870
1871/*============================================================================*/
1872
1873static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1874                                                 u32 waddr,
1875                                                 u32 raddr,
1876                                                 u16 wdata, u16 *rdata)
1877{
1878        /* TODO: correct short/long addressing format decision,
1879           now long format has higher prio then short because short also
1880           needs virt bnks (not impl yet) for certain audio registers */
1881#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1882        return drxdap_fasi_read_modify_write_reg16(dev_addr,
1883                                                          waddr,
1884                                                          raddr, wdata, rdata);
1885#else
1886        return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1887#endif
1888}
1889
1890
1891/*============================================================================*/
1892
1893/*
1894* \fn int drxj_dap_read_aud_reg16
1895* \brief Read 16 bits audio register
1896* \param dev_addr
1897* \param addr
1898* \param data
1899* \return int
1900* \retval 0 Success
1901* \retval -EIO Timeout, I2C error, illegal bank
1902*
1903* 16 bits register read access via audio token ring interface.
1904*
1905*/
1906static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1907                                         u32 addr, u16 *data)
1908{
1909        u32 start_timer = 0;
1910        u32 current_timer = 0;
1911        u32 delta_timer = 0;
1912        u16 tr_status = 0;
1913        int stat = -EIO;
1914
1915        /* No read possible for bank 3, return with error */
1916        if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1917                stat = -EINVAL;
1918        } else {
1919                const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1920
1921                /* Force reset write bit */
1922                addr &= (~write_bit);
1923
1924                /* Set up read */
1925                start_timer = jiffies_to_msecs(jiffies);
1926                do {
1927                        /* RMW to aud TR IF until request is granted or timeout */
1928                        stat = drxj_dap_read_modify_write_reg16(dev_addr,
1929                                                             addr,
1930                                                             SIO_HI_RA_RAM_S0_RMWBUF__A,
1931                                                             0x0000, &tr_status);
1932
1933                        if (stat != 0)
1934                                break;
1935
1936                        current_timer = jiffies_to_msecs(jiffies);
1937                        delta_timer = current_timer - start_timer;
1938                        if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1939                                stat = -EIO;
1940                                break;
1941                        }
1942
1943                } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1944                          AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1945                         ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1946                          AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1947        }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1948
1949        /* Wait for read ready status or timeout */
1950        if (stat == 0) {
1951                start_timer = jiffies_to_msecs(jiffies);
1952
1953                while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1954                       AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1955                        stat = drxj_dap_read_reg16(dev_addr,
1956                                                  AUD_TOP_TR_CTR__A,
1957                                                  &tr_status, 0x0000);
1958                        if (stat != 0)
1959                                break;
1960
1961                        current_timer = jiffies_to_msecs(jiffies);
1962                        delta_timer = current_timer - start_timer;
1963                        if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1964                                stat = -EIO;
1965                                break;
1966                        }
1967                }               /* while ( ... ) */
1968        }
1969
1970        /* Read value */
1971        if (stat == 0)
1972                stat = drxj_dap_read_modify_write_reg16(dev_addr,
1973                                                     AUD_TOP_TR_RD_REG__A,
1974                                                     SIO_HI_RA_RAM_S0_RMWBUF__A,
1975                                                     0x0000, data);
1976        return stat;
1977}
1978
1979/*============================================================================*/
1980
1981static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1982                                      u32 addr,
1983                                      u16 *data, u32 flags)
1984{
1985        int stat = -EIO;
1986
1987        /* Check param */
1988        if ((dev_addr == NULL) || (data == NULL))
1989                return -EINVAL;
1990
1991        if (is_handled_by_aud_tr_if(addr))
1992                stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1993        else
1994                stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
1995
1996        return stat;
1997}
1998/*============================================================================*/
1999
2000/*
2001* \fn int drxj_dap_write_aud_reg16
2002* \brief Write 16 bits audio register
2003* \param dev_addr
2004* \param addr
2005* \param data
2006* \return int
2007* \retval 0 Success
2008* \retval -EIO Timeout, I2C error, illegal bank
2009*
2010* 16 bits register write access via audio token ring interface.
2011*
2012*/
2013static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
2014                                          u32 addr, u16 data)
2015{
2016        int stat = -EIO;
2017
2018        /* No write possible for bank 2, return with error */
2019        if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
2020                stat = -EINVAL;
2021        } else {
2022                u32 start_timer = 0;
2023                u32 current_timer = 0;
2024                u32 delta_timer = 0;
2025                u16 tr_status = 0;
2026                const u32 write_bit = ((dr_xaddr_t) 1) << 16;
2027
2028                /* Force write bit */
2029                addr |= write_bit;
2030                start_timer = jiffies_to_msecs(jiffies);
2031                do {
2032                        /* RMW to aud TR IF until request is granted or timeout */
2033                        stat = drxj_dap_read_modify_write_reg16(dev_addr,
2034                                                             addr,
2035                                                             SIO_HI_RA_RAM_S0_RMWBUF__A,
2036                                                             data, &tr_status);
2037                        if (stat != 0)
2038                                break;
2039
2040                        current_timer = jiffies_to_msecs(jiffies);
2041                        delta_timer = current_timer - start_timer;
2042                        if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
2043                                stat = -EIO;
2044                                break;
2045                        }
2046
2047                } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
2048                          AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
2049                         ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
2050                          AUD_TOP_TR_CTR_FIFO_FULL_FULL));
2051
2052        }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
2053
2054        return stat;
2055}
2056
2057/*============================================================================*/
2058
2059static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
2060                                       u32 addr,
2061                                       u16 data, u32 flags)
2062{
2063        int stat = -EIO;
2064
2065        /* Check param */
2066        if (dev_addr == NULL)
2067                return -EINVAL;
2068
2069        if (is_handled_by_aud_tr_if(addr))
2070                stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
2071        else
2072                stat = drxdap_fasi_write_reg16(dev_addr,
2073                                                            addr, data, flags);
2074
2075        return stat;
2076}
2077
2078/*============================================================================*/
2079
2080/* Free data ram in SIO HI */
2081#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2082#define SIO_HI_RA_RAM_USR_END__A   0x420060
2083
2084#define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2085#define DRXJ_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2086#define DRXJ_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2087#define DRXJ_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2088
2089/*
2090* \fn int drxj_dap_atomic_read_write_block()
2091* \brief Basic access routine for atomic read or write access
2092* \param dev_addr  pointer to i2c dev address
2093* \param addr     destination/source address
2094* \param datasize size of data buffer in bytes
2095* \param data     pointer to data buffer
2096* \return int
2097* \retval 0 Success
2098* \retval -EIO Timeout, I2C error, illegal bank
2099*
2100*/
2101static
2102int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2103                                          u32 addr,
2104                                          u16 datasize,
2105                                          u8 *data, bool read_flag)
2106{
2107        struct drxj_hi_cmd hi_cmd;
2108        int rc;
2109        u16 word;
2110        u16 dummy = 0;
2111        u16 i = 0;
2112
2113        /* Parameter check */
2114        if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2115                return -EINVAL;
2116
2117        /* Set up HI parameters to read or write n bytes */
2118        hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2119        hi_cmd.param1 =
2120            (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2121                     DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2122        hi_cmd.param2 =
2123            (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2124        hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2125        if (!read_flag)
2126                hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2127        else
2128                hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2129        hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2130                                DRXDAP_FASI_ADDR2BANK(addr));
2131        hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2132
2133        if (!read_flag) {
2134                /* write data to buffer */
2135                for (i = 0; i < (datasize / 2); i++) {
2136
2137                        word = ((u16) data[2 * i]);
2138                        word += (((u16) data[(2 * i) + 1]) << 8);
2139                        drxj_dap_write_reg16(dev_addr,
2140                                             (DRXJ_HI_ATOMIC_BUF_START + i),
2141                                            word, 0);
2142                }
2143        }
2144
2145        rc = hi_command(dev_addr, &hi_cmd, &dummy);
2146        if (rc != 0) {
2147                pr_err("error %d\n", rc);
2148                goto rw_error;
2149        }
2150
2151        if (read_flag) {
2152                /* read data from buffer */
2153                for (i = 0; i < (datasize / 2); i++) {
2154                        rc = drxj_dap_read_reg16(dev_addr,
2155                                                 (DRXJ_HI_ATOMIC_BUF_START + i),
2156                                                 &word, 0);
2157                        if (rc) {
2158                                pr_err("error %d\n", rc);
2159                                goto rw_error;
2160                        }
2161                        data[2 * i] = (u8) (word & 0xFF);
2162                        data[(2 * i) + 1] = (u8) (word >> 8);
2163                }
2164        }
2165
2166        return 0;
2167
2168rw_error:
2169        return rc;
2170
2171}
2172
2173/*============================================================================*/
2174
2175/*
2176* \fn int drxj_dap_atomic_read_reg32()
2177* \brief Atomic read of 32 bits words
2178*/
2179static
2180int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2181                                     u32 addr,
2182                                     u32 *data, u32 flags)
2183{
2184        u8 buf[sizeof(*data)] = { 0 };
2185        int rc;
2186        u32 word = 0;
2187
2188        if (!data)
2189                return -EINVAL;
2190
2191        rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2192                                              sizeof(*data), buf, true);
2193
2194        if (rc < 0)
2195                return 0;
2196
2197        word = (u32) buf[3];
2198        word <<= 8;
2199        word |= (u32) buf[2];
2200        word <<= 8;
2201        word |= (u32) buf[1];
2202        word <<= 8;
2203        word |= (u32) buf[0];
2204
2205        *data = word;
2206
2207        return rc;
2208}
2209
2210/*============================================================================*/
2211
2212/*============================================================================*/
2213/*==                        END DRXJ DAP FUNCTIONS                          ==*/
2214/*============================================================================*/
2215
2216/*============================================================================*/
2217/*============================================================================*/
2218/*==                      HOST INTERFACE FUNCTIONS                          ==*/
2219/*============================================================================*/
2220/*============================================================================*/
2221
2222/*
2223* \fn int hi_cfg_command()
2224* \brief Configure HI with settings stored in the demod structure.
2225* \param demod Demodulator.
2226* \return int.
2227*
2228* This routine was created because to much orthogonal settings have
2229* been put into one HI API function (configure). Especially the I2C bridge
2230* enable/disable should not need re-configuration of the HI.
2231*
2232*/
2233static int hi_cfg_command(const struct drx_demod_instance *demod)
2234{
2235        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2236        struct drxj_hi_cmd hi_cmd;
2237        u16 result = 0;
2238        int rc;
2239
2240        ext_attr = (struct drxj_data *) demod->my_ext_attr;
2241
2242        hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2243        hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2244        hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2245        hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2246        hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2247        hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2248        hi_cmd.param6 = ext_attr->hi_cfg_transmit;
2249
2250        rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
2251        if (rc != 0) {
2252                pr_err("error %d\n", rc);
2253                goto rw_error;
2254        }
2255
2256        /* Reset power down flag (set one call only) */
2257        ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2258
2259        return 0;
2260
2261rw_error:
2262        return rc;
2263}
2264
2265/*
2266* \fn int hi_command()
2267* \brief Configure HI with settings stored in the demod structure.
2268* \param dev_addr I2C address.
2269* \param cmd HI command.
2270* \param result HI command result.
2271* \return int.
2272*
2273* Sends command to HI
2274*
2275*/
2276static int
2277hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2278{
2279        u16 wait_cmd = 0;
2280        u16 nr_retries = 0;
2281        bool powerdown_cmd = false;
2282        int rc;
2283
2284        /* Write parameters */
2285        switch (cmd->cmd) {
2286
2287        case SIO_HI_RA_RAM_CMD_CONFIG:
2288        case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2289                rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
2290                if (rc != 0) {
2291                        pr_err("error %d\n", rc);
2292                        goto rw_error;
2293                }
2294                rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
2295                if (rc != 0) {
2296                        pr_err("error %d\n", rc);
2297                        goto rw_error;
2298                }
2299                rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
2300                if (rc != 0) {
2301                        pr_err("error %d\n", rc);
2302                        goto rw_error;
2303                }
2304                rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
2305                if (rc != 0) {
2306                        pr_err("error %d\n", rc);
2307                        goto rw_error;
2308                }
2309                fallthrough;
2310        case SIO_HI_RA_RAM_CMD_BRDCTRL:
2311                rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
2312                if (rc != 0) {
2313                        pr_err("error %d\n", rc);
2314                        goto rw_error;
2315                }
2316                rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
2317                if (rc != 0) {
2318                        pr_err("error %d\n", rc);
2319                        goto rw_error;
2320                }
2321                fallthrough;
2322        case SIO_HI_RA_RAM_CMD_NULL:
2323                /* No parameters */
2324                break;
2325
2326        default:
2327                return -EINVAL;
2328        }
2329
2330        /* Write command */
2331        rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
2332        if (rc != 0) {
2333                pr_err("error %d\n", rc);
2334                goto rw_error;
2335        }
2336
2337        if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2338                msleep(1);
2339
2340        /* Detect power down to omit reading result */
2341        powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2342                                  (((cmd->
2343                                     param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2344                                   == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2345        if (!powerdown_cmd) {
2346                /* Wait until command rdy */
2347                do {
2348                        nr_retries++;
2349                        if (nr_retries > DRXJ_MAX_RETRIES) {
2350                                pr_err("timeout\n");
2351                                goto rw_error;
2352                        }
2353
2354                        rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
2355                        if (rc != 0) {
2356                                pr_err("error %d\n", rc);
2357                                goto rw_error;
2358                        }
2359                } while (wait_cmd != 0);
2360
2361                /* Read result */
2362                rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
2363                if (rc != 0) {
2364                        pr_err("error %d\n", rc);
2365                        goto rw_error;
2366                }
2367
2368        }
2369        /* if ( powerdown_cmd == true ) */
2370        return 0;
2371rw_error:
2372        return rc;
2373}
2374
2375/*
2376* \fn int init_hi( const struct drx_demod_instance *demod )
2377* \brief Initialise and configurate HI.
2378* \param demod pointer to demod data.
2379* \return int Return status.
2380* \retval 0 Success.
2381* \retval -EIO Failure.
2382*
2383* Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2384* Need to store configuration in driver because of the way I2C
2385* bridging is controlled.
2386*
2387*/
2388static int init_hi(const struct drx_demod_instance *demod)
2389{
2390        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2391        struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2392        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2393        int rc;
2394
2395        ext_attr = (struct drxj_data *) demod->my_ext_attr;
2396        common_attr = (struct drx_common_attr *) demod->my_common_attr;
2397        dev_addr = demod->my_i2c_dev_addr;
2398
2399        /* PATCH for bug 5003, HI ucode v3.1.0 */
2400        rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);
2401        if (rc != 0) {
2402                pr_err("error %d\n", rc);
2403                goto rw_error;
2404        }
2405
2406        /* Timing div, 250ns/Psys */
2407        /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2408        ext_attr->hi_cfg_timing_div =
2409            (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2410        /* Clipping */
2411        if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2412                ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2413        /* Bridge delay, uses oscilator clock */
2414        /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2415        /* SDA brdige delay */
2416        ext_attr->hi_cfg_bridge_delay =
2417            (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2418            1000;
2419        /* Clipping */
2420        if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2421                ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2422        /* SCL bridge delay, same as SDA for now */
2423        ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
2424                                      SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2425        /* Wakeup key, setting the read flag (as suggest in the documentation) does
2426           not always result into a working solution (barebones worked VI2C failed).
2427           Not setting the bit works in all cases . */
2428        ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2429        /* port/bridge/power down ctrl */
2430        ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2431        /* transit mode time out delay and watch dog divider */
2432        ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2433
2434        rc = hi_cfg_command(demod);
2435        if (rc != 0) {
2436                pr_err("error %d\n", rc);
2437                goto rw_error;
2438        }
2439
2440        return 0;
2441
2442rw_error:
2443        return rc;
2444}
2445
2446/*============================================================================*/
2447/*==                   END HOST INTERFACE FUNCTIONS                         ==*/
2448/*============================================================================*/
2449
2450/*============================================================================*/
2451/*============================================================================*/
2452/*==                        AUXILIARY FUNCTIONS                             ==*/
2453/*============================================================================*/
2454/*============================================================================*/
2455
2456/*
2457* \fn int get_device_capabilities()
2458* \brief Get and store device capabilities.
2459* \param demod  Pointer to demodulator instance.
2460* \return int.
2461* \return 0    Success
2462* \retval -EIO Failure
2463*
2464* Depending on pulldowns on MDx pins the following internals are set:
2465*  * common_attr->osc_clock_freq
2466*  * ext_attr->has_lna
2467*  * ext_attr->has_ntsc
2468*  * ext_attr->has_btsc
2469*  * ext_attr->has_oob
2470*
2471*/
2472static int get_device_capabilities(struct drx_demod_instance *demod)
2473{
2474        struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2475        struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2476        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2477        u16 sio_pdr_ohw_cfg = 0;
2478        u32 sio_top_jtagid_lo = 0;
2479        u16 bid = 0;
2480        int rc;
2481
2482        common_attr = (struct drx_common_attr *) demod->my_common_attr;
2483        ext_attr = (struct drxj_data *) demod->my_ext_attr;
2484        dev_addr = demod->my_i2c_dev_addr;
2485
2486        rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2487        if (rc != 0) {
2488                pr_err("error %d\n", rc);
2489                goto rw_error;
2490        }
2491        rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
2492        if (rc != 0) {
2493                pr_err("error %d\n", rc);
2494                goto rw_error;
2495        }
2496        rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2497        if (rc != 0) {
2498                pr_err("error %d\n", rc);
2499                goto rw_error;
2500        }
2501
2502        switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2503        case 0:
2504                /* ignore (bypass ?) */
2505                break;
2506        case 1:
2507                /* 27 MHz */
2508                common_attr->osc_clock_freq = 27000;
2509                break;
2510        case 2:
2511                /* 20.25 MHz */
2512                common_attr->osc_clock_freq = 20250;
2513                break;
2514        case 3:
2515                /* 4 MHz */
2516                common_attr->osc_clock_freq = 4000;
2517                break;
2518        default:
2519                return -EIO;
2520        }
2521
2522        /*
2523           Determine device capabilities
2524           Based on pinning v47
2525         */
2526        rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
2527        if (rc != 0) {
2528                pr_err("error %d\n", rc);
2529                goto rw_error;
2530        }
2531        ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2532
2533        switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2534        case 0x31:
2535                rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2536                if (rc != 0) {
2537                        pr_err("error %d\n", rc);
2538                        goto rw_error;
2539                }
2540                rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
2541                if (rc != 0) {
2542                        pr_err("error %d\n", rc);
2543                        goto rw_error;
2544                }
2545                bid = (bid >> 10) & 0xf;
2546                rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2547                if (rc != 0) {
2548                        pr_err("error %d\n", rc);
2549                        goto rw_error;
2550                }
2551
2552                ext_attr->has_lna = true;
2553                ext_attr->has_ntsc = false;
2554                ext_attr->has_btsc = false;
2555                ext_attr->has_oob = false;
2556                ext_attr->has_smatx = true;
2557                ext_attr->has_smarx = false;
2558                ext_attr->has_gpio = false;
2559                ext_attr->has_irqn = false;
2560                break;
2561        case 0x33:
2562                ext_attr->has_lna = false;
2563                ext_attr->has_ntsc = false;
2564                ext_attr->has_btsc = false;
2565                ext_attr->has_oob = false;
2566                ext_attr->has_smatx = true;
2567                ext_attr->has_smarx = false;
2568                ext_attr->has_gpio = false;
2569                ext_attr->has_irqn = false;
2570                break;
2571        case 0x45:
2572                ext_attr->has_lna = true;
2573                ext_attr->has_ntsc = true;
2574                ext_attr->has_btsc = false;
2575                ext_attr->has_oob = false;
2576                ext_attr->has_smatx = true;
2577                ext_attr->has_smarx = true;
2578                ext_attr->has_gpio = true;
2579                ext_attr->has_irqn = false;
2580                break;
2581        case 0x46:
2582                ext_attr->has_lna = false;
2583                ext_attr->has_ntsc = true;
2584                ext_attr->has_btsc = false;
2585                ext_attr->has_oob = false;
2586                ext_attr->has_smatx = true;
2587                ext_attr->has_smarx = true;
2588                ext_attr->has_gpio = true;
2589                ext_attr->has_irqn = false;
2590                break;
2591        case 0x41:
2592                ext_attr->has_lna = true;
2593                ext_attr->has_ntsc = true;
2594                ext_attr->has_btsc = true;
2595                ext_attr->has_oob = false;
2596                ext_attr->has_smatx = true;
2597                ext_attr->has_smarx = true;
2598                ext_attr->has_gpio = true;
2599                ext_attr->has_irqn = false;
2600                break;
2601        case 0x43:
2602                ext_attr->has_lna = false;
2603                ext_attr->has_ntsc = true;
2604                ext_attr->has_btsc = true;
2605                ext_attr->has_oob = false;
2606                ext_attr->has_smatx = true;
2607                ext_attr->has_smarx = true;
2608                ext_attr->has_gpio = true;
2609                ext_attr->has_irqn = false;
2610                break;
2611        case 0x32:
2612                ext_attr->has_lna = true;
2613                ext_attr->has_ntsc = false;
2614                ext_attr->has_btsc = false;
2615                ext_attr->has_oob = true;
2616                ext_attr->has_smatx = true;
2617                ext_attr->has_smarx = true;
2618                ext_attr->has_gpio = true;
2619                ext_attr->has_irqn = true;
2620                break;
2621        case 0x34:
2622                ext_attr->has_lna = false;
2623                ext_attr->has_ntsc = true;
2624                ext_attr->has_btsc = true;
2625                ext_attr->has_oob = true;
2626                ext_attr->has_smatx = true;
2627                ext_attr->has_smarx = true;
2628                ext_attr->has_gpio = true;
2629                ext_attr->has_irqn = true;
2630                break;
2631        case 0x42:
2632                ext_attr->has_lna = true;
2633                ext_attr->has_ntsc = true;
2634                ext_attr->has_btsc = true;
2635                ext_attr->has_oob = true;
2636                ext_attr->has_smatx = true;
2637                ext_attr->has_smarx = true;
2638                ext_attr->has_gpio = true;
2639                ext_attr->has_irqn = true;
2640                break;
2641        case 0x44:
2642                ext_attr->has_lna = false;
2643                ext_attr->has_ntsc = true;
2644                ext_attr->has_btsc = true;
2645                ext_attr->has_oob = true;
2646                ext_attr->has_smatx = true;
2647                ext_attr->has_smarx = true;
2648                ext_attr->has_gpio = true;
2649                ext_attr->has_irqn = true;
2650                break;
2651        default:
2652                /* Unknown device variant */
2653                return -EIO;
2654                break;
2655        }
2656
2657        return 0;
2658rw_error:
2659        return rc;
2660}
2661
2662/*
2663* \fn int power_up_device()
2664* \brief Power up device.
2665* \param demod  Pointer to demodulator instance.
2666* \return int.
2667* \return 0    Success
2668* \retval -EIO Failure, I2C or max retries reached
2669*
2670*/
2671
2672#ifndef DRXJ_MAX_RETRIES_POWERUP
2673#define DRXJ_MAX_RETRIES_POWERUP 10
2674#endif
2675
2676static int power_up_device(struct drx_demod_instance *demod)
2677{
2678        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2679        u8 data = 0;
2680        u16 retry_count = 0;
2681        struct i2c_device_addr wake_up_addr;
2682
2683        dev_addr = demod->my_i2c_dev_addr;
2684        wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2685        wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2686        wake_up_addr.user_data = dev_addr->user_data;
2687        /*
2688         * I2C access may fail in this case: no ack
2689         * dummy write must be used to wake uop device, dummy read must be used to
2690         * reset HI state machine (avoiding actual writes)
2691         */
2692        do {
2693                data = 0;
2694                drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
2695                                      (struct i2c_device_addr *)(NULL), 0,
2696                                     (u8 *)(NULL));
2697                msleep(10);
2698                retry_count++;
2699        } while ((drxbsp_i2c_write_read
2700                  ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
2701                   &data)
2702                  != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2703
2704        /* Need some recovery time .... */
2705        msleep(10);
2706
2707        if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2708                return -EIO;
2709
2710        return 0;
2711}
2712
2713/*----------------------------------------------------------------------------*/
2714/* MPEG Output Configuration Functions - begin                                */
2715/*----------------------------------------------------------------------------*/
2716/*
2717* \fn int ctrl_set_cfg_mpeg_output()
2718* \brief Set MPEG output configuration of the device.
2719* \param devmod  Pointer to demodulator instance.
2720* \param cfg_data Pointer to mpeg output configuaration.
2721* \return int.
2722*
2723*  Configure MPEG output parameters.
2724*
2725*/
2726static int
2727ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2728{
2729        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2730        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2731        struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2732        int rc;
2733        u16 fec_oc_reg_mode = 0;
2734        u16 fec_oc_reg_ipr_mode = 0;
2735        u16 fec_oc_reg_ipr_invert = 0;
2736        u32 max_bit_rate = 0;
2737        u32 rcn_rate = 0;
2738        u32 nr_bits = 0;
2739        u16 sio_pdr_md_cfg = 0;
2740        /* data mask for the output data byte */
2741        u16 invert_data_mask =
2742            FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2743            FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2744            FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2745            FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2746
2747        /* check arguments */
2748        if ((demod == NULL) || (cfg_data == NULL))
2749                return -EINVAL;
2750
2751        dev_addr = demod->my_i2c_dev_addr;
2752        ext_attr = (struct drxj_data *) demod->my_ext_attr;
2753        common_attr = (struct drx_common_attr *) demod->my_common_attr;
2754
2755        if (cfg_data->enable_mpeg_output == true) {
2756                /* quick and dirty patch to set MPEG in case current std is not
2757                   producing MPEG */
2758                switch (ext_attr->standard) {
2759                case DRX_STANDARD_8VSB:
2760                case DRX_STANDARD_ITU_A:
2761                case DRX_STANDARD_ITU_B:
2762                case DRX_STANDARD_ITU_C:
2763                        break;
2764                default:
2765                        return 0;
2766                }
2767
2768                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
2769                if (rc != 0) {
2770                        pr_err("error %d\n", rc);
2771                        goto rw_error;
2772                }
2773                switch (ext_attr->standard) {
2774                case DRX_STANDARD_8VSB:
2775                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
2776                        if (rc != 0) {
2777                                pr_err("error %d\n", rc);
2778                                goto rw_error;
2779                        }       /* 2048 bytes fifo ram */
2780                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
2781                        if (rc != 0) {
2782                                pr_err("error %d\n", rc);
2783                                goto rw_error;
2784                        }
2785                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
2786                        if (rc != 0) {
2787                                pr_err("error %d\n", rc);
2788                                goto rw_error;
2789                        }
2790                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
2791                        if (rc != 0) {
2792                                pr_err("error %d\n", rc);
2793                                goto rw_error;
2794                        }
2795                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
2796                        if (rc != 0) {
2797                                pr_err("error %d\n", rc);
2798                                goto rw_error;
2799                        }
2800                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
2801                        if (rc != 0) {
2802                                pr_err("error %d\n", rc);
2803                                goto rw_error;
2804                        }
2805                        /* Low Water Mark for synchronization  */
2806                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
2807                        if (rc != 0) {
2808                                pr_err("error %d\n", rc);
2809                                goto rw_error;
2810                        }
2811                        /* High Water Mark for synchronization */
2812                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
2813                        if (rc != 0) {
2814                                pr_err("error %d\n", rc);
2815                                goto rw_error;
2816                        }
2817                        break;
2818                case DRX_STANDARD_ITU_A:
2819                case DRX_STANDARD_ITU_C:
2820                        switch (ext_attr->constellation) {
2821                        case DRX_CONSTELLATION_QAM256:
2822                                nr_bits = 8;
2823                                break;
2824                        case DRX_CONSTELLATION_QAM128:
2825                                nr_bits = 7;
2826                                break;
2827                        case DRX_CONSTELLATION_QAM64:
2828                                nr_bits = 6;
2829                                break;
2830                        case DRX_CONSTELLATION_QAM32:
2831                                nr_bits = 5;
2832                                break;
2833                        case DRX_CONSTELLATION_QAM16:
2834                                nr_bits = 4;
2835                                break;
2836                        default:
2837                                return -EIO;
2838                        }       /* ext_attr->constellation */
2839                        /* max_bit_rate = symbol_rate * nr_bits * coef */
2840                        /* coef = 188/204                          */
2841                        max_bit_rate =
2842                            (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2843                        fallthrough;    /* as b/c Annex A/C need following settings */
2844                case DRX_STANDARD_ITU_B:
2845                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
2846                        if (rc != 0) {
2847                                pr_err("error %d\n", rc);
2848                                goto rw_error;
2849                        }
2850                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
2851                        if (rc != 0) {
2852                                pr_err("error %d\n", rc);
2853                                goto rw_error;
2854                        }
2855                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
2856                        if (rc != 0) {
2857                                pr_err("error %d\n", rc);
2858                                goto rw_error;
2859                        }
2860                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
2861                        if (rc != 0) {
2862                                pr_err("error %d\n", rc);
2863                                goto rw_error;
2864                        }
2865                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
2866                        if (rc != 0) {
2867                                pr_err("error %d\n", rc);
2868                                goto rw_error;
2869                        }
2870                        if (cfg_data->static_clk == true) {
2871                                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
2872                                if (rc != 0) {
2873                                        pr_err("error %d\n", rc);
2874                                        goto rw_error;
2875                                }
2876                        } else {
2877                                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
2878                                if (rc != 0) {
2879                                        pr_err("error %d\n", rc);
2880                                        goto rw_error;
2881                                }
2882                        }
2883                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
2884                        if (rc != 0) {
2885                                pr_err("error %d\n", rc);
2886                                goto rw_error;
2887                        }
2888                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
2889                        if (rc != 0) {
2890                                pr_err("error %d\n", rc);
2891                                goto rw_error;
2892                        }
2893                        break;
2894                default:
2895                        break;
2896                }               /* switch (standard) */
2897
2898                /* Check insertion of the Reed-Solomon parity bytes */
2899                rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
2900                if (rc != 0) {
2901                        pr_err("error %d\n", rc);
2902                        goto rw_error;
2903                }
2904                rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
2905                if (rc != 0) {
2906                        pr_err("error %d\n", rc);
2907                        goto rw_error;
2908                }
2909                if (cfg_data->insert_rs_byte == true) {
2910                        /* enable parity symbol forward */
2911                        fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2912                        /* MVAL disable during parity bytes */
2913                        fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2914                        switch (ext_attr->standard) {
2915                        case DRX_STANDARD_8VSB:
2916                                rcn_rate = 0x004854D3;
2917                                break;
2918                        case DRX_STANDARD_ITU_B:
2919                                fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2920                                switch (ext_attr->constellation) {
2921                                case DRX_CONSTELLATION_QAM256:
2922                                        rcn_rate = 0x008945E7;
2923                                        break;
2924                                case DRX_CONSTELLATION_QAM64:
2925                                        rcn_rate = 0x005F64D4;
2926                                        break;
2927                                default:
2928                                        return -EIO;
2929                                }
2930                                break;
2931                        case DRX_STANDARD_ITU_A:
2932                        case DRX_STANDARD_ITU_C:
2933                                /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2934                                rcn_rate =
2935                                    (frac28
2936                                     (max_bit_rate,
2937                                      (u32) (common_attr->sys_clock_freq / 8))) /
2938                                    188;
2939                                break;
2940                        default:
2941                                return -EIO;
2942                        }       /* ext_attr->standard */
2943                } else {        /* insert_rs_byte == false */
2944
2945                        /* disable parity symbol forward */
2946                        fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2947                        /* MVAL enable during parity bytes */
2948                        fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2949                        switch (ext_attr->standard) {
2950                        case DRX_STANDARD_8VSB:
2951                                rcn_rate = 0x0041605C;
2952                                break;
2953                        case DRX_STANDARD_ITU_B:
2954                                fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2955                                switch (ext_attr->constellation) {
2956                                case DRX_CONSTELLATION_QAM256:
2957                                        rcn_rate = 0x0082D6A0;
2958                                        break;
2959                                case DRX_CONSTELLATION_QAM64:
2960                                        rcn_rate = 0x005AEC1A;
2961                                        break;
2962                                default:
2963                                        return -EIO;
2964                                }
2965                                break;
2966                        case DRX_STANDARD_ITU_A:
2967                        case DRX_STANDARD_ITU_C:
2968                                /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2969                                rcn_rate =
2970                                    (frac28
2971                                     (max_bit_rate,
2972                                      (u32) (common_attr->sys_clock_freq / 8))) /
2973                                    204;
2974                                break;
2975                        default:
2976                                return -EIO;
2977                        }       /* ext_attr->standard */
2978                }
2979
2980                if (cfg_data->enable_parallel == true) {        /* MPEG data output is parallel -> clear ipr_mode[0] */
2981                        fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2982                } else {        /* MPEG data output is serial -> set ipr_mode[0] */
2983                        fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2984                }
2985
2986                /* Control slective inversion of output bits */
2987                if (cfg_data->invert_data == true)
2988                        fec_oc_reg_ipr_invert |= invert_data_mask;
2989                else
2990                        fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2991
2992                if (cfg_data->invert_err == true)
2993                        fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2994                else
2995                        fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2996
2997                if (cfg_data->invert_str == true)
2998                        fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2999                else
3000                        fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
3001
3002                if (cfg_data->invert_val == true)
3003                        fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
3004                else
3005                        fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
3006
3007                if (cfg_data->invert_clk == true)
3008                        fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
3009                else
3010                        fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
3011
3012
3013                if (cfg_data->static_clk == true) {     /* Static mode */
3014                        u32 dto_rate = 0;
3015                        u32 bit_rate = 0;
3016                        u16 fec_oc_dto_burst_len = 0;
3017                        u16 fec_oc_dto_period = 0;
3018
3019                        fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
3020
3021                        switch (ext_attr->standard) {
3022                        case DRX_STANDARD_8VSB:
3023                                fec_oc_dto_period = 4;
3024                                if (cfg_data->insert_rs_byte == true)
3025                                        fec_oc_dto_burst_len = 208;
3026                                break;
3027                        case DRX_STANDARD_ITU_A:
3028                                {
3029                                        u32 symbol_rate_th = 6400000;
3030                                        if (cfg_data->insert_rs_byte == true) {
3031                                                fec_oc_dto_burst_len = 204;
3032                                                symbol_rate_th = 5900000;
3033                                        }
3034                                        if (ext_attr->curr_symbol_rate >=
3035                                            symbol_rate_th) {
3036                                                fec_oc_dto_period = 0;
3037                                        } else {
3038                                                fec_oc_dto_period = 1;
3039                                        }
3040                                }
3041                                break;
3042                        case DRX_STANDARD_ITU_B:
3043                                fec_oc_dto_period = 1;
3044                                if (cfg_data->insert_rs_byte == true)
3045                                        fec_oc_dto_burst_len = 128;
3046                                break;
3047                        case DRX_STANDARD_ITU_C:
3048                                fec_oc_dto_period = 1;
3049                                if (cfg_data->insert_rs_byte == true)
3050                                        fec_oc_dto_burst_len = 204;
3051                                break;
3052                        default:
3053                                return -EIO;
3054                        }
3055                        bit_rate =
3056                            common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
3057                                                               2);
3058                        dto_rate =
3059                            frac28(bit_rate, common_attr->sys_clock_freq * 1000);
3060                        dto_rate >>= 3;
3061                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
3062                        if (rc != 0) {
3063                                pr_err("error %d\n", rc);
3064                                goto rw_error;
3065                        }
3066                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
3067                        if (rc != 0) {
3068                                pr_err("error %d\n", rc);
3069                                goto rw_error;
3070                        }
3071                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
3072                        if (rc != 0) {
3073                                pr_err("error %d\n", rc);
3074                                goto rw_error;
3075                        }
3076                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
3077                        if (rc != 0) {
3078                                pr_err("error %d\n", rc);
3079                                goto rw_error;
3080                        }
3081                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
3082                        if (rc != 0) {
3083                                pr_err("error %d\n", rc);
3084                                goto rw_error;
3085                        }
3086                        if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3087                                fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
3088                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
3089                        if (rc != 0) {
3090                                pr_err("error %d\n", rc);
3091                                goto rw_error;
3092                        }
3093                } else {        /* Dynamic mode */
3094
3095                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
3096                        if (rc != 0) {
3097                                pr_err("error %d\n", rc);
3098                                goto rw_error;
3099                        }
3100                        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
3101                        if (rc != 0) {
3102                                pr_err("error %d\n", rc);
3103                                goto rw_error;
3104                        }
3105                }
3106
3107                rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
3108                if (rc != 0) {
3109                        pr_err("error %d\n", rc);
3110                        goto rw_error;
3111                }
3112
3113                /* Write appropriate registers with requested configuration */
3114                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
3115                if (rc != 0) {
3116                        pr_err("error %d\n", rc);
3117                        goto rw_error;
3118                }
3119                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
3120                if (rc != 0) {
3121                        pr_err("error %d\n", rc);
3122                        goto rw_error;
3123                }
3124                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
3125                if (rc != 0) {
3126                        pr_err("error %d\n", rc);
3127                        goto rw_error;
3128                }
3129
3130                /* enabling for both parallel and serial now */
3131                /*  Write magic word to enable pdr reg write */
3132                rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3133                if (rc != 0) {
3134                        pr_err("error %d\n", rc);
3135                        goto rw_error;
3136                }
3137                /*  Set MPEG TS pads to outputmode */
3138                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
3139                if (rc != 0) {
3140                        pr_err("error %d\n", rc);
3141                        goto rw_error;
3142                }
3143                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
3144                if (rc != 0) {
3145                        pr_err("error %d\n", rc);
3146                        goto rw_error;
3147                }
3148                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B | 0x03 << SIO_PDR_MCLK_CFG_MODE__B, 0);
3149                if (rc != 0) {
3150                        pr_err("error %d\n", rc);
3151                        goto rw_error;
3152                }
3153                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
3154                if (rc != 0) {
3155                        pr_err("error %d\n", rc);
3156                        goto rw_error;
3157                }
3158                sio_pdr_md_cfg =
3159                    MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3160                    SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3161                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3162                if (rc != 0) {
3163                        pr_err("error %d\n", rc);
3164                        goto rw_error;
3165                }
3166                if (cfg_data->enable_parallel == true) {        /* MPEG data output is parallel -> set MD1 to MD7 to output mode */
3167                        sio_pdr_md_cfg =
3168                            MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3169                            SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3170                            SIO_PDR_MD0_CFG_MODE__B;
3171                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3172                        if (rc != 0) {
3173                                pr_err("error %d\n", rc);
3174                                goto rw_error;
3175                        }
3176                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
3177                        if (rc != 0) {
3178                                pr_err("error %d\n", rc);
3179                                goto rw_error;
3180                        }
3181                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
3182                        if (rc != 0) {
3183                                pr_err("error %d\n", rc);
3184                                goto rw_error;
3185                        }
3186                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
3187                        if (rc != 0) {
3188                                pr_err("error %d\n", rc);
3189                                goto rw_error;
3190                        }
3191                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
3192                        if (rc != 0) {
3193                                pr_err("error %d\n", rc);
3194                                goto rw_error;
3195                        }
3196                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
3197                        if (rc != 0) {
3198                                pr_err("error %d\n", rc);
3199                                goto rw_error;
3200                        }
3201                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
3202                        if (rc != 0) {
3203                                pr_err("error %d\n", rc);
3204                                goto rw_error;
3205                        }
3206                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
3207                        if (rc != 0) {
3208                                pr_err("error %d\n", rc);
3209                                goto rw_error;
3210                        }
3211                } else {        /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3212                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3213                        if (rc != 0) {
3214                                pr_err("error %d\n", rc);
3215                                goto rw_error;
3216                        }
3217                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3218                        if (rc != 0) {
3219                                pr_err("error %d\n", rc);
3220                                goto rw_error;
3221                        }
3222                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3223                        if (rc != 0) {
3224                                pr_err("error %d\n", rc);
3225                                goto rw_error;
3226                        }
3227                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3228                        if (rc != 0) {
3229                                pr_err("error %d\n", rc);
3230                                goto rw_error;
3231                        }
3232                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3233                        if (rc != 0) {
3234                                pr_err("error %d\n", rc);
3235                                goto rw_error;
3236                        }
3237                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3238                        if (rc != 0) {
3239                                pr_err("error %d\n", rc);
3240                                goto rw_error;
3241                        }
3242                        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3243                        if (rc != 0) {
3244                                pr_err("error %d\n", rc);
3245                                goto rw_error;
3246                        }
3247                }
3248                /*  Enable Monitor Bus output over MPEG pads and ctl input */
3249                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3250                if (rc != 0) {
3251                        pr_err("error %d\n", rc);
3252                        goto rw_error;
3253                }
3254                /*  Write nomagic word to enable pdr reg write */
3255                rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3256                if (rc != 0) {
3257                        pr_err("error %d\n", rc);
3258                        goto rw_error;
3259                }
3260        } else {
3261                /*  Write magic word to enable pdr reg write */
3262                rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3263                if (rc != 0) {
3264                        pr_err("error %d\n", rc);
3265                        goto rw_error;
3266                }
3267                /*  Set MPEG TS pads to inputmode */
3268                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
3269                if (rc != 0) {
3270                        pr_err("error %d\n", rc);
3271                        goto rw_error;
3272                }
3273                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
3274                if (rc != 0) {
3275                        pr_err("error %d\n", rc);
3276                        goto rw_error;
3277                }
3278                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
3279                if (rc != 0) {
3280                        pr_err("error %d\n", rc);
3281                        goto rw_error;
3282                }
3283                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
3284                if (rc != 0) {
3285                        pr_err("error %d\n", rc);
3286                        goto rw_error;
3287                }
3288                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
3289                if (rc != 0) {
3290                        pr_err("error %d\n", rc);
3291                        goto rw_error;
3292                }
3293                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3294                if (rc != 0) {
3295                        pr_err("error %d\n", rc);
3296                        goto rw_error;
3297                }
3298                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3299                if (rc != 0) {
3300                        pr_err("error %d\n", rc);
3301                        goto rw_error;
3302                }
3303                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3304                if (rc != 0) {
3305                        pr_err("error %d\n", rc);
3306                        goto rw_error;
3307                }
3308                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3309                if (rc != 0) {
3310                        pr_err("error %d\n", rc);
3311                        goto rw_error;
3312                }
3313                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3314                if (rc != 0) {
3315                        pr_err("error %d\n", rc);
3316                        goto rw_error;
3317                }
3318                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3319                if (rc != 0) {
3320                        pr_err("error %d\n", rc);
3321                        goto rw_error;
3322                }
3323                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3324                if (rc != 0) {
3325                        pr_err("error %d\n", rc);
3326                        goto rw_error;
3327                }
3328                /* Enable Monitor Bus output over MPEG pads and ctl input */
3329                rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3330                if (rc != 0) {
3331                        pr_err("error %d\n", rc);
3332                        goto rw_error;
3333                }
3334                /* Write nomagic word to enable pdr reg write */
3335                rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3336                if (rc != 0) {
3337                        pr_err("error %d\n", rc);
3338                        goto rw_error;
3339                }
3340        }
3341
3342        /* save values for restore after re-acquire */
3343        common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3344
3345        return 0;
3346rw_error:
3347        return rc;
3348}
3349
3350/*----------------------------------------------------------------------------*/
3351
3352
3353/*----------------------------------------------------------------------------*/
3354/* MPEG Output Configuration Functions - end                                  */
3355/*----------------------------------------------------------------------------*/
3356
3357/*----------------------------------------------------------------------------*/
3358/* miscellaneous configurations - begin                           */
3359/*----------------------------------------------------------------------------*/
3360
3361/*
3362* \fn int set_mpegtei_handling()
3363* \brief Activate MPEG TEI handling settings.
3364* \param devmod  Pointer to demodulator instance.
3365* \return int.
3366*
3367* This routine should be called during a set channel of QAM/VSB
3368*
3369*/
3370static int set_mpegtei_handling(struct drx_demod_instance *demod)
3371{
3372        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3373        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3374        int rc;
3375        u16 fec_oc_dpr_mode = 0;
3376        u16 fec_oc_snc_mode = 0;
3377        u16 fec_oc_ems_mode = 0;
3378
3379        dev_addr = demod->my_i2c_dev_addr;
3380        ext_attr = (struct drxj_data *) demod->my_ext_attr;
3381
3382        rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
3383        if (rc != 0) {
3384                pr_err("error %d\n", rc);
3385                goto rw_error;
3386        }
3387        rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
3388        if (rc != 0) {
3389                pr_err("error %d\n", rc);
3390                goto rw_error;
3391        }
3392        rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
3393        if (rc != 0) {
3394                pr_err("error %d\n", rc);
3395                goto rw_error;
3396        }
3397
3398        /* reset to default, allow TEI bit to be changed */
3399        fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3400        fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3401                           FEC_OC_SNC_MODE_CORR_DISABLE__M));
3402        fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3403
3404        if (ext_attr->disable_te_ihandling) {
3405                /* do not change TEI bit */
3406                fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3407                fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3408                    ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3409                fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3410        }
3411
3412        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
3413        if (rc != 0) {
3414                pr_err("error %d\n", rc);
3415                goto rw_error;
3416        }
3417        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
3418        if (rc != 0) {
3419                pr_err("error %d\n", rc);
3420                goto rw_error;
3421        }
3422        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
3423        if (rc != 0) {
3424                pr_err("error %d\n", rc);
3425                goto rw_error;
3426        }
3427
3428        return 0;
3429rw_error:
3430        return rc;
3431}
3432
3433/*----------------------------------------------------------------------------*/
3434/*
3435* \fn int bit_reverse_mpeg_output()
3436* \brief Set MPEG output bit-endian settings.
3437* \param devmod  Pointer to demodulator instance.
3438* \return int.
3439*
3440* This routine should be called during a set channel of QAM/VSB
3441*
3442*/
3443static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3444{
3445        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3446        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3447        int rc;
3448        u16 fec_oc_ipr_mode = 0;
3449
3450        dev_addr = demod->my_i2c_dev_addr;
3451        ext_attr = (struct drxj_data *) demod->my_ext_attr;
3452
3453        rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
3454        if (rc != 0) {
3455                pr_err("error %d\n", rc);
3456                goto rw_error;
3457        }
3458
3459        /* reset to default (normal bit order) */
3460        fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3461
3462        if (ext_attr->bit_reverse_mpeg_outout)
3463                fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3464
3465        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
3466        if (rc != 0) {
3467                pr_err("error %d\n", rc);
3468                goto rw_error;
3469        }
3470
3471        return 0;
3472rw_error:
3473        return rc;
3474}
3475
3476/*----------------------------------------------------------------------------*/
3477/*
3478* \fn int set_mpeg_start_width()
3479* \brief Set MPEG start width.
3480* \param devmod  Pointer to demodulator instance.
3481* \return int.
3482*
3483* This routine should be called during a set channel of QAM/VSB
3484*
3485*/
3486static int set_mpeg_start_width(struct drx_demod_instance *demod)
3487{
3488        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3489        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3490        struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3491        int rc;
3492        u16 fec_oc_comm_mb = 0;
3493
3494        dev_addr = demod->my_i2c_dev_addr;
3495        ext_attr = (struct drxj_data *) demod->my_ext_attr;
3496        common_attr = demod->my_common_attr;
3497
3498        if ((common_attr->mpeg_cfg.static_clk == true)
3499            && (common_attr->mpeg_cfg.enable_parallel == false)) {
3500                rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
3501                if (rc != 0) {
3502                        pr_err("error %d\n", rc);
3503                        goto rw_error;
3504                }
3505                fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3506                if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3507                        fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3508                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
3509                if (rc != 0) {
3510                        pr_err("error %d\n", rc);
3511                        goto rw_error;
3512                }
3513        }
3514
3515        return 0;
3516rw_error:
3517        return rc;
3518}
3519
3520/*----------------------------------------------------------------------------*/
3521/* miscellaneous configurations - end                             */
3522/*----------------------------------------------------------------------------*/
3523
3524/*----------------------------------------------------------------------------*/
3525/* UIO Configuration Functions - begin                                        */
3526/*----------------------------------------------------------------------------*/
3527/*
3528* \fn int ctrl_set_uio_cfg()
3529* \brief Configure modus oprandi UIO.
3530* \param demod Pointer to demodulator instance.
3531* \param uio_cfg Pointer to a configuration setting for a certain UIO.
3532* \return int.
3533*/
3534static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3535{
3536        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3537        int rc;
3538
3539        if ((uio_cfg == NULL) || (demod == NULL))
3540                return -EINVAL;
3541
3542        ext_attr = (struct drxj_data *) demod->my_ext_attr;
3543
3544        /*  Write magic word to enable pdr reg write               */
3545        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3546        if (rc != 0) {
3547                pr_err("error %d\n", rc);
3548                goto rw_error;
3549        }
3550        switch (uio_cfg->uio) {
3551      /*====================================================================*/
3552        case DRX_UIO1:
3553                /* DRX_UIO1: SMA_TX UIO-1 */
3554                if (!ext_attr->has_smatx)
3555                        return -EIO;
3556                switch (uio_cfg->mode) {
3557                case DRX_UIO_MODE_FIRMWARE_SMA:
3558                case DRX_UIO_MODE_FIRMWARE_SAW:
3559                case DRX_UIO_MODE_READWRITE:
3560                        ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3561                        break;
3562                case DRX_UIO_MODE_DISABLE:
3563                        ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3564                        /* pad configuration register is set 0 - input mode */
3565                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
3566                        if (rc != 0) {
3567                                pr_err("error %d\n", rc);
3568                                goto rw_error;
3569                        }
3570                        break;
3571                default:
3572                        return -EINVAL;
3573                }               /* switch ( uio_cfg->mode ) */
3574                break;
3575      /*====================================================================*/
3576        case DRX_UIO2:
3577                /* DRX_UIO2: SMA_RX UIO-2 */
3578                if (!ext_attr->has_smarx)
3579                        return -EIO;
3580                switch (uio_cfg->mode) {
3581                case DRX_UIO_MODE_FIRMWARE0:
3582                case DRX_UIO_MODE_READWRITE:
3583                        ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3584                        break;
3585                case DRX_UIO_MODE_DISABLE:
3586                        ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3587                        /* pad configuration register is set 0 - input mode */
3588                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
3589                        if (rc != 0) {
3590                                pr_err("error %d\n", rc);
3591                                goto rw_error;
3592                        }
3593                        break;
3594                default:
3595                        return -EINVAL;
3596                }               /* switch ( uio_cfg->mode ) */
3597                break;
3598      /*====================================================================*/
3599        case DRX_UIO3:
3600                /* DRX_UIO3: GPIO UIO-3 */
3601                if (!ext_attr->has_gpio)
3602                        return -EIO;
3603                switch (uio_cfg->mode) {
3604                case DRX_UIO_MODE_FIRMWARE0:
3605                case DRX_UIO_MODE_READWRITE:
3606                        ext_attr->uio_gpio_mode = uio_cfg->mode;
3607                        break;
3608                case DRX_UIO_MODE_DISABLE:
3609                        ext_attr->uio_gpio_mode = uio_cfg->mode;
3610                        /* pad configuration register is set 0 - input mode */
3611                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
3612                        if (rc != 0) {
3613                                pr_err("error %d\n", rc);
3614                                goto rw_error;
3615                        }
3616                        break;
3617                default:
3618                        return -EINVAL;
3619                }               /* switch ( uio_cfg->mode ) */
3620                break;
3621      /*====================================================================*/
3622        case DRX_UIO4:
3623                /* DRX_UIO4: IRQN UIO-4 */
3624                if (!ext_attr->has_irqn)
3625                        return -EIO;
3626                switch (uio_cfg->mode) {
3627                case DRX_UIO_MODE_READWRITE:
3628                        ext_attr->uio_irqn_mode = uio_cfg->mode;
3629                        break;
3630                case DRX_UIO_MODE_DISABLE:
3631                        /* pad configuration register is set 0 - input mode */
3632                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
3633                        if (rc != 0) {
3634                                pr_err("error %d\n", rc);
3635                                goto rw_error;
3636                        }
3637                        ext_attr->uio_irqn_mode = uio_cfg->mode;
3638                        break;
3639                case DRX_UIO_MODE_FIRMWARE0:
3640                default:
3641                        return -EINVAL;
3642                }               /* switch ( uio_cfg->mode ) */
3643                break;
3644      /*====================================================================*/
3645        default:
3646                return -EINVAL;
3647        }                       /* switch ( uio_cfg->uio ) */
3648
3649        /*  Write magic word to disable pdr reg write               */
3650        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3651        if (rc != 0) {
3652                pr_err("error %d\n", rc);
3653                goto rw_error;
3654        }
3655
3656        return 0;
3657rw_error:
3658        return rc;
3659}
3660
3661/*
3662* \fn int ctrl_uio_write()
3663* \brief Write to a UIO.
3664* \param demod Pointer to demodulator instance.
3665* \param uio_data Pointer to data container for a certain UIO.
3666* \return int.
3667*/
3668static int
3669ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3670{
3671        struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3672        int rc;
3673        u16 pin_cfg_value = 0;
3674        u16 value = 0;
3675
3676        if ((uio_data == NULL) || (demod == NULL))
3677                return -EINVAL;
3678
3679        ext_attr = (struct drxj_data *) demod->my_ext_attr;
3680
3681        /*  Write magic word to enable pdr reg write               */
3682        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3683        if (rc != 0) {
3684                pr_err("error %d\n", rc);
3685                goto rw_error;
3686        }
3687        switch (uio_data->uio) {
3688      /*====================================================================*/
3689        case DRX_UIO1:
3690                /* DRX_UIO1: SMA_TX UIO-1 */
3691                if (!ext_attr->has_smatx)
3692                        return -EIO;
3693                if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3694                    && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3695                        return -EIO;
3696                }
3697                pin_cfg_value = 0;
3698                /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3699                pin_cfg_value |= 0x0113;
3700                /* io_pad_cfg_mode output mode is drive always */
3701                /* io_pad_cfg_drive is set to power 2 (23 mA) */
3702
3703                /* write to io pad configuration register - output mode */
3704                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
3705                if (rc != 0) {
3706                        pr_err("error %d\n", rc);
3707                        goto rw_error;
3708                }
3709
3710                /* use corresponding bit in io data output registar */
3711                rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3712                if (rc != 0) {
3713                        pr_err("error %d\n", rc);
3714                        goto rw_error;
3715                }
3716                if (!uio_data->value)
3717                        value &= 0x7FFF;        /* write zero to 15th bit - 1st UIO */
3718                else
3719                        value |= 0x8000;        /* write one to 15th bit - 1st UIO */
3720
3721                /* write back to io data output register */
3722                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3723                if (rc != 0) {
3724                        pr_err("error %d\n", rc);
3725                        goto rw_error;
3726                }
3727                break;
3728   /*======================================================================*/
3729        case DRX_UIO2:
3730                /* DRX_UIO2: SMA_RX UIO-2 */
3731                if (!ext_attr->has_smarx)
3732                        return -EIO;
3733                if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3734                        return -EIO;
3735
3736                pin_cfg_value = 0;
3737                /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3738                pin_cfg_value |= 0x0113;
3739                /* io_pad_cfg_mode output mode is drive always */
3740                /* io_pad_cfg_drive is set to power 2 (23 mA) */
3741
3742                /* write to io pad configuration register - output mode */
3743                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
3744                if (rc != 0) {
3745                        pr_err("error %d\n", rc);
3746                        goto rw_error;
3747                }
3748
3749                /* use corresponding bit in io data output registar */
3750                rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3751                if (rc != 0) {
3752                        pr_err("error %d\n", rc);
3753                        goto rw_error;
3754                }
3755                if (!uio_data->value)
3756                        value &= 0xBFFF;        /* write zero to 14th bit - 2nd UIO */
3757                else
3758                        value |= 0x4000;        /* write one to 14th bit - 2nd UIO */
3759
3760                /* write back to io data output register */
3761                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3762                if (rc != 0) {
3763                        pr_err("error %d\n", rc);
3764                        goto rw_error;
3765                }
3766                break;
3767   /*====================================================================*/
3768        case DRX_UIO3:
3769                /* DRX_UIO3: ASEL UIO-3 */
3770                if (!ext_attr->has_gpio)
3771                        return -EIO;
3772                if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
3773                        return -EIO;
3774
3775                pin_cfg_value = 0;
3776                /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3777                pin_cfg_value |= 0x0113;
3778                /* io_pad_cfg_mode output mode is drive always */
3779                /* io_pad_cfg_drive is set to power 2 (23 mA) */
3780
3781                /* write to io pad configuration register - output mode */
3782                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
3783                if (rc != 0) {
3784                        pr_err("error %d\n", rc);
3785                        goto rw_error;
3786                }
3787
3788                /* use corresponding bit in io data output registar */
3789                rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
3790                if (rc != 0) {
3791                        pr_err("error %d\n", rc);
3792                        goto rw_error;
3793                }
3794                if (!uio_data->value)
3795                        value &= 0xFFFB;        /* write zero to 2nd bit - 3rd UIO */
3796                else
3797                        value |= 0x0004;        /* write one to 2nd bit - 3rd UIO */
3798
3799                /* write back to io data output register */
3800                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
3801                if (rc != 0) {
3802                        pr_err("error %d\n", rc);
3803                        goto rw_error;
3804                }
3805                break;
3806   /*=====================================================================*/
3807        case DRX_UIO4:
3808                /* DRX_UIO4: IRQN UIO-4 */
3809                if (!ext_attr->has_irqn)
3810                        return -EIO;
3811
3812                if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
3813                        return -EIO;
3814
3815                pin_cfg_value = 0;
3816                /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3817                pin_cfg_value |= 0x0113;
3818                /* io_pad_cfg_mode output mode is drive always */
3819                /* io_pad_cfg_drive is set to power 2 (23 mA) */
3820
3821                /* write to io pad configuration register - output mode */
3822                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
3823                if (rc != 0) {
3824                        pr_err("error %d\n", rc);
3825                        goto rw_error;
3826                }
3827
3828                /* use corresponding bit in io data output registar */
3829                rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3830                if (rc != 0) {
3831                        pr_err("error %d\n", rc);
3832                        goto rw_error;
3833                }
3834                if (uio_data->value == false)
3835                        value &= 0xEFFF;        /* write zero to 12th bit - 4th UIO */
3836                else
3837                        value |= 0x1000;        /* write one to 12th bit - 4th UIO */
3838
3839                /* write back to io data output register */
3840                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3841                if (rc != 0) {
3842                        pr_err("error %d\n", rc);
3843                        goto rw_error;
3844                }
3845                break;
3846      /*=====================================================================*/
3847        default:
3848                return -EINVAL;
3849        }                       /* switch ( uio_data->uio ) */
3850
3851        /*  Write magic word to disable pdr reg write               */
3852        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3853        if (rc != 0) {
3854                pr_err("error %d\n", rc);
3855                goto rw_error;
3856        }
3857
3858        return 0;
3859rw_error:
3860        return rc;
3861}
3862
3863/*---------------------------------------------------------------------------*/
3864/* UIO Configuration Functions - end                                         */
3865/*---------------------------------------------------------------------------*/
3866
3867/*----------------------------------------------------------------------------*/
3868/* I2C Bridge Functions - begin                                               */
3869/*----------------------------------------------------------------------------*/
3870/*
3871* \fn int ctrl_i2c_bridge()
3872* \brief Open or close the I2C switch to tuner.
3873* \param demod Pointer to demodulator instance.
3874* \param bridge_closed Pointer to bool indication if bridge is closed not.
3875* \return int.
3876
3877*/
3878static int
3879ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
3880{
3881        struct drxj_hi_cmd hi_cmd;
3882        u16 result = 0;
3883
3884        /* check arguments */
3885        if (bridge_closed == NULL)
3886                return -EINVAL;
3887
3888        hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3889        hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
3890        if (*bridge_closed)
3891                hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
3892        else
3893                hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
3894
3895        return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
3896}
3897
3898/*----------------------------------------------------------------------------*/
3899/* I2C Bridge Functions - end                                                 */
3900/*----------------------------------------------------------------------------*/
3901
3902/*----------------------------------------------------------------------------*/
3903/* Smart antenna Functions - begin                                            */
3904/*----------------------------------------------------------------------------*/
3905/*
3906* \fn int smart_ant_init()
3907* \brief Initialize Smart Antenna.
3908* \param pointer to struct drx_demod_instance.
3909* \return int.
3910*
3911*/
3912static int smart_ant_init(struct drx_demod_instance *demod)
3913{
3914        struct drxj_data *ext_attr = NULL;
3915        struct i2c_device_addr *dev_addr = NULL;
3916        struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
3917        int rc;
3918        u16 data = 0;
3919
3920        dev_addr = demod->my_i2c_dev_addr;
3921        ext_attr = (struct drxj_data *) demod->my_ext_attr;
3922
3923        /*  Write magic word to enable pdr reg write               */
3924        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3925        if (rc != 0) {
3926                pr_err("error %d\n", rc);
3927                goto rw_error;
3928        }
3929        /* init smart antenna */
3930        rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
3931        if (rc != 0) {
3932                pr_err("error %d\n", rc);
3933                goto rw_error;
3934        }
3935        if (ext_attr->smart_ant_inverted) {
3936                rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
3937                if (rc != 0) {
3938                        pr_err("error %d\n", rc);
3939                        goto rw_error;
3940                }
3941        } else {
3942                rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
3943                if (rc != 0) {
3944                        pr_err("error %d\n", rc);
3945                        goto rw_error;
3946                }
3947        }
3948
3949        /* config SMA_TX pin to smart antenna mode */
3950        rc = ctrl_set_uio_cfg(demod, &uio_cfg);
3951        if (rc != 0) {
3952                pr_err("error %d\n", rc);
3953                goto rw_error;
3954        }
3955        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
3956        if (rc != 0) {
3957                pr_err("error %d\n", rc);
3958                goto rw_error;
3959        }
3960        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
3961        if (rc != 0) {
3962                pr_err("error %d\n", rc);
3963                goto rw_error;
3964        }
3965
3966        /*  Write magic word to disable pdr reg write               */
3967        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3968        if (rc != 0) {
3969                pr_err("error %d\n", rc);
3970                goto rw_error;
3971        }
3972
3973        return 0;
3974rw_error:
3975        return rc;
3976}
3977
3978static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
3979{
3980        int rc;
3981        u16 cur_cmd = 0;
3982        unsigned long timeout;
3983
3984        /* Check param */
3985        if (cmd == NULL)
3986                return -EINVAL;
3987
3988        /* Wait until SCU command interface is ready to receive command */
3989        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
3990        if (rc != 0) {
3991                pr_err("error %d\n", rc);
3992                goto rw_error;
3993        }
3994        if (cur_cmd != DRX_SCU_READY)
3995                return -EIO;
3996
3997        switch (cmd->parameter_len) {
3998        case 5:
3999                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
4000                if (rc != 0) {
4001                        pr_err("error %d\n", rc);
4002                        goto rw_error;
4003                }
4004                fallthrough;
4005        case 4:
4006                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
4007                if (rc != 0) {
4008                        pr_err("error %d\n", rc);
4009                        goto rw_error;
4010                }
4011                fallthrough;
4012        case 3:
4013                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
4014                if (rc != 0) {
4015                        pr_err("error %d\n", rc);
4016                        goto rw_error;
4017                }
4018                fallthrough;
4019        case 2:
4020                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
4021                if (rc != 0) {
4022                        pr_err("error %d\n", rc);
4023                        goto rw_error;
4024                }
4025                fallthrough;
4026        case 1:
4027                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
4028                if (rc != 0) {
4029                        pr_err("error %d\n", rc);
4030                        goto rw_error;
4031                }
4032                fallthrough;
4033        case 0:
4034                /* do nothing */
4035                break;
4036        default:
4037                /* this number of parameters is not supported */
4038                return -EIO;
4039        }
4040        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
4041        if (rc != 0) {
4042                pr_err("error %d\n", rc);
4043                goto rw_error;
4044        }
4045
4046        /* Wait until SCU has processed command */
4047        timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
4048        while (time_is_after_jiffies(timeout)) {
4049                rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4050                if (rc != 0) {
4051                        pr_err("error %d\n", rc);
4052                        goto rw_error;
4053                }
4054                if (cur_cmd == DRX_SCU_READY)
4055                        break;
4056                usleep_range(1000, 2000);
4057        }
4058
4059        if (cur_cmd != DRX_SCU_READY)
4060                return -EIO;
4061
4062        /* read results */
4063        if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4064                s16 err;
4065
4066                switch (cmd->result_len) {
4067                case 4:
4068                        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
4069                        if (rc != 0) {
4070                                pr_err("error %d\n", rc);
4071                                goto rw_error;
4072                        }
4073                        fallthrough;
4074                case 3:
4075                        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
4076                        if (rc != 0) {
4077                                pr_err("error %d\n", rc);
4078                                goto rw_error;
4079                        }
4080                        fallthrough;
4081                case 2:
4082                        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
4083                        if (rc != 0) {
4084                                pr_err("error %d\n", rc);
4085                                goto rw_error;
4086                        }
4087                        fallthrough;
4088                case 1:
4089                        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
4090                        if (rc != 0) {
4091                                pr_err("error %d\n", rc);
4092                                goto rw_error;
4093                        }
4094                        fallthrough;
4095                case 0:
4096                        /* do nothing */
4097                        break;
4098                default:
4099                        /* this number of parameters is not supported */
4100                        return -EIO;
4101                }
4102
4103                /* Check if an error was reported by SCU */
4104                err = cmd->result[0];
4105
4106                /* check a few fixed error codes */
4107                if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4108                    || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4109                    || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4110                    || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4111                    ) {
4112                        return -EINVAL;
4113                }
4114                /* here it is assumed that negative means error, and positive no error */
4115                else if (err < 0)
4116                        return -EIO;
4117                else
4118                        return 0;
4119        }
4120
4121        return 0;
4122
4123rw_error:
4124        return rc;
4125}
4126
4127/*
4128* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4129* \brief Basic access routine for SCU atomic read or write access
4130* \param dev_addr  pointer to i2c dev address
4131* \param addr     destination/source address
4132* \param datasize size of data buffer in bytes
4133* \param data     pointer to data buffer
4134* \return int
4135* \retval 0 Success
4136* \retval -EIO Timeout, I2C error, illegal bank
4137*
4138*/
4139#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4140static
4141int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 addr, u16 datasize,      /* max 30 bytes because the limit of SCU parameter */
4142                                              u8 *data, bool read_flag)
4143{
4144        struct drxjscu_cmd scu_cmd;
4145        int rc;
4146        u16 set_param_parameters[18];
4147        u16 cmd_result[15];
4148
4149        /* Parameter check */
4150        if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4151                return -EINVAL;
4152
4153        set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4154        if (read_flag) {                /* read */
4155                set_param_parameters[0] = ((~(0x0080)) & datasize);
4156                scu_cmd.parameter_len = 2;
4157                scu_cmd.result_len = datasize / 2 + 2;
4158        } else {
4159                int i = 0;
4160
4161                set_param_parameters[0] = 0x0080 | datasize;
4162                for (i = 0; i < (datasize / 2); i++) {
4163                        set_param_parameters[i + 2] =
4164                            (data[2 * i] | (data[(2 * i) + 1] << 8));
4165                }
4166                scu_cmd.parameter_len = datasize / 2 + 2;
4167                scu_cmd.result_len = 1;
4168        }
4169
4170        scu_cmd.command =
4171            SCU_RAM_COMMAND_STANDARD_TOP |
4172            SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4173        scu_cmd.result = cmd_result;
4174        scu_cmd.parameter = set_param_parameters;
4175        rc = scu_command(dev_addr, &scu_cmd);
4176        if (rc != 0) {
4177                pr_err("error %d\n", rc);
4178                goto rw_error;
4179        }
4180
4181        if (read_flag) {
4182                int i = 0;
4183                /* read data from buffer */
4184                for (i = 0; i < (datasize / 2); i++) {
4185                        data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4186                        data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4187                }
4188        }
4189
4190        return 0;
4191
4192rw_error:
4193        return rc;
4194
4195}
4196
4197/*============================================================================*/
4198
4199/*
4200* \fn int DRXJ_DAP_AtomicReadReg16()
4201* \brief Atomic read of 16 bits words
4202*/
4203static
4204int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4205                                         u32 addr,
4206                                         u16 *data, u32 flags)
4207{
4208        u8 buf[2] = { 0 };
4209        int rc;
4210        u16 word = 0;
4211
4212        if (!data)
4213                return -EINVAL;
4214
4215        rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
4216        if (rc < 0)
4217                return rc;
4218
4219        word = (u16) (buf[0] + (buf[1] << 8));
4220
4221        *data = word;
4222
4223        return rc;
4224}
4225
4226/*============================================================================*/
4227/*
4228* \fn int drxj_dap_scu_atomic_write_reg16()
4229* \brief Atomic read of 16 bits words
4230*/
4231static
4232int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4233                                          u32 addr,
4234                                          u16 data, u32 flags)
4235{
4236        u8 buf[2];
4237        int rc;
4238
4239        buf[0] = (u8) (data & 0xff);
4240        buf[1] = (u8) ((data >> 8) & 0xff);
4241
4242        rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
4243
4244        return rc;
4245}
4246
4247/* -------------------------------------------------------------------------- */
4248/*
4249* \brief Measure result of ADC synchronisation
4250* \param demod demod instance
4251* \param count (returned) count
4252* \return int.
4253* \retval 0    Success
4254* \retval -EIO Failure: I2C error
4255*
4256*/
4257static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4258{
4259        struct i2c_device_addr *dev_addr = NULL;
4260        int rc;
4261        u16 data = 0;
4262
4263        dev_addr = demod->my_i2c_dev_addr;
4264
4265        /* Start measurement */
4266        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
4267        if (rc != 0) {
4268                pr_err("error %d\n", rc);
4269                goto rw_error;
4270        }
4271        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
4272        if (rc != 0) {
4273                pr_err("error %d\n", rc);
4274                goto rw_error;
4275        }
4276
4277        /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4278        msleep(1);
4279
4280        *count = 0;
4281        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);
4282        if (rc != 0) {
4283                pr_err("error %d\n", rc);
4284                goto rw_error;
4285        }
4286        if (data == 127)
4287                *count = *count + 1;
4288        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);
4289        if (rc != 0) {
4290                pr_err("error %d\n", rc);
4291                goto rw_error;
4292        }
4293        if (data == 127)
4294                *count = *count + 1;
4295        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);
4296        if (rc != 0) {
4297                pr_err("error %d\n", rc);
4298                goto rw_error;
4299        }
4300        if (data == 127)
4301                *count = *count + 1;
4302
4303        return 0;
4304rw_error:
4305        return rc;
4306}
4307
4308/*
4309* \brief Synchronize analog and digital clock domains
4310* \param demod demod instance
4311* \return int.
4312* \retval 0    Success
4313* \retval -EIO Failure: I2C error or failure to synchronize
4314*
4315* An IQM reset will also reset the results of this synchronization.
4316* After an IQM reset this routine needs to be called again.
4317*
4318*/
4319
4320static int adc_synchronization(struct drx_demod_instance *demod)
4321{
4322        struct i2c_device_addr *dev_addr = NULL;
4323        int rc;
4324        u16 count = 0;
4325
4326        dev_addr = demod->my_i2c_dev_addr;
4327
4328        rc = adc_sync_measurement(demod, &count);
4329        if (rc != 0) {
4330                pr_err("error %d\n", rc);
4331                goto rw_error;
4332        }
4333
4334        if (count == 1) {
4335                /* Try sampling on a different edge */
4336                u16 clk_neg = 0;
4337
4338                rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
4339                if (rc != 0) {
4340                        pr_err("error %d\n", rc);
4341                        goto rw_error;
4342                }
4343
4344                clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4345                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
4346                if (rc != 0) {
4347                        pr_err("error %d\n", rc);
4348                        goto rw_error;
4349                }
4350
4351                rc = adc_sync_measurement(demod, &count);
4352                if (rc != 0) {
4353                        pr_err("error %d\n", rc);
4354                        goto rw_error;
4355                }
4356        }
4357
4358        /* TODO: implement fallback scenarios */
4359        if (count < 2)
4360                return -EIO;
4361
4362        return 0;
4363rw_error:
4364        return rc;
4365}
4366
4367/*============================================================================*/
4368/*==                      END AUXILIARY FUNCTIONS                           ==*/
4369/*============================================================================*/
4370
4371/*============================================================================*/
4372/*============================================================================*/
4373/*==                8VSB & QAM COMMON DATAPATH FUNCTIONS                    ==*/
4374/*============================================================================*/
4375/*============================================================================*/
4376/*
4377* \fn int init_agc ()
4378* \brief Initialize AGC for all standards.
4379* \param demod instance of demodulator.
4380* \param channel pointer to channel data.
4381* \return int.
4382*/
4383static int init_agc(struct drx_demod_instance *demod)
4384{
4385        struct i2c_device_addr *dev_addr = NULL;
4386        struct drx_common_attr *common_attr = NULL;
4387        struct drxj_data *ext_attr = NULL;
4388        struct drxj_cfg_agc *p_agc_rf_settings = NULL;
4389        struct drxj_cfg_agc *p_agc_if_settings = NULL;
4390        int rc;
4391        u16 ingain_tgt_max = 0;
4392        u16 clp_dir_to = 0;
4393        u16 sns_sum_max = 0;
4394        u16 clp_sum_max = 0;
4395        u16 sns_dir_to = 0;
4396        u16 ki_innergain_min = 0;
4397        u16 agc_ki = 0;
4398        u16 ki_max = 0;
4399        u16 if_iaccu_hi_tgt_min = 0;
4400        u16 data = 0;
4401        u16 agc_ki_dgain = 0;
4402        u16 ki_min = 0;
4403        u16 clp_ctrl_mode = 0;
4404        u16 agc_rf = 0;
4405        u16 agc_if = 0;
4406
4407        dev_addr = demod->my_i2c_dev_addr;
4408        common_attr = (struct drx_common_attr *) demod->my_common_attr;
4409        ext_attr = (struct drxj_data *) demod->my_ext_attr;
4410
4411        switch (ext_attr->standard) {
4412        case DRX_STANDARD_8VSB:
4413                clp_sum_max = 1023;
4414                clp_dir_to = (u16) (-9);
4415                sns_sum_max = 1023;
4416                sns_dir_to = (u16) (-9);
4417                ki_innergain_min = (u16) (-32768);
4418                ki_max = 0x032C;
4419                agc_ki_dgain = 0xC;
4420                if_iaccu_hi_tgt_min = 2047;
4421                ki_min = 0x0117;
4422                ingain_tgt_max = 16383;
4423                clp_ctrl_mode = 0;
4424                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
4425                if (rc != 0) {
4426                        pr_err("error %d\n", rc);
4427                        goto rw_error;
4428                }
4429                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
4430                if (rc != 0) {
4431                        pr_err("error %d\n", rc);
4432                        goto rw_error;
4433                }
4434                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
4435                if (rc != 0) {
4436                        pr_err("error %d\n", rc);
4437                        goto rw_error;
4438                }
4439                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
4440                if (rc != 0) {
4441                        pr_err("error %d\n", rc);
4442                        goto rw_error;
4443                }
4444                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
4445                if (rc != 0) {
4446                        pr_err("error %d\n", rc);
4447                        goto rw_error;
4448                }
4449                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
4450                if (rc != 0) {
4451                        pr_err("error %d\n", rc);
4452                        goto rw_error;
4453                }
4454                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
4455                if (rc != 0) {
4456                        pr_err("error %d\n", rc);
4457                        goto rw_error;
4458                }
4459                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
4460                if (rc != 0) {
4461                        pr_err("error %d\n", rc);
4462                        goto rw_error;
4463                }
4464                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
4465                if (rc != 0) {
4466                        pr_err("error %d\n", rc);
4467                        goto rw_error;
4468                }
4469                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
4470                if (rc != 0) {
4471                        pr_err("error %d\n", rc);
4472                        goto rw_error;
4473                }
4474                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
4475                if (rc != 0) {
4476                        pr_err("error %d\n", rc);
4477                        goto rw_error;
4478                }
4479                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
4480                if (rc != 0) {
4481                        pr_err("error %d\n", rc);
4482                        goto rw_error;
4483                }
4484                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
4485                if (rc != 0) {
4486                        pr_err("error %d\n", rc);
4487                        goto rw_error;
4488                }
4489                p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
4490                p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
4491                break;
4492#ifndef DRXJ_VSB_ONLY
4493        case DRX_STANDARD_ITU_A:
4494        case DRX_STANDARD_ITU_C:
4495        case DRX_STANDARD_ITU_B:
4496                ingain_tgt_max = 5119;
4497                clp_sum_max = 1023;
4498                clp_dir_to = (u16) (-5);
4499                sns_sum_max = 127;
4500                sns_dir_to = (u16) (-3);
4501                ki_innergain_min = 0;
4502                ki_max = 0x0657;
4503                if_iaccu_hi_tgt_min = 2047;
4504                agc_ki_dgain = 0x7;
4505                ki_min = 0x0117;
4506                clp_ctrl_mode = 0;
4507                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
4508                if (rc != 0) {
4509                        pr_err("error %d\n", rc);
4510                        goto rw_error;
4511                }
4512                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
4513                if (rc != 0) {
4514                        pr_err("error %d\n", rc);
4515                        goto rw_error;
4516                }
4517                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
4518                if (rc != 0) {
4519                        pr_err("error %d\n", rc);
4520                        goto rw_error;
4521                }
4522                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
4523                if (rc != 0) {
4524                        pr_err("error %d\n", rc);
4525                        goto rw_error;
4526                }
4527                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
4528                if (rc != 0) {
4529                        pr_err("error %d\n", rc);
4530                        goto rw_error;
4531                }
4532                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
4533                if (rc != 0) {
4534                        pr_err("error %d\n", rc);
4535                        goto rw_error;
4536                }
4537                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
4538                if (rc != 0) {
4539                        pr_err("error %d\n", rc);
4540                        goto rw_error;
4541                }
4542                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
4543                if (rc != 0) {
4544                        pr_err("error %d\n", rc);
4545                        goto rw_error;
4546                }
4547                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
4548                if (rc != 0) {
4549                        pr_err("error %d\n", rc);
4550                        goto rw_error;
4551                }
4552                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
4553                if (rc != 0) {
4554                        pr_err("error %d\n", rc);
4555                        goto rw_error;
4556                }
4557                p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
4558                p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
4559                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
4560                if (rc != 0) {
4561                        pr_err("error %d\n", rc);
4562                        goto rw_error;
4563                }
4564
4565                rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
4566                if (rc != 0) {
4567                        pr_err("error %d\n", rc);
4568                        goto rw_error;
4569                }
4570                agc_ki &= 0xf000;
4571                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
4572                if (rc != 0) {
4573                        pr_err("error %d\n", rc);
4574                        goto rw_error;
4575                }
4576                break;
4577#endif
4578        default:
4579                return -EINVAL;
4580        }
4581
4582        /* for new AGC interface */
4583        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
4584        if (rc != 0) {
4585                pr_err("error %d\n", rc);
4586                goto rw_error;
4587        }
4588        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
4589        if (rc != 0) {
4590                pr_err("error %d\n", rc);
4591                goto rw_error;
4592        }       /* Gain fed from inner to outer AGC */
4593        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
4594        if (rc != 0) {
4595                pr_err("error %d\n", rc);
4596                goto rw_error;
4597        }
4598        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
4599        if (rc != 0) {
4600                pr_err("error %d\n", rc);
4601                goto rw_error;
4602        }
4603        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
4604        if (rc != 0) {
4605                pr_err("error %d\n", rc);
4606                goto rw_error;
4607        }       /* set to p_agc_settings->top before */
4608        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
4609        if (rc != 0) {
4610                pr_err("error %d\n", rc);
4611                goto rw_error;
4612        }
4613        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
4614        if (rc != 0) {
4615                pr_err("error %d\n", rc);
4616                goto rw_error;
4617        }
4618        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
4619        if (rc != 0) {
4620                pr_err("error %d\n", rc);
4621                goto rw_error;
4622        }
4623        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
4624        if (rc != 0) {
4625                pr_err("error %d\n", rc);
4626                goto rw_error;
4627        }
4628        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
4629        if (rc != 0) {
4630                pr_err("error %d\n", rc);
4631                goto rw_error;
4632        }
4633        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
4634        if (rc != 0) {
4635                pr_err("error %d\n", rc);
4636                goto rw_error;
4637        }
4638        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
4639        if (rc != 0) {
4640                pr_err("error %d\n", rc);
4641                goto rw_error;
4642        }
4643        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
4644        if (rc != 0) {
4645                pr_err("error %d\n", rc);
4646                goto rw_error;
4647        }
4648        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
4649        if (rc != 0) {
4650                pr_err("error %d\n", rc);
4651                goto rw_error;
4652        }
4653        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
4654        if (rc != 0) {
4655                pr_err("error %d\n", rc);
4656                goto rw_error;
4657        }
4658        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
4659        if (rc != 0) {
4660                pr_err("error %d\n", rc);
4661                goto rw_error;
4662        }
4663        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
4664        if (rc != 0) {
4665                pr_err("error %d\n", rc);
4666                goto rw_error;
4667        }
4668        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
4669        if (rc != 0) {
4670                pr_err("error %d\n", rc);
4671                goto rw_error;
4672        }
4673        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
4674        if (rc != 0) {
4675                pr_err("error %d\n", rc);
4676                goto rw_error;
4677        }
4678        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
4679        if (rc != 0) {
4680                pr_err("error %d\n", rc);
4681                goto rw_error;
4682        }
4683        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
4684        if (rc != 0) {
4685                pr_err("error %d\n", rc);
4686                goto rw_error;
4687        }
4688        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
4689        if (rc != 0) {
4690                pr_err("error %d\n", rc);
4691                goto rw_error;
4692        }
4693        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
4694        if (rc != 0) {
4695                pr_err("error %d\n", rc);
4696                goto rw_error;
4697        }
4698        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
4699        if (rc != 0) {
4700                pr_err("error %d\n", rc);
4701                goto rw_error;
4702        }
4703        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
4704        if (rc != 0) {
4705                pr_err("error %d\n", rc);
4706                goto rw_error;
4707        }
4708        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
4709        if (rc != 0) {
4710                pr_err("error %d\n", rc);
4711                goto rw_error;
4712        }
4713
4714        agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
4715        if (common_attr->tuner_rf_agc_pol == true)
4716                agc_rf = 0x87ff - agc_rf;
4717
4718        agc_if = 0x800;
4719        if (common_attr->tuner_if_agc_pol == true)
4720                agc_rf = 0x87ff - agc_rf;
4721
4722        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
4723        if (rc != 0) {
4724                pr_err("error %d\n", rc);
4725                goto rw_error;
4726        }
4727        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
4728        if (rc != 0) {
4729                pr_err("error %d\n", rc);
4730                goto rw_error;
4731        }
4732
4733        /* Set/restore Ki DGAIN factor */
4734        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
4735        if (rc != 0) {
4736                pr_err("error %d\n", rc);
4737                goto rw_error;
4738        }
4739        data &= ~SCU_RAM_AGC_KI_DGAIN__M;
4740        data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
4741        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
4742        if (rc != 0) {
4743                pr_err("error %d\n", rc);
4744                goto rw_error;
4745        }
4746
4747        return 0;
4748rw_error:
4749        return rc;
4750}
4751
4752/*
4753* \fn int set_frequency ()
4754* \brief Set frequency shift.
4755* \param demod instance of demodulator.
4756* \param channel pointer to channel data.
4757* \param tuner_freq_offset residual frequency from tuner.
4758* \return int.
4759*/
4760static int
4761set_frequency(struct drx_demod_instance *demod,
4762              struct drx_channel *channel, s32 tuner_freq_offset)
4763{
4764        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4765        struct drxj_data *ext_attr = demod->my_ext_attr;
4766        int rc;
4767        s32 sampling_frequency = 0;
4768        s32 frequency_shift = 0;
4769        s32 if_freq_actual = 0;
4770        s32 rf_freq_residual = -1 * tuner_freq_offset;
4771        s32 adc_freq = 0;
4772        s32 intermediate_freq = 0;
4773        u32 iqm_fs_rate_ofs = 0;
4774        bool adc_flip = true;
4775        bool select_pos_image = false;
4776        bool rf_mirror;
4777        bool tuner_mirror;
4778        bool image_to_select;
4779        s32 fm_frequency_shift = 0;
4780
4781        rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
4782        tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
4783        /*
4784           Program frequency shifter
4785           No need to account for mirroring on RF
4786         */
4787        switch (ext_attr->standard) {
4788        case DRX_STANDARD_ITU_A:
4789        case DRX_STANDARD_ITU_C:
4790        case DRX_STANDARD_PAL_SECAM_LP:
4791        case DRX_STANDARD_8VSB:
4792                select_pos_image = true;
4793                break;
4794        case DRX_STANDARD_FM:
4795                /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4796                   Sound carrier is already 3Mhz above centre frequency due
4797                   to tuner setting so now add an extra shift of 1MHz... */
4798                fm_frequency_shift = 1000;
4799                fallthrough;
4800        case DRX_STANDARD_ITU_B:
4801        case DRX_STANDARD_NTSC:
4802        case DRX_STANDARD_PAL_SECAM_BG:
4803        case DRX_STANDARD_PAL_SECAM_DK:
4804        case DRX_STANDARD_PAL_SECAM_I:
4805        case DRX_STANDARD_PAL_SECAM_L:
4806                select_pos_image = false;
4807                break;
4808        default:
4809                return -EINVAL;
4810        }
4811        intermediate_freq = demod->my_common_attr->intermediate_freq;
4812        sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
4813        if (tuner_mirror)
4814                if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
4815        else
4816                if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
4817        if (if_freq_actual > sampling_frequency / 2) {
4818                /* adc mirrors */
4819                adc_freq = sampling_frequency - if_freq_actual;
4820                adc_flip = true;
4821        } else {
4822                /* adc doesn't mirror */
4823                adc_freq = if_freq_actual;
4824                adc_flip = false;
4825        }
4826
4827        frequency_shift = adc_freq;
4828        image_to_select =
4829            (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
4830        iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
4831
4832        if (image_to_select)
4833                iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
4834
4835        /* Program frequency shifter with tuner offset compensation */
4836        /* frequency_shift += tuner_freq_offset; TODO */
4837        rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
4838        if (rc != 0) {
4839                pr_err("error %d\n", rc);
4840                goto rw_error;
4841        }
4842        ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
4843        ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
4844
4845        return 0;
4846rw_error:
4847        return rc;
4848}
4849
4850/*
4851* \fn int get_acc_pkt_err()
4852* \brief Retrieve signal strength for VSB and QAM.
4853* \param demod Pointer to demod instance
4854* \param packet_err Pointer to packet error
4855* \return int.
4856* \retval 0 sig_strength contains valid data.
4857* \retval -EINVAL sig_strength is NULL.
4858* \retval -EIO Erroneous data, sig_strength contains invalid data.
4859*/
4860#ifdef DRXJ_SIGNAL_ACCUM_ERR
4861static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
4862{
4863        int rc;
4864        static u16 pkt_err;
4865        static u16 last_pkt_err;
4866        u16 data = 0;
4867        struct drxj_data *ext_attr = NULL;
4868        struct i2c_device_addr *dev_addr = NULL;
4869
4870        ext_attr = (struct drxj_data *) demod->my_ext_attr;
4871        dev_addr = demod->my_i2c_dev_addr;
4872
4873        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
4874        if (rc != 0) {
4875                pr_err("error %d\n", rc);
4876                goto rw_error;
4877        }
4878        if (ext_attr->reset_pkt_err_acc) {
4879                last_pkt_err = data;
4880                pkt_err = 0;
4881                ext_attr->reset_pkt_err_acc = false;
4882        }
4883
4884        if (data < last_pkt_err) {
4885                pkt_err += 0xffff - last_pkt_err;
4886                pkt_err += data;
4887        } else {
4888                pkt_err += (data - last_pkt_err);
4889        }
4890        *packet_err = pkt_err;
4891        last_pkt_err = data;
4892
4893        return 0;
4894rw_error:
4895        return rc;
4896}
4897#endif
4898
4899
4900/*============================================================================*/
4901
4902/*
4903* \fn int set_agc_rf ()
4904* \brief Configure RF AGC
4905* \param demod instance of demodulator.
4906* \param agc_settings AGC configuration structure
4907* \return int.
4908*/
4909static int
4910set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
4911{
4912        struct i2c_device_addr *dev_addr = NULL;
4913        struct drxj_data *ext_attr = NULL;
4914        struct drxj_cfg_agc *p_agc_settings = NULL;
4915        struct drx_common_attr *common_attr = NULL;
4916        int rc;
4917        drx_write_reg16func_t scu_wr16 = NULL;
4918        drx_read_reg16func_t scu_rr16 = NULL;
4919
4920        common_attr = (struct drx_common_attr *) demod->my_common_attr;
4921        dev_addr = demod->my_i2c_dev_addr;
4922        ext_attr = (struct drxj_data *) demod->my_ext_attr;
4923
4924        if (atomic) {
4925                scu_rr16 = drxj_dap_scu_atomic_read_reg16;
4926                scu_wr16 = drxj_dap_scu_atomic_write_reg16;
4927        } else {
4928                scu_rr16 = drxj_dap_read_reg16;
4929                scu_wr16 = drxj_dap_write_reg16;
4930        }
4931
4932        /* Configure AGC only if standard is currently active */
4933        if ((ext_attr->standard == agc_settings->standard) ||
4934            (DRXJ_ISQAMSTD(ext_attr->standard) &&
4935             DRXJ_ISQAMSTD(agc_settings->standard)) ||
4936            (DRXJ_ISATVSTD(ext_attr->standard) &&
4937             DRXJ_ISATVSTD(agc_settings->standard))) {
4938                u16 data = 0;
4939
4940                switch (agc_settings->ctrl_mode) {
4941                case DRX_AGC_CTRL_AUTO:
4942
4943                        /* Enable RF AGC DAC */
4944                        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
4945                        if (rc != 0) {
4946                                pr_err("error %d\n", rc);
4947                                goto rw_error;
4948                        }
4949                        data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
4950                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
4951                        if (rc != 0) {
4952                                pr_err("error %d\n", rc);
4953                                goto rw_error;
4954                        }
4955
4956                        /* Enable SCU RF AGC loop */
4957                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
4958                        if (rc != 0) {
4959                                pr_err("error %d\n", rc);
4960                                goto rw_error;
4961                        }
4962                        data &= ~SCU_RAM_AGC_KI_RF__M;
4963                        if (ext_attr->standard == DRX_STANDARD_8VSB)
4964                                data |= (2 << SCU_RAM_AGC_KI_RF__B);
4965                        else if (DRXJ_ISQAMSTD(ext_attr->standard))
4966                                data |= (5 << SCU_RAM_AGC_KI_RF__B);
4967                        else
4968                                data |= (4 << SCU_RAM_AGC_KI_RF__B);
4969
4970                        if (common_attr->tuner_rf_agc_pol)
4971                                data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
4972                        else
4973                                data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
4974                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
4975                        if (rc != 0) {
4976                                pr_err("error %d\n", rc);
4977                                goto rw_error;
4978                        }
4979
4980                        /* Set speed ( using complementary reduction value ) */
4981                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
4982                        if (rc != 0) {
4983                                pr_err("error %d\n", rc);
4984                                goto rw_error;
4985                        }
4986                        data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
4987                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_RAGC_RED__B) & SCU_RAM_AGC_KI_RED_RAGC_RED__M) | data, 0);
4988                        if (rc != 0) {
4989                                pr_err("error %d\n", rc);
4990                                goto rw_error;
4991                        }
4992
4993                        if (agc_settings->standard == DRX_STANDARD_8VSB)
4994                                p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
4995                        else if (DRXJ_ISQAMSTD(agc_settings->standard))
4996                                p_agc_settings = &(ext_attr->qam_if_agc_cfg);
4997                        else if (DRXJ_ISATVSTD(agc_settings->standard))
4998                                p_agc_settings = &(ext_attr->atv_if_agc_cfg);
4999                        else
5000                                return -EINVAL;
5001
5002                        /* Set TOP, only if IF-AGC is in AUTO mode */
5003                        if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5004                                rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
5005                                if (rc != 0) {
5006                                        pr_err("error %d\n", rc);
5007                                        goto rw_error;
5008                                }
5009                                rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
5010                                if (rc != 0) {
5011                                        pr_err("error %d\n", rc);
5012                                        goto rw_error;
5013                                }
5014                        }
5015
5016                        /* Cut-Off current */
5017                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
5018                        if (rc != 0) {
5019                                pr_err("error %d\n", rc);
5020                                goto rw_error;
5021                        }
5022                        break;
5023                case DRX_AGC_CTRL_USER:
5024
5025                        /* Enable RF AGC DAC */
5026                        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5027                        if (rc != 0) {
5028                                pr_err("error %d\n", rc);
5029                                goto rw_error;
5030                        }
5031                        data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
5032                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5033                        if (rc != 0) {
5034                                pr_err("error %d\n", rc);
5035                                goto rw_error;
5036                        }
5037
5038                        /* Disable SCU RF AGC loop */
5039                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5040                        if (rc != 0) {
5041                                pr_err("error %d\n", rc);
5042                                goto rw_error;
5043                        }
5044                        data &= ~SCU_RAM_AGC_KI_RF__M;
5045                        if (common_attr->tuner_rf_agc_pol)
5046                                data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5047                        else
5048                                data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5049                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5050                        if (rc != 0) {
5051                                pr_err("error %d\n", rc);
5052                                goto rw_error;
5053                        }
5054
5055                        /* Write value to output pin */
5056                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
5057                        if (rc != 0) {
5058                                pr_err("error %d\n", rc);
5059                                goto rw_error;
5060                        }
5061                        break;
5062                case DRX_AGC_CTRL_OFF:
5063
5064                        /* Disable RF AGC DAC */
5065                        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5066                        if (rc != 0) {
5067                                pr_err("error %d\n", rc);
5068                                goto rw_error;
5069                        }
5070                        data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5071                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5072                        if (rc != 0) {
5073                                pr_err("error %d\n", rc);
5074                                goto rw_error;
5075                        }
5076
5077                        /* Disable SCU RF AGC loop */
5078                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5079                        if (rc != 0) {
5080                                pr_err("error %d\n", rc);
5081                                goto rw_error;
5082                        }
5083                        data &= ~SCU_RAM_AGC_KI_RF__M;
5084                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5085                        if (rc != 0) {
5086                                pr_err("error %d\n", rc);
5087                                goto rw_error;
5088                        }
5089                        break;
5090                default:
5091                        return -EINVAL;
5092                }               /* switch ( agcsettings->ctrl_mode ) */
5093        }
5094
5095        /* Store rf agc settings */
5096        switch (agc_settings->standard) {
5097        case DRX_STANDARD_8VSB:
5098                ext_attr->vsb_rf_agc_cfg = *agc_settings;
5099                break;
5100#ifndef DRXJ_VSB_ONLY
5101        case DRX_STANDARD_ITU_A:
5102        case DRX_STANDARD_ITU_B:
5103        case DRX_STANDARD_ITU_C:
5104                ext_attr->qam_rf_agc_cfg = *agc_settings;
5105                break;
5106#endif
5107        default:
5108                return -EIO;
5109        }
5110
5111        return 0;
5112rw_error:
5113        return rc;
5114}
5115
5116/*
5117* \fn int set_agc_if ()
5118* \brief Configure If AGC
5119* \param demod instance of demodulator.
5120* \param agc_settings AGC configuration structure
5121* \return int.
5122*/
5123static int
5124set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
5125{
5126        struct i2c_device_addr *dev_addr = NULL;
5127        struct drxj_data *ext_attr = NULL;
5128        struct drxj_cfg_agc *p_agc_settings = NULL;
5129        struct drx_common_attr *common_attr = NULL;
5130        drx_write_reg16func_t scu_wr16 = NULL;
5131        drx_read_reg16func_t scu_rr16 = NULL;
5132        int rc;
5133
5134        common_attr = (struct drx_common_attr *) demod->my_common_attr;
5135        dev_addr = demod->my_i2c_dev_addr;
5136        ext_attr = (struct drxj_data *) demod->my_ext_attr;
5137
5138        if (atomic) {
5139                scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5140                scu_wr16 = drxj_dap_scu_atomic_write_reg16;
5141        } else {
5142                scu_rr16 = drxj_dap_read_reg16;
5143                scu_wr16 = drxj_dap_write_reg16;
5144        }
5145
5146        /* Configure AGC only if standard is currently active */
5147        if ((ext_attr->standard == agc_settings->standard) ||
5148            (DRXJ_ISQAMSTD(ext_attr->standard) &&
5149             DRXJ_ISQAMSTD(agc_settings->standard)) ||
5150            (DRXJ_ISATVSTD(ext_attr->standard) &&
5151             DRXJ_ISATVSTD(agc_settings->standard))) {
5152                u16 data = 0;
5153
5154                switch (agc_settings->ctrl_mode) {
5155                case DRX_AGC_CTRL_AUTO:
5156                        /* Enable IF AGC DAC */
5157                        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5158                        if (rc != 0) {
5159                                pr_err("error %d\n", rc);
5160                                goto rw_error;
5161                        }
5162                        data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5163                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5164                        if (rc != 0) {
5165                                pr_err("error %d\n", rc);
5166                                goto rw_error;
5167                        }
5168
5169                        /* Enable SCU IF AGC loop */
5170                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5171                        if (rc != 0) {
5172                                pr_err("error %d\n", rc);
5173                                goto rw_error;
5174                        }
5175                        data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5176                        data &= ~SCU_RAM_AGC_KI_IF__M;
5177                        if (ext_attr->standard == DRX_STANDARD_8VSB)
5178                                data |= (3 << SCU_RAM_AGC_KI_IF__B);
5179                        else if (DRXJ_ISQAMSTD(ext_attr->standard))
5180                                data |= (6 << SCU_RAM_AGC_KI_IF__B);
5181                        else
5182                                data |= (5 << SCU_RAM_AGC_KI_IF__B);
5183
5184                        if (common_attr->tuner_if_agc_pol)
5185                                data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5186                        else
5187                                data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5188                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5189                        if (rc != 0) {
5190                                pr_err("error %d\n", rc);
5191                                goto rw_error;
5192                        }
5193
5194                        /* Set speed (using complementary reduction value) */
5195                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
5196                        if (rc != 0) {
5197                                pr_err("error %d\n", rc);
5198                                goto rw_error;
5199                        }
5200                        data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
5201                        rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_IAGC_RED__B) & SCU_RAM_AGC_KI_RED_IAGC_RED__M) | data, 0);
5202                        if (rc != 0) {
5203                                pr_err("error %d\n", rc);
5204                                goto rw_error;
5205                        }
5206
5207                        if (agc_settings->standard == DRX_STANDARD_8VSB)
5208                                p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
5209                        else if (DRXJ_ISQAMSTD(agc_settings->standard))
5210                                p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
5211                        else if (DRXJ_ISATVSTD(agc_settings->standard))
5212                                p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
5213                        else
5214                                return -EINVAL;
5215
5216                        /* Restore TOP */
5217                        if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5218                                rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
5219                                if (rc != 0) {
5220                                        pr_err("error %d\n", rc);
5221                                        goto rw_error;
5222                                }
5223                                rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
5224                                if (rc != 0) {
5225                                        pr_err("error %d\n", rc);
5226                                        goto rw_error;
5227                                }
5228                        } else {
5229                                rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
5230                                if (rc != 0) {
5231                                        pr_err("error %d\n", rc);
5232                                        goto rw_error;
5233                                }
5234                                rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
5235                                if (rc != 0) {
5236                                        pr_err("error %d\n", rc);
5237                                        goto rw_error;
5238                                }
5239                        }
5240                        break;
5241
5242                case DRX_AGC_CTRL_USER:
5243
5244                        /* Enable IF AGC DAC */
5245                        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5246                        if (rc != 0) {
5247                                pr_err("error %d\n", rc);
5248                                goto rw_error;
5249                        }
5250                        data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5251                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5252                        if (rc != 0) {
5253                                pr_err("error %d\n", rc);
5254                                goto rw_error;
5255                        }
5256
5257                        /* Disable SCU IF AGC loop */
5258                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5259                        if (rc != 0) {
5260                                pr_err("error %d\n", rc);
5261                                goto rw_error;
5262                        }
5263                        data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5264                        data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5265                        if (common_attr->tuner_if_agc_pol)
5266                                data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5267                        else
5268                                data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5269                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5270                        if (rc != 0) {
5271                                pr_err("error %d\n", rc);
5272                                goto rw_error;
5273                        }
5274
5275                        /* Write value to output pin */
5276                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
5277                        if (rc != 0) {
5278                                pr_err("error %d\n", rc);
5279                                goto rw_error;
5280                        }
5281                        break;
5282
5283                case DRX_AGC_CTRL_OFF:
5284
5285                        /* Disable If AGC DAC */
5286                        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5287                        if (rc != 0) {
5288                                pr_err("error %d\n", rc);
5289                                goto rw_error;
5290                        }
5291                        data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
5292                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5293                        if (rc != 0) {
5294                                pr_err("error %d\n", rc);
5295                                goto rw_error;
5296                        }
5297
5298                        /* Disable SCU IF AGC loop */
5299                        rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5300                        if (rc != 0) {
5301                                pr_err("error %d\n", rc);
5302                                goto rw_error;
5303                        }
5304                        data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5305                        data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5306                        rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5307                        if (rc != 0) {
5308                                pr_err("error %d\n", rc);
5309                                goto rw_error;
5310                        }
5311                        break;
5312                default:
5313                        return -EINVAL;
5314                }               /* switch ( agcsettings->ctrl_mode ) */
5315
5316                /* always set the top to support configurations without if-loop */
5317                rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
5318                if (rc != 0) {
5319                        pr_err("error %d\n", rc);
5320                        goto rw_error;
5321                }
5322        }
5323
5324        /* Store if agc settings */
5325        switch (agc_settings->standard) {
5326        case DRX_STANDARD_8VSB:
5327                ext_attr->vsb_if_agc_cfg = *agc_settings;
5328                break;
5329#ifndef DRXJ_VSB_ONLY
5330        case DRX_STANDARD_ITU_A:
5331        case DRX_STANDARD_ITU_B:
5332        case DRX_STANDARD_ITU_C:
5333                ext_attr->qam_if_agc_cfg = *agc_settings;
5334                break;
5335#endif
5336        default:
5337                return -EIO;
5338        }
5339
5340        return 0;
5341rw_error:
5342        return rc;
5343}
5344
5345/*
5346* \fn int set_iqm_af ()
5347* \brief Configure IQM AF registers
5348* \param demod instance of demodulator.
5349* \param active
5350* \return int.
5351*/
5352static int set_iqm_af(struct drx_demod_instance *demod, bool active)
5353{
5354        u16 data = 0;
5355        struct i2c_device_addr *dev_addr = NULL;
5356        int rc;
5357
5358        dev_addr = demod->my_i2c_dev_addr;
5359
5360        /* Configure IQM */
5361        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5362        if (rc != 0) {
5363                pr_err("error %d\n", rc);
5364                goto rw_error;
5365        }
5366        if (!active)
5367                data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE));
5368        else
5369                data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5370        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5371        if (rc != 0) {
5372                pr_err("error %d\n", rc);
5373                goto rw_error;
5374        }
5375
5376        return 0;
5377rw_error:
5378        return rc;
5379}
5380
5381/*============================================================================*/
5382/*==              END 8VSB & QAM COMMON DATAPATH FUNCTIONS                  ==*/
5383/*============================================================================*/
5384
5385/*============================================================================*/
5386/*============================================================================*/
5387/*==                       8VSB DATAPATH FUNCTIONS                          ==*/
5388/*============================================================================*/
5389/*============================================================================*/
5390
5391/*
5392* \fn int power_down_vsb ()
5393* \brief Powr down QAM related blocks.
5394* \param demod instance of demodulator.
5395* \param channel pointer to channel data.
5396* \return int.
5397*/
5398static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
5399{
5400        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5401        struct drxjscu_cmd cmd_scu = { /* command     */ 0,
5402                /* parameter_len */ 0,
5403                /* result_len    */ 0,
5404                /* *parameter   */ NULL,
5405                /* *result      */ NULL
5406        };
5407        struct drx_cfg_mpeg_output cfg_mpeg_output;
5408        int rc;
5409        u16 cmd_result = 0;
5410
5411        /*
5412           STOP demodulator
5413           reset of FEC and VSB HW
5414         */
5415        cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
5416            SCU_RAM_COMMAND_CMD_DEMOD_STOP;
5417        cmd_scu.parameter_len = 0;
5418        cmd_scu.result_len = 1;
5419        cmd_scu.parameter = NULL;
5420        cmd_scu.result = &cmd_result;
5421        rc = scu_command(dev_addr, &cmd_scu);
5422        if (rc != 0) {
5423                pr_err("error %d\n", rc);
5424                goto rw_error;
5425        }
5426
5427        /* stop all comm_exec */
5428        rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
5429        if (rc != 0) {
5430                pr_err("error %d\n", rc);
5431                goto rw_error;
5432        }
5433        rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
5434        if (rc != 0) {
5435                pr_err("error %d\n", rc);
5436                goto rw_error;
5437        }
5438        if (primary) {
5439                rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
5440                if (rc != 0) {
5441                        pr_err("error %d\n", rc);
5442                        goto rw_error;
5443                }
5444                rc = set_iqm_af(demod, false);
5445                if (rc != 0) {
5446                        pr_err("error %d\n", rc);
5447                        goto rw_error;
5448                }
5449        } else {
5450                rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
5451                if (rc != 0) {
5452                        pr_err("error %d\n", rc);
5453                        goto rw_error;
5454                }
5455                rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
5456                if (rc != 0) {
5457                        pr_err("error %d\n", rc);
5458                        goto rw_error;
5459                }
5460                rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
5461                if (rc != 0) {
5462                        pr_err("error %d\n", rc);
5463                        goto rw_error;
5464                }
5465                rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
5466                if (rc != 0) {
5467                        pr_err("error %d\n", rc);
5468                        goto rw_error;
5469                }
5470                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
5471                if (rc != 0) {
5472                        pr_err("error %d\n", rc);
5473                        goto rw_error;
5474                }
5475        }
5476
5477        cfg_mpeg_output.enable_mpeg_output = false;
5478        rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
5479        if (rc != 0) {
5480                pr_err("error %d\n", rc);
5481                goto rw_error;
5482        }
5483
5484        return 0;
5485rw_error:
5486        return rc;
5487}
5488
5489/*
5490* \fn int set_vsb_leak_n_gain ()
5491* \brief Set ATSC demod.
5492* \param demod instance of demodulator.
5493* \return int.
5494*/
5495static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
5496{
5497        struct i2c_device_addr *dev_addr = NULL;
5498        int rc;
5499
5500        static const u8 vsb_ffe_leak_gain_ram0[] = {
5501                DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO1  */
5502                DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO2  */
5503                DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO3  */
5504                DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO4  */
5505                DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO5  */
5506                DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO6  */
5507                DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO7  */
5508                DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO8  */
5509                DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO9  */
5510                DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO10  */
5511                DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO11 */
5512                DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO12 */
5513                DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO1 */
5514                DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO2 */
5515                DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO3 */
5516                DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO4 */
5517                DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO5 */
5518                DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO6 */
5519                DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO7 */
5520                DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO8 */
5521                DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO9 */
5522                DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO10 */
5523                DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO11 */
5524                DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO12 */
5525                DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO1 */
5526                DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO2 */
5527                DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO3 */
5528                DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO4 */
5529                DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO5 */
5530                DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO6 */
5531                DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO7 */
5532                DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO8 */
5533                DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO9 */
5534                DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO10 */
5535                DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO11 */
5536                DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO12 */
5537                DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO1 */
5538                DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO2 */
5539                DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO3 */
5540                DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO4 */
5541                DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO5 */
5542                DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO6 */
5543                DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO7 */
5544                DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO8 */
5545                DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO9 */
5546                DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO10 */
5547                DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO11 */
5548                DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO12 */
5549                DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO1 */
5550                DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO2 */
5551                DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO3 */
5552                DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO4 */
5553                DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO5 */
5554                DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO6 */
5555                DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO7 */
5556                DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO8 */
5557                DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO9 */
5558                DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO10 */
5559                DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO11 */
5560                DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO12 */
5561                DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO1 */
5562                DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO2 */
5563                DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO3 */
5564                DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO4 */
5565                DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO5 */
5566                DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO6 */
5567                DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO7 */
5568                DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO8 */
5569                DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO9 */
5570                DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO10 */
5571                DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO11 */
5572                DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO12 */
5573                DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO1 */
5574                DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO2 */
5575                DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO3 */
5576                DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO4 */
5577                DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO5 */
5578                DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO6 */
5579                DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO7 */
5580                DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO8 */
5581                DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO9 */
5582                DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO10 */
5583                DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO11 */
5584                DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO12 */
5585                DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO1 */
5586                DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO2 */
5587                DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO3 */
5588                DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO4 */
5589                DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO5 */
5590                DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO6 */
5591                DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO7 */
5592                DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO8 */
5593                DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO9 */
5594                DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO10 */
5595                DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO11 */
5596                DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO12 */
5597                DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO1 */
5598                DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO2 */
5599                DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO3 */
5600                DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO4 */
5601                DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO5 */
5602                DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO6 */
5603                DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO7 */
5604                DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO8 */
5605                DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO9 */
5606                DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO10 */
5607                DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO11 */
5608                DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO12 */
5609                DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN1 */
5610                DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN2 */
5611                DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN3 */
5612                DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN4 */
5613                DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN5 */
5614                DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN6 */
5615                DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN7 */
5616                DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN8 */
5617                DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN9 */
5618                DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN10 */
5619                DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN11 */
5620                DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN12 */
5621                DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN1 */
5622                DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN2 */
5623                DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN3 */
5624                DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN4 */
5625                DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN5 */
5626                DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN6 */
5627                DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN7 */
5628                DRXJ_16TO8(0x1010)      /* FIRRCA1GAIN8 */
5629        };
5630
5631        static const u8 vsb_ffe_leak_gain_ram1[] = {
5632                DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN9 */
5633                DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN10 */
5634                DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN11 */
5635                DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN12 */
5636                DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN1 */
5637                DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN2 */
5638                DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN3 */
5639                DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN4 */
5640                DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN5 */
5641                DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN6 */
5642                DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN7 */
5643                DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN8 */
5644                DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN9 */
5645                DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN10 */
5646                DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN11 */
5647                DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN12 */
5648                DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN1 */
5649                DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN2 */
5650                DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN3 */
5651                DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN4 */
5652                DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN5 */
5653                DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN6 */
5654                DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN7 */
5655                DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN8 */
5656                DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN9 */
5657                DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN10 */
5658                DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN11 */
5659                DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN12 */
5660                DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN1 */
5661                DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN2 */
5662                DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN3 */
5663                DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN4 */
5664                DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN5 */
5665                DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN6 */
5666                DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN7 */
5667                DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN8 */
5668                DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN9 */
5669                DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN10 */
5670                DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN11 */
5671                DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN12 */
5672                DRXJ_16TO8(0x001f),     /* DFETRAINLKRATIO */
5673                DRXJ_16TO8(0x01ff),     /* DFERCA1TRAINLKRATIO */
5674                DRXJ_16TO8(0x01ff),     /* DFERCA1DATALKRATIO */
5675                DRXJ_16TO8(0x004f),     /* DFERCA2TRAINLKRATIO */
5676                DRXJ_16TO8(0x004f),     /* DFERCA2DATALKRATIO */
5677                DRXJ_16TO8(0x01ff),     /* DFEDDM1TRAINLKRATIO */
5678                DRXJ_16TO8(0x01ff),     /* DFEDDM1DATALKRATIO */
5679                DRXJ_16TO8(0x0352),     /* DFEDDM2TRAINLKRATIO */
5680                DRXJ_16TO8(0x0352),     /* DFEDDM2DATALKRATIO */
5681                DRXJ_16TO8(0x0000),     /* DFETRAINGAIN */
5682                DRXJ_16TO8(0x2020),     /* DFERCA1GAIN */
5683                DRXJ_16TO8(0x1010),     /* DFERCA2GAIN */
5684                DRXJ_16TO8(0x1818),     /* DFEDDM1GAIN */
5685                DRXJ_16TO8(0x1212)      /* DFEDDM2GAIN */
5686        };
5687
5688        dev_addr = demod->my_i2c_dev_addr;
5689        rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
5690        if (rc != 0) {
5691                pr_err("error %d\n", rc);
5692                goto rw_error;
5693        }
5694        rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
5695        if (rc != 0) {
5696                pr_err("error %d\n", rc);
5697                goto rw_error;
5698        }
5699
5700        return 0;
5701rw_error:
5702        return rc;
5703}
5704
5705/*
5706* \fn int set_vsb()
5707* \brief Set 8VSB demod.
5708* \param demod instance of demodulator.
5709* \return int.
5710*
5711*/
5712static int set_vsb(struct drx_demod_instance *demod)
5713{
5714        struct i2c_device_addr *dev_addr = NULL;
5715        int rc;
5716        struct drx_common_attr *common_attr = NULL;
5717        struct drxjscu_cmd cmd_scu;
5718        struct drxj_data *ext_attr = NULL;
5719        u16 cmd_result = 0;
5720        u16 cmd_param = 0;
5721        static const u8 vsb_taps_re[] = {
5722                DRXJ_16TO8(-2), /* re0  */
5723                DRXJ_16TO8(4),  /* re1  */
5724                DRXJ_16TO8(1),  /* re2  */
5725                DRXJ_16TO8(-4), /* re3  */
5726                DRXJ_16TO8(1),  /* re4  */
5727                DRXJ_16TO8(4),  /* re5  */
5728                DRXJ_16TO8(-3), /* re6  */
5729                DRXJ_16TO8(-3), /* re7  */
5730                DRXJ_16TO8(6),  /* re8  */
5731                DRXJ_16TO8(1),  /* re9  */
5732                DRXJ_16TO8(-9), /* re10 */
5733                DRXJ_16TO8(3),  /* re11 */
5734                DRXJ_16TO8(12), /* re12 */
5735                DRXJ_16TO8(-9), /* re13 */
5736                DRXJ_16TO8(-15),        /* re14 */
5737                DRXJ_16TO8(17), /* re15 */
5738                DRXJ_16TO8(19), /* re16 */
5739                DRXJ_16TO8(-29),        /* re17 */
5740                DRXJ_16TO8(-22),        /* re18 */
5741                DRXJ_16TO8(45), /* re19 */
5742                DRXJ_16TO8(25), /* re20 */
5743                DRXJ_16TO8(-70),        /* re21 */
5744                DRXJ_16TO8(-28),        /* re22 */
5745                DRXJ_16TO8(111),        /* re23 */
5746                DRXJ_16TO8(30), /* re24 */
5747                DRXJ_16TO8(-201),       /* re25 */
5748                DRXJ_16TO8(-31),        /* re26 */
5749                DRXJ_16TO8(629) /* re27 */
5750        };
5751
5752        dev_addr = demod->my_i2c_dev_addr;
5753        common_attr = (struct drx_common_attr *) demod->my_common_attr;
5754        ext_attr = (struct drxj_data *) demod->my_ext_attr;
5755
5756        /* stop all comm_exec */
5757        rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
5758        if (rc != 0) {
5759                pr_err("error %d\n", rc);
5760                goto rw_error;
5761        }
5762        rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
5763        if (rc != 0) {
5764                pr_err("error %d\n", rc);
5765                goto rw_error;
5766        }
5767        rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
5768        if (rc != 0) {
5769                pr_err("error %d\n", rc);
5770                goto rw_error;
5771        }
5772        rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
5773        if (rc != 0) {
5774                pr_err("error %d\n", rc);
5775                goto rw_error;
5776        }
5777        rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
5778        if (rc != 0) {
5779                pr_err("error %d\n", rc);
5780                goto rw_error;
5781        }
5782        rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
5783        if (rc != 0) {
5784                pr_err("error %d\n", rc);
5785                goto rw_error;
5786        }
5787        rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
5788        if (rc != 0) {
5789                pr_err("error %d\n", rc);
5790                goto rw_error;
5791        }
5792
5793        /* reset demodulator */
5794        cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
5795            | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
5796        cmd_scu.parameter_len = 0;
5797        cmd_scu.result_len = 1;
5798        cmd_scu.parameter = NULL;
5799        cmd_scu.result = &cmd_result;
5800        rc = scu_command(dev_addr, &cmd_scu);
5801        if (rc != 0) {
5802                pr_err("error %d\n", rc);
5803                goto rw_error;
5804        }
5805
5806        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
5807        if (rc != 0) {
5808                pr_err("error %d\n", rc);
5809                goto rw_error;
5810        }
5811        rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
5812        if (rc != 0) {
5813                pr_err("error %d\n", rc);
5814                goto rw_error;
5815        }
5816        rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
5817        if (rc != 0) {
5818                pr_err("error %d\n", rc);
5819                goto rw_error;
5820        }
5821        ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
5822        rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
5823        if (rc != 0) {
5824                pr_err("error %d\n", rc);
5825                goto rw_error;
5826        }
5827        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
5828        if (rc != 0) {
5829                pr_err("error %d\n", rc);
5830                goto rw_error;
5831        }
5832        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
5833        if (rc != 0) {
5834                pr_err("error %d\n", rc);
5835                goto rw_error;
5836        }
5837
5838        rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
5839        if (rc != 0) {
5840                pr_err("error %d\n", rc);
5841                goto rw_error;
5842        }
5843        rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);
5844        if (rc != 0) {
5845                pr_err("error %d\n", rc);
5846                goto rw_error;
5847        }
5848        rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
5849        if (rc != 0) {
5850                pr_err("error %d\n", rc);
5851                goto rw_error;
5852        }
5853        rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
5854        if (rc != 0) {
5855                pr_err("error %d\n", rc);
5856                goto rw_error;
5857        }
5858        rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
5859        if (rc != 0) {
5860                pr_err("error %d\n", rc);
5861                goto rw_error;
5862        }
5863        rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
5864        if (rc != 0) {
5865                pr_err("error %d\n", rc);
5866                goto rw_error;
5867        }
5868        rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);
5869        if (rc != 0) {
5870                pr_err("error %d\n", rc);
5871                goto rw_error;
5872        }
5873        rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
5874        if (rc != 0) {
5875                pr_err("error %d\n", rc);
5876                goto rw_error;
5877        }
5878        rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
5879        if (rc != 0) {
5880                pr_err("error %d\n", rc);
5881                goto rw_error;
5882        }
5883
5884        rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
5885        if (rc != 0) {
5886                pr_err("error %d\n", rc);
5887                goto rw_error;
5888        }
5889        rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
5890        if (rc != 0) {
5891                pr_err("error %d\n", rc);
5892                goto rw_error;
5893        }
5894
5895        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
5896        if (rc != 0) {
5897                pr_err("error %d\n", rc);
5898                goto rw_error;
5899        }       /* set higher threshold */
5900        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
5901        if (rc != 0) {
5902                pr_err("error %d\n", rc);
5903                goto rw_error;
5904        }       /* burst detection on   */
5905        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
5906        if (rc != 0) {
5907                pr_err("error %d\n", rc);
5908                goto rw_error;
5909        }       /* drop thresholds by 1 dB */
5910        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
5911        if (rc != 0) {
5912                pr_err("error %d\n", rc);
5913                goto rw_error;
5914        }       /* drop thresholds by 2 dB */
5915        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
5916        if (rc != 0) {
5917                pr_err("error %d\n", rc);
5918                goto rw_error;
5919        }       /* cma on               */
5920        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
5921        if (rc != 0) {
5922                pr_err("error %d\n", rc);
5923                goto rw_error;
5924        }       /* GPIO               */
5925
5926        /* Initialize the FEC Subsystem */
5927        rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
5928        if (rc != 0) {
5929                pr_err("error %d\n", rc);
5930                goto rw_error;
5931        }
5932        {
5933                u16 fec_oc_snc_mode = 0;
5934                rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
5935                if (rc != 0) {
5936                        pr_err("error %d\n", rc);
5937                        goto rw_error;
5938                }
5939                /* output data even when not locked */
5940                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
5941                if (rc != 0) {
5942                        pr_err("error %d\n", rc);
5943                        goto rw_error;
5944                }
5945        }
5946
5947        /* set clip */
5948        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
5949        if (rc != 0) {
5950                pr_err("error %d\n", rc);
5951                goto rw_error;
5952        }
5953        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
5954        if (rc != 0) {
5955                pr_err("error %d\n", rc);
5956                goto rw_error;
5957        }
5958        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
5959        if (rc != 0) {
5960                pr_err("error %d\n", rc);
5961                goto rw_error;
5962        }
5963        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
5964        if (rc != 0) {
5965                pr_err("error %d\n", rc);
5966                goto rw_error;
5967        }
5968        /* no transparent, no A&C framing; parity is set in mpegoutput */
5969        {
5970                u16 fec_oc_reg_mode = 0;
5971                rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
5972                if (rc != 0) {
5973                        pr_err("error %d\n", rc);
5974                        goto rw_error;
5975                }
5976                rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), 0);
5977                if (rc != 0) {
5978                        pr_err("error %d\n", rc);
5979                        goto rw_error;
5980                }
5981        }
5982
5983        rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
5984        if (rc != 0) {
5985                pr_err("error %d\n", rc);
5986                goto rw_error;
5987        }       /* timeout counter for restarting */
5988        rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
5989        if (rc != 0) {
5990                pr_err("error %d\n", rc);
5991                goto rw_error;
5992        }
5993        rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);
5994        if (rc != 0) {
5995                pr_err("error %d\n", rc);
5996                goto rw_error;
5997        }       /* bypass disabled */
5998        /* initialize RS packet error measurement parameters */
5999        rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
6000        if (rc != 0) {
6001                pr_err("error %d\n", rc);
6002                goto rw_error;
6003        }
6004        rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
6005        if (rc != 0) {
6006                pr_err("error %d\n", rc);
6007                goto rw_error;
6008        }
6009
6010        /* init measurement period of MER/SER */
6011        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
6012        if (rc != 0) {
6013                pr_err("error %d\n", rc);
6014                goto rw_error;
6015        }
6016        rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
6017        if (rc != 0) {
6018                pr_err("error %d\n", rc);
6019                goto rw_error;
6020        }
6021        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
6022        if (rc != 0) {
6023                pr_err("error %d\n", rc);
6024                goto rw_error;
6025        }
6026        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
6027        if (rc != 0) {
6028                pr_err("error %d\n", rc);
6029                goto rw_error;
6030        }
6031
6032        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
6033        if (rc != 0) {
6034                pr_err("error %d\n", rc);
6035                goto rw_error;
6036        }
6037        /* B-Input to ADC, PGA+filter in standby */
6038        if (!ext_attr->has_lna) {
6039                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
6040                if (rc != 0) {
6041                        pr_err("error %d\n", rc);
6042                        goto rw_error;
6043                }
6044        }
6045
6046        /* turn on IQMAF. It has to be in front of setAgc**() */
6047        rc = set_iqm_af(demod, true);
6048        if (rc != 0) {
6049                pr_err("error %d\n", rc);
6050                goto rw_error;
6051        }
6052        rc = adc_synchronization(demod);
6053        if (rc != 0) {
6054                pr_err("error %d\n", rc);
6055                goto rw_error;
6056        }
6057
6058        rc = init_agc(demod);
6059        if (rc != 0) {
6060                pr_err("error %d\n", rc);
6061                goto rw_error;
6062        }
6063        rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
6064        if (rc != 0) {
6065                pr_err("error %d\n", rc);
6066                goto rw_error;
6067        }
6068        rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
6069        if (rc != 0) {
6070                pr_err("error %d\n", rc);
6071                goto rw_error;
6072        }
6073        {
6074                /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
6075                   of only the gain */
6076                struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
6077
6078                vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
6079                rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
6080                if (rc != 0) {
6081                        pr_err("error %d\n", rc);
6082                        goto rw_error;
6083                }
6084        }
6085        rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
6086        if (rc != 0) {
6087                pr_err("error %d\n", rc);
6088                goto rw_error;
6089        }
6090
6091        /* Mpeg output has to be in front of FEC active */
6092        rc = set_mpegtei_handling(demod);
6093        if (rc != 0) {
6094                pr_err("error %d\n", rc);
6095                goto rw_error;
6096        }
6097        rc = bit_reverse_mpeg_output(demod);
6098        if (rc != 0) {
6099                pr_err("error %d\n", rc);
6100                goto rw_error;
6101        }
6102        rc = set_mpeg_start_width(demod);
6103        if (rc != 0) {
6104                pr_err("error %d\n", rc);
6105                goto rw_error;
6106        }
6107        {
6108                /* TODO: move to set_standard after hardware reset value problem is solved */
6109                /* Configure initial MPEG output */
6110                struct drx_cfg_mpeg_output cfg_mpeg_output;
6111
6112                memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6113                cfg_mpeg_output.enable_mpeg_output = true;
6114
6115                rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6116                if (rc != 0) {
6117                        pr_err("error %d\n", rc);
6118                        goto rw_error;
6119                }
6120        }
6121
6122        /* TBD: what parameters should be set */
6123        cmd_param = 0x00;       /* Default mode AGC on, etc */
6124        cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6125            | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
6126        cmd_scu.parameter_len = 1;
6127        cmd_scu.result_len = 1;
6128        cmd_scu.parameter = &cmd_param;
6129        cmd_scu.result = &cmd_result;
6130        rc = scu_command(dev_addr, &cmd_scu);
6131        if (rc != 0) {
6132                pr_err("error %d\n", rc);
6133                goto rw_error;
6134        }
6135
6136        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
6137        if (rc != 0) {
6138                pr_err("error %d\n", rc);
6139                goto rw_error;
6140        }
6141        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
6142        if (rc != 0) {
6143                pr_err("error %d\n", rc);
6144                goto rw_error;
6145        }
6146        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
6147        if (rc != 0) {
6148                pr_err("error %d\n", rc);
6149                goto rw_error;
6150        }
6151        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
6152        if (rc != 0) {
6153                pr_err("error %d\n", rc);
6154                goto rw_error;
6155        }
6156        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
6157        if (rc != 0) {
6158                pr_err("error %d\n", rc);
6159                goto rw_error;
6160        }
6161        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
6162        if (rc != 0) {
6163                pr_err("error %d\n", rc);
6164                goto rw_error;
6165        }
6166        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
6167        if (rc != 0) {
6168                pr_err("error %d\n", rc);
6169                goto rw_error;
6170        }
6171        rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
6172        if (rc != 0) {
6173                pr_err("error %d\n", rc);
6174                goto rw_error;
6175        }
6176
6177        /* start demodulator */
6178        cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6179            | SCU_RAM_COMMAND_CMD_DEMOD_START;
6180        cmd_scu.parameter_len = 0;
6181        cmd_scu.result_len = 1;
6182        cmd_scu.parameter = NULL;
6183        cmd_scu.result = &cmd_result;
6184        rc = scu_command(dev_addr, &cmd_scu);
6185        if (rc != 0) {
6186                pr_err("error %d\n", rc);
6187                goto rw_error;
6188        }
6189
6190        rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
6191        if (rc != 0) {
6192                pr_err("error %d\n", rc);
6193                goto rw_error;
6194        }
6195        rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
6196        if (rc != 0) {
6197                pr_err("error %d\n", rc);
6198                goto rw_error;
6199        }
6200        rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
6201        if (rc != 0) {
6202                pr_err("error %d\n", rc);
6203                goto rw_error;
6204        }
6205
6206        return 0;
6207rw_error:
6208        return rc;
6209}
6210
6211/*
6212* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
6213* \brief Get the values of packet error in 8VSB mode
6214* \return Error code
6215*/
6216static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
6217                                   u32 *pck_errs, u32 *pck_count)
6218{
6219        int rc;
6220        u16 data = 0;
6221        u16 period = 0;
6222        u16 prescale = 0;
6223        u16 packet_errors_mant = 0;
6224        u16 packet_errors_exp = 0;
6225
6226        rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
6227        if (rc != 0) {
6228                pr_err("error %d\n", rc);
6229                goto rw_error;
6230        }
6231        packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6232        packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
6233            >> FEC_RS_NR_FAILURES_EXP__B;
6234        period = FEC_RS_MEASUREMENT_PERIOD;
6235        prescale = FEC_RS_MEASUREMENT_PRESCALE;
6236        /* packet error rate = (error packet number) per second */
6237        /* 77.3 us is time for per packet */
6238        if (period * prescale == 0) {
6239                pr_err("error: period and/or prescale is zero!\n");
6240                return -EIO;
6241        }
6242        *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
6243        *pck_count = period * prescale * 77;
6244
6245        return 0;
6246rw_error:
6247        return rc;
6248}
6249
6250/*
6251* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
6252* \brief Get the values of ber in VSB mode
6253* \return Error code
6254*/
6255static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
6256                                    u32 *ber, u32 *cnt)
6257{
6258        int rc;
6259        u16 data = 0;
6260        u16 period = 0;
6261        u16 prescale = 0;
6262        u16 bit_errors_mant = 0;
6263        u16 bit_errors_exp = 0;
6264
6265        rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
6266        if (rc != 0) {
6267                pr_err("error %d\n", rc);
6268                goto rw_error;
6269        }
6270        period = FEC_RS_MEASUREMENT_PERIOD;
6271        prescale = FEC_RS_MEASUREMENT_PRESCALE;
6272
6273        bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6274        bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
6275            >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6276
6277        *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
6278
6279        if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
6280                *ber = (*cnt) * 26570;
6281        else {
6282                if (period * prescale == 0) {
6283                        pr_err("error: period and/or prescale is zero!\n");
6284                        return -EIO;
6285                }
6286                *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
6287                        (bit_errors_exp - 3) : bit_errors_exp);
6288        }
6289
6290        return 0;
6291rw_error:
6292        return rc;
6293}
6294
6295/*
6296* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
6297* \brief Get the values of ber in VSB mode
6298* \return Error code
6299*/
6300static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
6301                                   u32 *ber, u32 *cnt)
6302{
6303        u16 data = 0;
6304        int rc;
6305
6306        rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
6307        if (rc != 0) {
6308                pr_err("error %d\n", rc);
6309                return -EIO;
6310        }
6311        *ber = data;
6312        *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
6313
6314        return 0;
6315}
6316
6317/*
6318* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6319* \brief Get the values of MER
6320* \return Error code
6321*/
6322static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6323{
6324        int rc;
6325        u16 data_hi = 0;
6326
6327        rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
6328        if (rc != 0) {
6329                pr_err("error %d\n", rc);
6330                goto rw_error;
6331        }
6332        *mer =
6333            (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
6334
6335        return 0;
6336rw_error:
6337        return rc;
6338}
6339
6340
6341/*============================================================================*/
6342/*==                     END 8VSB DATAPATH FUNCTIONS                        ==*/
6343/*============================================================================*/
6344
6345/*============================================================================*/
6346/*============================================================================*/
6347/*==                       QAM DATAPATH FUNCTIONS                           ==*/
6348/*============================================================================*/
6349/*============================================================================*/
6350
6351/*
6352* \fn int power_down_qam ()
6353* \brief Powr down QAM related blocks.
6354* \param demod instance of demodulator.
6355* \param channel pointer to channel data.
6356* \return int.
6357*/
6358static int power_down_qam(struct drx_demod_instance *demod, bool primary)
6359{
6360        struct drxjscu_cmd cmd_scu = { /* command      */ 0,
6361                /* parameter_len */ 0,
6362                /* result_len    */ 0,
6363                /* *parameter   */ NULL,
6364                /* *result      */ NULL
6365        };
6366        int rc;
6367        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6368        struct drx_cfg_mpeg_output cfg_mpeg_output;
6369        struct drx_common_attr *common_attr = demod->my_common_attr;
6370        u16 cmd_result = 0;
6371
6372        /*
6373           STOP demodulator
6374           resets IQM, QAM and FEC HW blocks
6375         */
6376        /* stop all comm_exec */
6377        rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
6378        if (rc != 0) {
6379                pr_err("error %d\n", rc);
6380                goto rw_error;
6381        }
6382        rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
6383        if (rc != 0) {
6384                pr_err("error %d\n", rc);
6385                goto rw_error;
6386        }
6387
6388        cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
6389            SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6390        cmd_scu.parameter_len = 0;
6391        cmd_scu.result_len = 1;
6392        cmd_scu.parameter = NULL;
6393        cmd_scu.result = &cmd_result;
6394        rc = scu_command(dev_addr, &cmd_scu);
6395        if (rc != 0) {
6396                pr_err("error %d\n", rc);
6397                goto rw_error;
6398        }
6399
6400        if (primary) {
6401                rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
6402                if (rc != 0) {
6403                        pr_err("error %d\n", rc);
6404                        goto rw_error;
6405                }
6406                rc = set_iqm_af(demod, false);
6407                if (rc != 0) {
6408                        pr_err("error %d\n", rc);
6409                        goto rw_error;
6410                }
6411        } else {
6412                rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
6413                if (rc != 0) {
6414                        pr_err("error %d\n", rc);
6415                        goto rw_error;
6416                }
6417                rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
6418                if (rc != 0) {
6419                        pr_err("error %d\n", rc);
6420                        goto rw_error;
6421                }
6422                rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
6423                if (rc != 0) {
6424                        pr_err("error %d\n", rc);
6425                        goto rw_error;
6426                }
6427                rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
6428                if (rc != 0) {
6429                        pr_err("error %d\n", rc);
6430                        goto rw_error;
6431                }
6432                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
6433                if (rc != 0) {
6434                        pr_err("error %d\n", rc);
6435                        goto rw_error;
6436                }
6437        }
6438
6439        memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6440        cfg_mpeg_output.enable_mpeg_output = false;
6441
6442        rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6443        if (rc != 0) {
6444                pr_err("error %d\n", rc);
6445                goto rw_error;
6446        }
6447
6448        return 0;
6449rw_error:
6450        return rc;
6451}
6452
6453/*============================================================================*/
6454
6455/*
6456* \fn int set_qam_measurement ()
6457* \brief Setup of the QAM Measuremnt intervals for signal quality
6458* \param demod instance of demod.
6459* \param constellation current constellation.
6460* \return int.
6461*
6462*  NOTE:
6463*  Take into account that for certain settings the errorcounters can overflow.
6464*  The implementation does not check this.
6465*
6466*  TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
6467*  constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
6468*  field ?
6469*
6470*/
6471#ifndef DRXJ_VSB_ONLY
6472static int
6473set_qam_measurement(struct drx_demod_instance *demod,
6474                    enum drx_modulation constellation, u32 symbol_rate)
6475{
6476        struct i2c_device_addr *dev_addr = NULL;        /* device address for I2C writes */
6477        struct drxj_data *ext_attr = NULL;      /* Global data container for DRXJ specific data */
6478        int rc;
6479        u32 fec_bits_desired = 0;       /* BER accounting period */
6480        u16 fec_rs_plen = 0;    /* defines RS BER measurement period */
6481        u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
6482        u32 fec_rs_period = 0;  /* Value for corresponding I2C register */
6483        u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
6484        u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
6485        u32 qam_vd_period = 0;  /* Value for corresponding I2C register */
6486        u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
6487        u16 fec_vd_plen = 0;    /* no of trellis symbols: VD SER measur period */
6488        u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
6489
6490        dev_addr = demod->my_i2c_dev_addr;
6491        ext_attr = (struct drxj_data *) demod->my_ext_attr;
6492
6493        fec_bits_desired = ext_attr->fec_bits_desired;
6494        fec_rs_prescale = ext_attr->fec_rs_prescale;
6495
6496        switch (constellation) {
6497        case DRX_CONSTELLATION_QAM16:
6498                fec_bits_desired = 4 * symbol_rate;
6499                break;
6500        case DRX_CONSTELLATION_QAM32:
6501                fec_bits_desired = 5 * symbol_rate;
6502                break;
6503        case DRX_CONSTELLATION_QAM64:
6504                fec_bits_desired = 6 * symbol_rate;
6505                break;
6506        case DRX_CONSTELLATION_QAM128:
6507                fec_bits_desired = 7 * symbol_rate;
6508                break;
6509        case DRX_CONSTELLATION_QAM256:
6510                fec_bits_desired = 8 * symbol_rate;
6511                break;
6512        default:
6513                return -EINVAL;
6514        }
6515
6516        /* Parameters for Reed-Solomon Decoder */
6517        /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6518        /* rs_bit_cnt   = fecrs_period*fecrs_prescale*plen                  */
6519        /*     result is within 32 bit arithmetic ->                        */
6520        /*     no need for mult or frac functions                           */
6521
6522        /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
6523        switch (ext_attr->standard) {
6524        case DRX_STANDARD_ITU_A:
6525        case DRX_STANDARD_ITU_C:
6526                fec_rs_plen = 204 * 8;
6527                break;
6528        case DRX_STANDARD_ITU_B:
6529                fec_rs_plen = 128 * 7;
6530                break;
6531        default:
6532                return -EINVAL;
6533        }
6534
6535        ext_attr->fec_rs_plen = fec_rs_plen;    /* for getSigQual */
6536        fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage   */
6537        if (fec_rs_bit_cnt == 0) {
6538                pr_err("error: fec_rs_bit_cnt is zero!\n");
6539                return -EIO;
6540        }
6541        fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1;  /* ceil */
6542        if (ext_attr->standard != DRX_STANDARD_ITU_B)
6543                fec_oc_snc_fail_period = fec_rs_period;
6544
6545        /* limit to max 16 bit value (I2C register width) if needed */
6546        if (fec_rs_period > 0xFFFF)
6547                fec_rs_period = 0xFFFF;
6548
6549        /* write corresponding registers */
6550        switch (ext_attr->standard) {
6551        case DRX_STANDARD_ITU_A:
6552        case DRX_STANDARD_ITU_C:
6553                break;
6554        case DRX_STANDARD_ITU_B:
6555                switch (constellation) {
6556                case DRX_CONSTELLATION_QAM64:
6557                        fec_rs_period = 31581;
6558                        fec_oc_snc_fail_period = 17932;
6559                        break;
6560                case DRX_CONSTELLATION_QAM256:
6561                        fec_rs_period = 45446;
6562                        fec_oc_snc_fail_period = 25805;
6563                        break;
6564                default:
6565                        return -EINVAL;
6566                }
6567                break;
6568        default:
6569                return -EINVAL;
6570        }
6571
6572        rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
6573        if (rc != 0) {
6574                pr_err("error %d\n", rc);
6575                goto rw_error;
6576        }
6577        rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
6578        if (rc != 0) {
6579                pr_err("error %d\n", rc);
6580                goto rw_error;
6581        }
6582        rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
6583        if (rc != 0) {
6584                pr_err("error %d\n", rc);
6585                goto rw_error;
6586        }
6587        ext_attr->fec_rs_period = (u16) fec_rs_period;
6588        ext_attr->fec_rs_prescale = fec_rs_prescale;
6589        rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
6590        if (rc != 0) {
6591                pr_err("error %d\n", rc);
6592                goto rw_error;
6593        }
6594        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
6595        if (rc != 0) {
6596                pr_err("error %d\n", rc);
6597                goto rw_error;
6598        }
6599        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
6600        if (rc != 0) {
6601                pr_err("error %d\n", rc);
6602                goto rw_error;
6603        }
6604
6605        if (ext_attr->standard == DRX_STANDARD_ITU_B) {
6606                /* Parameters for Viterbi Decoder */
6607                /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/                      */
6608                /*                    (qamvd_prescale*plen*(qam_constellation+1))) */
6609                /* vd_bit_cnt   = qamvd_period*qamvd_prescale*plen                 */
6610                /*     result is within 32 bit arithmetic ->                       */
6611                /*     no need for mult or frac functions                          */
6612
6613                /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
6614                fec_vd_plen = ext_attr->fec_vd_plen;
6615                qam_vd_prescale = ext_attr->qam_vd_prescale;
6616                qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
6617
6618                switch (constellation) {
6619                case DRX_CONSTELLATION_QAM64:
6620                        /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
6621                        qam_vd_period =
6622                            qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
6623                            * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6624                        break;
6625                case DRX_CONSTELLATION_QAM256:
6626                        /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
6627                        qam_vd_period =
6628                            qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
6629                            * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6630                        break;
6631                default:
6632                        return -EINVAL;
6633                }
6634                if (qam_vd_period == 0) {
6635                        pr_err("error: qam_vd_period is zero!\n");
6636                        return -EIO;
6637                }
6638                qam_vd_period = fec_bits_desired / qam_vd_period;
6639                /* limit to max 16 bit value (I2C register width) if needed */
6640                if (qam_vd_period > 0xFFFF)
6641                        qam_vd_period = 0xFFFF;
6642
6643                /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
6644                qam_vd_bit_cnt *= qam_vd_period;
6645
6646                rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
6647                if (rc != 0) {
6648                        pr_err("error %d\n", rc);
6649                        goto rw_error;
6650                }
6651                rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
6652                if (rc != 0) {
6653                        pr_err("error %d\n", rc);
6654                        goto rw_error;
6655                }
6656                ext_attr->qam_vd_period = (u16) qam_vd_period;
6657                ext_attr->qam_vd_prescale = qam_vd_prescale;
6658        }
6659
6660        return 0;
6661rw_error:
6662        return rc;
6663}
6664
6665/*============================================================================*/
6666
6667/*
6668* \fn int set_qam16 ()
6669* \brief QAM16 specific setup
6670* \param demod instance of demod.
6671* \return int.
6672*/
6673static int set_qam16(struct drx_demod_instance *demod)
6674{
6675        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6676        int rc;
6677        static const u8 qam_dq_qual_fun[] = {
6678                DRXJ_16TO8(2),  /* fun0  */
6679                DRXJ_16TO8(2),  /* fun1  */
6680                DRXJ_16TO8(2),  /* fun2  */
6681                DRXJ_16TO8(2),  /* fun3  */
6682                DRXJ_16TO8(3),  /* fun4  */
6683                DRXJ_16TO8(3),  /* fun5  */
6684        };
6685        static const u8 qam_eq_cma_rad[] = {
6686                DRXJ_16TO8(13517),      /* RAD0  */
6687                DRXJ_16TO8(13517),      /* RAD1  */
6688                DRXJ_16TO8(13517),      /* RAD2  */
6689                DRXJ_16TO8(13517),      /* RAD3  */
6690                DRXJ_16TO8(13517),      /* RAD4  */
6691                DRXJ_16TO8(13517),      /* RAD5  */
6692        };
6693
6694        rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
6695        if (rc != 0) {
6696                pr_err("error %d\n", rc);
6697                goto rw_error;
6698        }
6699        rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
6700        if (rc != 0) {
6701                pr_err("error %d\n", rc);
6702                goto rw_error;
6703        }
6704
6705        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
6706        if (rc != 0) {
6707                pr_err("error %d\n", rc);
6708                goto rw_error;
6709        }
6710        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
6711        if (rc != 0) {
6712                pr_err("error %d\n", rc);
6713                goto rw_error;
6714        }
6715        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
6716        if (rc != 0) {
6717                pr_err("error %d\n", rc);
6718                goto rw_error;
6719        }
6720        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
6721        if (rc != 0) {
6722                pr_err("error %d\n", rc);
6723                goto rw_error;
6724        }
6725        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
6726        if (rc != 0) {
6727                pr_err("error %d\n", rc);
6728                goto rw_error;
6729        }
6730        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
6731        if (rc != 0) {
6732                pr_err("error %d\n", rc);
6733                goto rw_error;
6734        }
6735
6736        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
6737        if (rc != 0) {
6738                pr_err("error %d\n", rc);
6739                goto rw_error;
6740        }
6741        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
6742        if (rc != 0) {
6743                pr_err("error %d\n", rc);
6744                goto rw_error;
6745        }
6746        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
6747        if (rc != 0) {
6748                pr_err("error %d\n", rc);
6749                goto rw_error;
6750        }
6751
6752        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
6753        if (rc != 0) {
6754                pr_err("error %d\n", rc);
6755                goto rw_error;
6756        }
6757        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
6758        if (rc != 0) {
6759                pr_err("error %d\n", rc);
6760                goto rw_error;
6761        }
6762        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
6763        if (rc != 0) {
6764                pr_err("error %d\n", rc);
6765                goto rw_error;
6766        }
6767        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
6768        if (rc != 0) {
6769                pr_err("error %d\n", rc);
6770                goto rw_error;
6771        }
6772        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
6773        if (rc != 0) {
6774                pr_err("error %d\n", rc);
6775                goto rw_error;
6776        }
6777        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
6778        if (rc != 0) {
6779                pr_err("error %d\n", rc);
6780                goto rw_error;
6781        }
6782        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
6783        if (rc != 0) {
6784                pr_err("error %d\n", rc);
6785                goto rw_error;
6786        }
6787
6788        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
6789        if (rc != 0) {
6790                pr_err("error %d\n", rc);
6791                goto rw_error;
6792        }
6793        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
6794        if (rc != 0) {
6795                pr_err("error %d\n", rc);
6796                goto rw_error;
6797        }
6798        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
6799        if (rc != 0) {
6800                pr_err("error %d\n", rc);
6801                goto rw_error;
6802        }
6803        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
6804        if (rc != 0) {
6805                pr_err("error %d\n", rc);
6806                goto rw_error;
6807        }
6808        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
6809        if (rc != 0) {
6810                pr_err("error %d\n", rc);
6811                goto rw_error;
6812        }
6813        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
6814        if (rc != 0) {
6815                pr_err("error %d\n", rc);
6816                goto rw_error;
6817        }
6818        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
6819        if (rc != 0) {
6820                pr_err("error %d\n", rc);
6821                goto rw_error;
6822        }
6823        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
6824        if (rc != 0) {
6825                pr_err("error %d\n", rc);
6826                goto rw_error;
6827        }
6828        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
6829        if (rc != 0) {
6830                pr_err("error %d\n", rc);
6831                goto rw_error;
6832        }
6833        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
6834        if (rc != 0) {
6835                pr_err("error %d\n", rc);
6836                goto rw_error;
6837        }
6838        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
6839        if (rc != 0) {
6840                pr_err("error %d\n", rc);
6841                goto rw_error;
6842        }
6843        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
6844        if (rc != 0) {
6845                pr_err("error %d\n", rc);
6846                goto rw_error;
6847        }
6848        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
6849        if (rc != 0) {
6850                pr_err("error %d\n", rc);
6851                goto rw_error;
6852        }
6853        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
6854        if (rc != 0) {
6855                pr_err("error %d\n", rc);
6856                goto rw_error;
6857        }
6858        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
6859        if (rc != 0) {
6860                pr_err("error %d\n", rc);
6861                goto rw_error;
6862        }
6863        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
6864        if (rc != 0) {
6865                pr_err("error %d\n", rc);
6866                goto rw_error;
6867        }
6868        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
6869        if (rc != 0) {
6870                pr_err("error %d\n", rc);
6871                goto rw_error;
6872        }
6873        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
6874        if (rc != 0) {
6875                pr_err("error %d\n", rc);
6876                goto rw_error;
6877        }
6878        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
6879        if (rc != 0) {
6880                pr_err("error %d\n", rc);
6881                goto rw_error;
6882        }
6883        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
6884        if (rc != 0) {
6885                pr_err("error %d\n", rc);
6886                goto rw_error;
6887        }
6888
6889        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
6890        if (rc != 0) {
6891                pr_err("error %d\n", rc);
6892                goto rw_error;
6893        }
6894
6895        return 0;
6896rw_error:
6897        return rc;
6898}
6899
6900/*============================================================================*/
6901
6902/*
6903* \fn int set_qam32 ()
6904* \brief QAM32 specific setup
6905* \param demod instance of demod.
6906* \return int.
6907*/
6908static int set_qam32(struct drx_demod_instance *demod)
6909{
6910        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6911        int rc;
6912        static const u8 qam_dq_qual_fun[] = {
6913                DRXJ_16TO8(3),  /* fun0  */
6914                DRXJ_16TO8(3),  /* fun1  */
6915                DRXJ_16TO8(3),  /* fun2  */
6916                DRXJ_16TO8(3),  /* fun3  */
6917                DRXJ_16TO8(4),  /* fun4  */
6918                DRXJ_16TO8(4),  /* fun5  */
6919        };
6920        static const u8 qam_eq_cma_rad[] = {
6921                DRXJ_16TO8(6707),       /* RAD0  */
6922                DRXJ_16TO8(6707),       /* RAD1  */
6923                DRXJ_16TO8(6707),       /* RAD2  */
6924                DRXJ_16TO8(6707),       /* RAD3  */
6925                DRXJ_16TO8(6707),       /* RAD4  */
6926                DRXJ_16TO8(6707),       /* RAD5  */
6927        };
6928
6929        rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
6930        if (rc != 0) {
6931                pr_err("error %d\n", rc);
6932                goto rw_error;
6933        }
6934        rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
6935        if (rc != 0) {
6936                pr_err("error %d\n", rc);
6937                goto rw_error;
6938        }
6939
6940        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
6941        if (rc != 0) {
6942                pr_err("error %d\n", rc);
6943                goto rw_error;
6944        }
6945        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
6946        if (rc != 0) {
6947                pr_err("error %d\n", rc);
6948                goto rw_error;
6949        }
6950        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
6951        if (rc != 0) {
6952                pr_err("error %d\n", rc);
6953                goto rw_error;
6954        }
6955        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
6956        if (rc != 0) {
6957                pr_err("error %d\n", rc);
6958                goto rw_error;
6959        }
6960        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
6961        if (rc != 0) {
6962                pr_err("error %d\n", rc);
6963                goto rw_error;
6964        }
6965        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
6966        if (rc != 0) {
6967                pr_err("error %d\n", rc);
6968                goto rw_error;
6969        }
6970
6971        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
6972        if (rc != 0) {
6973                pr_err("error %d\n", rc);
6974                goto rw_error;
6975        }
6976        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
6977        if (rc != 0) {
6978                pr_err("error %d\n", rc);
6979                goto rw_error;
6980        }
6981        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
6982        if (rc != 0) {
6983                pr_err("error %d\n", rc);
6984                goto rw_error;
6985        }
6986
6987        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
6988        if (rc != 0) {
6989                pr_err("error %d\n", rc);
6990                goto rw_error;
6991        }
6992        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
6993        if (rc != 0) {
6994                pr_err("error %d\n", rc);
6995                goto rw_error;
6996        }
6997        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
6998        if (rc != 0) {
6999                pr_err("error %d\n", rc);
7000                goto rw_error;
7001        }
7002        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
7003        if (rc != 0) {
7004                pr_err("error %d\n", rc);
7005                goto rw_error;
7006        }
7007        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
7008        if (rc != 0) {
7009                pr_err("error %d\n", rc);
7010                goto rw_error;
7011        }
7012        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
7013        if (rc != 0) {
7014                pr_err("error %d\n", rc);
7015                goto rw_error;
7016        }
7017        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
7018        if (rc != 0) {
7019                pr_err("error %d\n", rc);
7020                goto rw_error;
7021        }
7022
7023        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7024        if (rc != 0) {
7025                pr_err("error %d\n", rc);
7026                goto rw_error;
7027        }
7028        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7029        if (rc != 0) {
7030                pr_err("error %d\n", rc);
7031                goto rw_error;
7032        }
7033        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7034        if (rc != 0) {
7035                pr_err("error %d\n", rc);
7036                goto rw_error;
7037        }
7038        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
7039        if (rc != 0) {
7040                pr_err("error %d\n", rc);
7041                goto rw_error;
7042        }
7043        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7044        if (rc != 0) {
7045                pr_err("error %d\n", rc);
7046                goto rw_error;
7047        }
7048        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7049        if (rc != 0) {
7050                pr_err("error %d\n", rc);
7051                goto rw_error;
7052        }
7053        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
7054        if (rc != 0) {
7055                pr_err("error %d\n", rc);
7056                goto rw_error;
7057        }
7058        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
7059        if (rc != 0) {
7060                pr_err("error %d\n", rc);
7061                goto rw_error;
7062        }
7063        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7064        if (rc != 0) {
7065                pr_err("error %d\n", rc);
7066                goto rw_error;
7067        }
7068        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7069        if (rc != 0) {
7070                pr_err("error %d\n", rc);
7071                goto rw_error;
7072        }
7073        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7074        if (rc != 0) {
7075                pr_err("error %d\n", rc);
7076                goto rw_error;
7077        }
7078        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7079        if (rc != 0) {
7080                pr_err("error %d\n", rc);
7081                goto rw_error;
7082        }
7083        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7084        if (rc != 0) {
7085                pr_err("error %d\n", rc);
7086                goto rw_error;
7087        }
7088        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7089        if (rc != 0) {
7090                pr_err("error %d\n", rc);
7091                goto rw_error;
7092        }
7093        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7094        if (rc != 0) {
7095                pr_err("error %d\n", rc);
7096                goto rw_error;
7097        }
7098        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
7099        if (rc != 0) {
7100                pr_err("error %d\n", rc);
7101                goto rw_error;
7102        }
7103        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
7104        if (rc != 0) {
7105                pr_err("error %d\n", rc);
7106                goto rw_error;
7107        }
7108        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7109        if (rc != 0) {
7110                pr_err("error %d\n", rc);
7111                goto rw_error;
7112        }
7113        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7114        if (rc != 0) {
7115                pr_err("error %d\n", rc);
7116                goto rw_error;
7117        }
7118        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
7119        if (rc != 0) {
7120                pr_err("error %d\n", rc);
7121                goto rw_error;
7122        }
7123
7124        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
7125        if (rc != 0) {
7126                pr_err("error %d\n", rc);
7127                goto rw_error;
7128        }
7129
7130        return 0;
7131rw_error:
7132        return rc;
7133}
7134
7135/*============================================================================*/
7136
7137/*
7138* \fn int set_qam64 ()
7139* \brief QAM64 specific setup
7140* \param demod instance of demod.
7141* \return int.
7142*/
7143static int set_qam64(struct drx_demod_instance *demod)
7144{
7145        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7146        int rc;
7147        static const u8 qam_dq_qual_fun[] = {
7148                /* this is hw reset value. no necessary to re-write */
7149                DRXJ_16TO8(4),  /* fun0  */
7150                DRXJ_16TO8(4),  /* fun1  */
7151                DRXJ_16TO8(4),  /* fun2  */
7152                DRXJ_16TO8(4),  /* fun3  */
7153                DRXJ_16TO8(6),  /* fun4  */
7154                DRXJ_16TO8(6),  /* fun5  */
7155        };
7156        static const u8 qam_eq_cma_rad[] = {
7157                DRXJ_16TO8(13336),      /* RAD0  */
7158                DRXJ_16TO8(12618),      /* RAD1  */
7159                DRXJ_16TO8(11988),      /* RAD2  */
7160                DRXJ_16TO8(13809),      /* RAD3  */
7161                DRXJ_16TO8(13809),      /* RAD4  */
7162                DRXJ_16TO8(15609),      /* RAD5  */
7163        };
7164
7165        rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7166        if (rc != 0) {
7167                pr_err("error %d\n", rc);
7168                goto rw_error;
7169        }
7170        rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7171        if (rc != 0) {
7172                pr_err("error %d\n", rc);
7173                goto rw_error;
7174        }
7175
7176        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
7177        if (rc != 0) {
7178                pr_err("error %d\n", rc);
7179                goto rw_error;
7180        }
7181        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7182        if (rc != 0) {
7183                pr_err("error %d\n", rc);
7184                goto rw_error;
7185        }
7186        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7187        if (rc != 0) {
7188                pr_err("error %d\n", rc);
7189                goto rw_error;
7190        }
7191        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
7192        if (rc != 0) {
7193                pr_err("error %d\n", rc);
7194                goto rw_error;
7195        }
7196        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7197        if (rc != 0) {
7198                pr_err("error %d\n", rc);
7199                goto rw_error;
7200        }
7201        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
7202        if (rc != 0) {
7203                pr_err("error %d\n", rc);
7204                goto rw_error;
7205        }
7206
7207        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7208        if (rc != 0) {
7209                pr_err("error %d\n", rc);
7210                goto rw_error;
7211        }
7212        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
7213        if (rc != 0) {
7214                pr_err("error %d\n", rc);
7215                goto rw_error;
7216        }
7217        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7218        if (rc != 0) {
7219                pr_err("error %d\n", rc);
7220                goto rw_error;
7221        }
7222
7223        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
7224        if (rc != 0) {
7225                pr_err("error %d\n", rc);
7226                goto rw_error;
7227        }
7228        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
7229        if (rc != 0) {
7230                pr_err("error %d\n", rc);
7231                goto rw_error;
7232        }
7233        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
7234        if (rc != 0) {
7235                pr_err("error %d\n", rc);
7236                goto rw_error;
7237        }
7238        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
7239        if (rc != 0) {
7240                pr_err("error %d\n", rc);
7241                goto rw_error;
7242        }
7243        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
7244        if (rc != 0) {
7245                pr_err("error %d\n", rc);
7246                goto rw_error;
7247        }
7248        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
7249        if (rc != 0) {
7250                pr_err("error %d\n", rc);
7251                goto rw_error;
7252        }
7253        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
7254        if (rc != 0) {
7255                pr_err("error %d\n", rc);
7256                goto rw_error;
7257        }
7258
7259        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7260        if (rc != 0) {
7261                pr_err("error %d\n", rc);
7262                goto rw_error;
7263        }
7264        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7265        if (rc != 0) {
7266                pr_err("error %d\n", rc);
7267                goto rw_error;
7268        }
7269        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7270        if (rc != 0) {
7271                pr_err("error %d\n", rc);
7272                goto rw_error;
7273        }
7274        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
7275        if (rc != 0) {
7276                pr_err("error %d\n", rc);
7277                goto rw_error;
7278        }
7279        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7280        if (rc != 0) {
7281                pr_err("error %d\n", rc);
7282                goto rw_error;
7283        }
7284        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7285        if (rc != 0) {
7286                pr_err("error %d\n", rc);
7287                goto rw_error;
7288        }
7289        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
7290        if (rc != 0) {
7291                pr_err("error %d\n", rc);
7292                goto rw_error;
7293        }
7294        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7295        if (rc != 0) {
7296                pr_err("error %d\n", rc);
7297                goto rw_error;
7298        }
7299        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7300        if (rc != 0) {
7301                pr_err("error %d\n", rc);
7302                goto rw_error;
7303        }
7304        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7305        if (rc != 0) {
7306                pr_err("error %d\n", rc);
7307                goto rw_error;
7308        }
7309        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7310        if (rc != 0) {
7311                pr_err("error %d\n", rc);
7312                goto rw_error;
7313        }
7314        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7315        if (rc != 0) {
7316                pr_err("error %d\n", rc);
7317                goto rw_error;
7318        }
7319        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7320        if (rc != 0) {
7321                pr_err("error %d\n", rc);
7322                goto rw_error;
7323        }
7324        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7325        if (rc != 0) {
7326                pr_err("error %d\n", rc);
7327                goto rw_error;
7328        }
7329        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7330        if (rc != 0) {
7331                pr_err("error %d\n", rc);
7332                goto rw_error;
7333        }
7334        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
7335        if (rc != 0) {
7336                pr_err("error %d\n", rc);
7337                goto rw_error;
7338        }
7339        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
7340        if (rc != 0) {
7341                pr_err("error %d\n", rc);
7342                goto rw_error;
7343        }
7344        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7345        if (rc != 0) {
7346                pr_err("error %d\n", rc);
7347                goto rw_error;
7348        }
7349        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7350        if (rc != 0) {
7351                pr_err("error %d\n", rc);
7352                goto rw_error;
7353        }
7354        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
7355        if (rc != 0) {
7356                pr_err("error %d\n", rc);
7357                goto rw_error;
7358        }
7359
7360        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
7361        if (rc != 0) {
7362                pr_err("error %d\n", rc);
7363                goto rw_error;
7364        }
7365
7366        return 0;
7367rw_error:
7368        return rc;
7369}
7370
7371/*============================================================================*/
7372
7373/*
7374* \fn int set_qam128 ()
7375* \brief QAM128 specific setup
7376* \param demod: instance of demod.
7377* \return int.
7378*/
7379static int set_qam128(struct drx_demod_instance *demod)
7380{
7381        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7382        int rc;
7383        static const u8 qam_dq_qual_fun[] = {
7384                DRXJ_16TO8(6),  /* fun0  */
7385                DRXJ_16TO8(6),  /* fun1  */
7386                DRXJ_16TO8(6),  /* fun2  */
7387                DRXJ_16TO8(6),  /* fun3  */
7388                DRXJ_16TO8(9),  /* fun4  */
7389                DRXJ_16TO8(9),  /* fun5  */
7390        };
7391        static const u8 qam_eq_cma_rad[] = {
7392                DRXJ_16TO8(6164),       /* RAD0  */
7393                DRXJ_16TO8(6598),       /* RAD1  */
7394                DRXJ_16TO8(6394),       /* RAD2  */
7395                DRXJ_16TO8(6409),       /* RAD3  */
7396                DRXJ_16TO8(6656),       /* RAD4  */
7397                DRXJ_16TO8(7238),       /* RAD5  */
7398        };
7399
7400        rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7401        if (rc != 0) {
7402                pr_err("error %d\n", rc);
7403                goto rw_error;
7404        }
7405        rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7406        if (rc != 0) {
7407                pr_err("error %d\n", rc);
7408                goto rw_error;
7409        }
7410
7411        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
7412        if (rc != 0) {
7413                pr_err("error %d\n", rc);
7414                goto rw_error;
7415        }
7416        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7417        if (rc != 0) {
7418                pr_err("error %d\n", rc);
7419                goto rw_error;
7420        }
7421        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7422        if (rc != 0) {
7423                pr_err("error %d\n", rc);
7424                goto rw_error;
7425        }
7426        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
7427        if (rc != 0) {
7428                pr_err("error %d\n", rc);
7429                goto rw_error;
7430        }
7431        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7432        if (rc != 0) {
7433                pr_err("error %d\n", rc);
7434                goto rw_error;
7435        }
7436        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
7437        if (rc != 0) {
7438                pr_err("error %d\n", rc);
7439                goto rw_error;
7440        }
7441
7442        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7443        if (rc != 0) {
7444                pr_err("error %d\n", rc);
7445                goto rw_error;
7446        }
7447        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
7448        if (rc != 0) {
7449                pr_err("error %d\n", rc);
7450                goto rw_error;
7451        }
7452        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7453        if (rc != 0) {
7454                pr_err("error %d\n", rc);
7455                goto rw_error;
7456        }
7457
7458        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
7459        if (rc != 0) {
7460                pr_err("error %d\n", rc);
7461                goto rw_error;
7462        }
7463        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
7464        if (rc != 0) {
7465                pr_err("error %d\n", rc);
7466                goto rw_error;
7467        }
7468        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
7469        if (rc != 0) {
7470                pr_err("error %d\n", rc);
7471                goto rw_error;
7472        }
7473        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
7474        if (rc != 0) {
7475                pr_err("error %d\n", rc);
7476                goto rw_error;
7477        }
7478        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
7479        if (rc != 0) {
7480                pr_err("error %d\n", rc);
7481                goto rw_error;
7482        }
7483        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
7484        if (rc != 0) {
7485                pr_err("error %d\n", rc);
7486                goto rw_error;
7487        }
7488        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
7489        if (rc != 0) {
7490                pr_err("error %d\n", rc);
7491                goto rw_error;
7492        }
7493
7494        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7495        if (rc != 0) {
7496                pr_err("error %d\n", rc);
7497                goto rw_error;
7498        }
7499        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7500        if (rc != 0) {
7501                pr_err("error %d\n", rc);
7502                goto rw_error;
7503        }
7504        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7505        if (rc != 0) {
7506                pr_err("error %d\n", rc);
7507                goto rw_error;
7508        }
7509        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
7510        if (rc != 0) {
7511                pr_err("error %d\n", rc);
7512                goto rw_error;
7513        }
7514        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7515        if (rc != 0) {
7516                pr_err("error %d\n", rc);
7517                goto rw_error;
7518        }
7519        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7520        if (rc != 0) {
7521                pr_err("error %d\n", rc);
7522                goto rw_error;
7523        }
7524        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
7525        if (rc != 0) {
7526                pr_err("error %d\n", rc);
7527                goto rw_error;
7528        }
7529        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7530        if (rc != 0) {
7531                pr_err("error %d\n", rc);
7532                goto rw_error;
7533        }
7534        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7535        if (rc != 0) {
7536                pr_err("error %d\n", rc);
7537                goto rw_error;
7538        }
7539        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7540        if (rc != 0) {
7541                pr_err("error %d\n", rc);
7542                goto rw_error;
7543        }
7544        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7545        if (rc != 0) {
7546                pr_err("error %d\n", rc);
7547                goto rw_error;
7548        }
7549        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7550        if (rc != 0) {
7551                pr_err("error %d\n", rc);
7552                goto rw_error;
7553        }
7554        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7555        if (rc != 0) {
7556                pr_err("error %d\n", rc);
7557                goto rw_error;
7558        }
7559        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7560        if (rc != 0) {
7561                pr_err("error %d\n", rc);
7562                goto rw_error;
7563        }
7564        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7565        if (rc != 0) {
7566                pr_err("error %d\n", rc);
7567                goto rw_error;
7568        }
7569        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
7570        if (rc != 0) {
7571                pr_err("error %d\n", rc);
7572                goto rw_error;
7573        }
7574        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
7575        if (rc != 0) {
7576                pr_err("error %d\n", rc);
7577                goto rw_error;
7578        }
7579        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7580        if (rc != 0) {
7581                pr_err("error %d\n", rc);
7582                goto rw_error;
7583        }
7584        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7585        if (rc != 0) {
7586                pr_err("error %d\n", rc);
7587                goto rw_error;
7588        }
7589        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
7590        if (rc != 0) {
7591                pr_err("error %d\n", rc);
7592                goto rw_error;
7593        }
7594
7595        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
7596        if (rc != 0) {
7597                pr_err("error %d\n", rc);
7598                goto rw_error;
7599        }
7600
7601        return 0;
7602rw_error:
7603        return rc;
7604}
7605
7606/*============================================================================*/
7607
7608/*
7609* \fn int set_qam256 ()
7610* \brief QAM256 specific setup
7611* \param demod: instance of demod.
7612* \return int.
7613*/
7614static int set_qam256(struct drx_demod_instance *demod)
7615{
7616        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7617        int rc;
7618        static const u8 qam_dq_qual_fun[] = {
7619                DRXJ_16TO8(8),  /* fun0  */
7620                DRXJ_16TO8(8),  /* fun1  */
7621                DRXJ_16TO8(8),  /* fun2  */
7622                DRXJ_16TO8(8),  /* fun3  */
7623                DRXJ_16TO8(12), /* fun4  */
7624                DRXJ_16TO8(12), /* fun5  */
7625        };
7626        static const u8 qam_eq_cma_rad[] = {
7627                DRXJ_16TO8(12345),      /* RAD0  */
7628                DRXJ_16TO8(12345),      /* RAD1  */
7629                DRXJ_16TO8(13626),      /* RAD2  */
7630                DRXJ_16TO8(12931),      /* RAD3  */
7631                DRXJ_16TO8(14719),      /* RAD4  */
7632                DRXJ_16TO8(15356),      /* RAD5  */
7633        };
7634
7635        rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7636        if (rc != 0) {
7637                pr_err("error %d\n", rc);
7638                goto rw_error;
7639        }
7640        rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7641        if (rc != 0) {
7642                pr_err("error %d\n", rc);
7643                goto rw_error;
7644        }
7645
7646        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
7647        if (rc != 0) {
7648                pr_err("error %d\n", rc);
7649                goto rw_error;
7650        }
7651        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7652        if (rc != 0) {
7653                pr_err("error %d\n", rc);
7654                goto rw_error;
7655        }
7656        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7657        if (rc != 0) {
7658                pr_err("error %d\n", rc);
7659                goto rw_error;
7660        }
7661        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
7662        if (rc != 0) {
7663                pr_err("error %d\n", rc);
7664                goto rw_error;
7665        }
7666        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7667        if (rc != 0) {
7668                pr_err("error %d\n", rc);
7669                goto rw_error;
7670        }
7671        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
7672        if (rc != 0) {
7673                pr_err("error %d\n", rc);
7674                goto rw_error;
7675        }
7676
7677        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7678        if (rc != 0) {
7679                pr_err("error %d\n", rc);
7680                goto rw_error;
7681        }
7682        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
7683        if (rc != 0) {
7684                pr_err("error %d\n", rc);
7685                goto rw_error;
7686        }
7687        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7688        if (rc != 0) {
7689                pr_err("error %d\n", rc);
7690                goto rw_error;
7691        }
7692
7693        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
7694        if (rc != 0) {
7695                pr_err("error %d\n", rc);
7696                goto rw_error;
7697        }
7698        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
7699        if (rc != 0) {
7700                pr_err("error %d\n", rc);
7701                goto rw_error;
7702        }
7703        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
7704        if (rc != 0) {
7705                pr_err("error %d\n", rc);
7706                goto rw_error;
7707        }
7708        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
7709        if (rc != 0) {
7710                pr_err("error %d\n", rc);
7711                goto rw_error;
7712        }
7713        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
7714        if (rc != 0) {
7715                pr_err("error %d\n", rc);
7716                goto rw_error;
7717        }
7718        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
7719        if (rc != 0) {
7720                pr_err("error %d\n", rc);
7721                goto rw_error;
7722        }
7723        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
7724        if (rc != 0) {
7725                pr_err("error %d\n", rc);
7726                goto rw_error;
7727        }
7728
7729        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7730        if (rc != 0) {
7731                pr_err("error %d\n", rc);
7732                goto rw_error;
7733        }
7734        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7735        if (rc != 0) {
7736                pr_err("error %d\n", rc);
7737                goto rw_error;
7738        }
7739        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7740        if (rc != 0) {
7741                pr_err("error %d\n", rc);
7742                goto rw_error;
7743        }
7744        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
7745        if (rc != 0) {
7746                pr_err("error %d\n", rc);
7747                goto rw_error;
7748        }
7749        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7750        if (rc != 0) {
7751                pr_err("error %d\n", rc);
7752                goto rw_error;
7753        }
7754        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7755        if (rc != 0) {
7756                pr_err("error %d\n", rc);
7757                goto rw_error;
7758        }
7759        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
7760        if (rc != 0) {
7761                pr_err("error %d\n", rc);
7762                goto rw_error;
7763        }
7764        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7765        if (rc != 0) {
7766                pr_err("error %d\n", rc);
7767                goto rw_error;
7768        }
7769        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7770        if (rc != 0) {
7771                pr_err("error %d\n", rc);
7772                goto rw_error;
7773        }
7774        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7775        if (rc != 0) {
7776                pr_err("error %d\n", rc);
7777                goto rw_error;
7778        }
7779        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7780        if (rc != 0) {
7781                pr_err("error %d\n", rc);
7782                goto rw_error;
7783        }
7784        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7785        if (rc != 0) {
7786                pr_err("error %d\n", rc);
7787                goto rw_error;
7788        }
7789        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7790        if (rc != 0) {
7791                pr_err("error %d\n", rc);
7792                goto rw_error;
7793        }
7794        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7795        if (rc != 0) {
7796                pr_err("error %d\n", rc);
7797                goto rw_error;
7798        }
7799        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7800        if (rc != 0) {
7801                pr_err("error %d\n", rc);
7802                goto rw_error;
7803        }
7804        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
7805        if (rc != 0) {
7806                pr_err("error %d\n", rc);
7807                goto rw_error;
7808        }
7809        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
7810        if (rc != 0) {
7811                pr_err("error %d\n", rc);
7812                goto rw_error;
7813        }
7814        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7815        if (rc != 0) {
7816                pr_err("error %d\n", rc);
7817                goto rw_error;
7818        }
7819        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7820        if (rc != 0) {
7821                pr_err("error %d\n", rc);
7822                goto rw_error;
7823        }
7824        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
7825        if (rc != 0) {
7826                pr_err("error %d\n", rc);
7827                goto rw_error;
7828        }
7829
7830        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
7831        if (rc != 0) {
7832                pr_err("error %d\n", rc);
7833                goto rw_error;
7834        }
7835
7836        return 0;
7837rw_error:
7838        return rc;
7839}
7840
7841/*============================================================================*/
7842#define QAM_SET_OP_ALL 0x1
7843#define QAM_SET_OP_CONSTELLATION 0x2
7844#define QAM_SET_OP_SPECTRUM 0X4
7845
7846/*
7847* \fn int set_qam ()
7848* \brief Set QAM demod.
7849* \param demod:   instance of demod.
7850* \param channel: pointer to channel data.
7851* \return int.
7852*/
7853static int
7854set_qam(struct drx_demod_instance *demod,
7855        struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
7856{
7857        struct i2c_device_addr *dev_addr = NULL;
7858        struct drxj_data *ext_attr = NULL;
7859        struct drx_common_attr *common_attr = NULL;
7860        int rc;
7861        u32 adc_frequency = 0;
7862        u32 iqm_rc_rate = 0;
7863        u16 cmd_result = 0;
7864        u16 lc_symbol_freq = 0;
7865        u16 iqm_rc_stretch = 0;
7866        u16 set_env_parameters = 0;
7867        u16 set_param_parameters[2] = { 0 };
7868        struct drxjscu_cmd cmd_scu = { /* command      */ 0,
7869                /* parameter_len */ 0,
7870                /* result_len    */ 0,
7871                /* parameter    */ NULL,
7872                /* result       */ NULL
7873        };
7874        static const u8 qam_a_taps[] = {
7875                DRXJ_16TO8(-1), /* re0  */
7876                DRXJ_16TO8(1),  /* re1  */
7877                DRXJ_16TO8(1),  /* re2  */
7878                DRXJ_16TO8(-1), /* re3  */
7879                DRXJ_16TO8(-1), /* re4  */
7880                DRXJ_16TO8(2),  /* re5  */
7881                DRXJ_16TO8(1),  /* re6  */
7882                DRXJ_16TO8(-2), /* re7  */
7883                DRXJ_16TO8(0),  /* re8  */
7884                DRXJ_16TO8(3),  /* re9  */
7885                DRXJ_16TO8(-1), /* re10 */
7886                DRXJ_16TO8(-3), /* re11 */
7887                DRXJ_16TO8(4),  /* re12 */
7888                DRXJ_16TO8(1),  /* re13 */
7889                DRXJ_16TO8(-8), /* re14 */
7890                DRXJ_16TO8(4),  /* re15 */
7891                DRXJ_16TO8(13), /* re16 */
7892                DRXJ_16TO8(-13),        /* re17 */
7893                DRXJ_16TO8(-19),        /* re18 */
7894                DRXJ_16TO8(28), /* re19 */
7895                DRXJ_16TO8(25), /* re20 */
7896                DRXJ_16TO8(-53),        /* re21 */
7897                DRXJ_16TO8(-31),        /* re22 */
7898                DRXJ_16TO8(96), /* re23 */
7899                DRXJ_16TO8(37), /* re24 */
7900                DRXJ_16TO8(-190),       /* re25 */
7901                DRXJ_16TO8(-40),        /* re26 */
7902                DRXJ_16TO8(619) /* re27 */
7903        };
7904        static const u8 qam_b64_taps[] = {
7905                DRXJ_16TO8(0),  /* re0  */
7906                DRXJ_16TO8(-2), /* re1  */
7907                DRXJ_16TO8(1),  /* re2  */
7908                DRXJ_16TO8(2),  /* re3  */
7909                DRXJ_16TO8(-2), /* re4  */
7910                DRXJ_16TO8(0),  /* re5  */
7911                DRXJ_16TO8(4),  /* re6  */
7912                DRXJ_16TO8(-2), /* re7  */
7913                DRXJ_16TO8(-4), /* re8  */
7914                DRXJ_16TO8(4),  /* re9  */
7915                DRXJ_16TO8(3),  /* re10 */
7916                DRXJ_16TO8(-6), /* re11 */
7917                DRXJ_16TO8(0),  /* re12 */
7918                DRXJ_16TO8(6),  /* re13 */
7919                DRXJ_16TO8(-5), /* re14 */
7920                DRXJ_16TO8(-3), /* re15 */
7921                DRXJ_16TO8(11), /* re16 */
7922                DRXJ_16TO8(-4), /* re17 */
7923                DRXJ_16TO8(-19),        /* re18 */
7924                DRXJ_16TO8(19), /* re19 */
7925                DRXJ_16TO8(28), /* re20 */
7926                DRXJ_16TO8(-45),        /* re21 */
7927                DRXJ_16TO8(-36),        /* re22 */
7928                DRXJ_16TO8(90), /* re23 */
7929                DRXJ_16TO8(42), /* re24 */
7930                DRXJ_16TO8(-185),       /* re25 */
7931                DRXJ_16TO8(-46),        /* re26 */
7932                DRXJ_16TO8(614) /* re27 */
7933        };
7934        static const u8 qam_b256_taps[] = {
7935                DRXJ_16TO8(-2), /* re0  */
7936                DRXJ_16TO8(4),  /* re1  */
7937                DRXJ_16TO8(1),  /* re2  */
7938                DRXJ_16TO8(-4), /* re3  */
7939                DRXJ_16TO8(0),  /* re4  */
7940                DRXJ_16TO8(4),  /* re5  */
7941                DRXJ_16TO8(-2), /* re6  */
7942                DRXJ_16TO8(-4), /* re7  */
7943                DRXJ_16TO8(5),  /* re8  */
7944                DRXJ_16TO8(2),  /* re9  */
7945                DRXJ_16TO8(-8), /* re10 */
7946                DRXJ_16TO8(2),  /* re11 */
7947                DRXJ_16TO8(11), /* re12 */
7948                DRXJ_16TO8(-8), /* re13 */
7949                DRXJ_16TO8(-15),        /* re14 */
7950                DRXJ_16TO8(16), /* re15 */
7951                DRXJ_16TO8(19), /* re16 */
7952                DRXJ_16TO8(-27),        /* re17 */
7953                DRXJ_16TO8(-22),        /* re18 */
7954                DRXJ_16TO8(44), /* re19 */
7955                DRXJ_16TO8(26), /* re20 */
7956                DRXJ_16TO8(-69),        /* re21 */
7957                DRXJ_16TO8(-28),        /* re22 */
7958                DRXJ_16TO8(110),        /* re23 */
7959                DRXJ_16TO8(31), /* re24 */
7960                DRXJ_16TO8(-201),       /* re25 */
7961                DRXJ_16TO8(-32),        /* re26 */
7962                DRXJ_16TO8(628) /* re27 */
7963        };
7964        static const u8 qam_c_taps[] = {
7965                DRXJ_16TO8(-3), /* re0  */
7966                DRXJ_16TO8(3),  /* re1  */
7967                DRXJ_16TO8(2),  /* re2  */
7968                DRXJ_16TO8(-4), /* re3  */
7969                DRXJ_16TO8(0),  /* re4  */
7970                DRXJ_16TO8(4),  /* re5  */
7971                DRXJ_16TO8(-1), /* re6  */
7972                DRXJ_16TO8(-4), /* re7  */
7973                DRXJ_16TO8(3),  /* re8  */
7974                DRXJ_16TO8(3),  /* re9  */
7975                DRXJ_16TO8(-5), /* re10 */
7976                DRXJ_16TO8(0),  /* re11 */
7977                DRXJ_16TO8(9),  /* re12 */
7978                DRXJ_16TO8(-4), /* re13 */
7979                DRXJ_16TO8(-12),        /* re14 */
7980                DRXJ_16TO8(10), /* re15 */
7981                DRXJ_16TO8(16), /* re16 */
7982                DRXJ_16TO8(-21),        /* re17 */
7983                DRXJ_16TO8(-20),        /* re18 */
7984                DRXJ_16TO8(37), /* re19 */
7985                DRXJ_16TO8(25), /* re20 */
7986                DRXJ_16TO8(-62),        /* re21 */
7987                DRXJ_16TO8(-28),        /* re22 */
7988                DRXJ_16TO8(105),        /* re23 */
7989                DRXJ_16TO8(31), /* re24 */
7990                DRXJ_16TO8(-197),       /* re25 */
7991                DRXJ_16TO8(-33),        /* re26 */
7992                DRXJ_16TO8(626) /* re27 */
7993        };
7994
7995        dev_addr = demod->my_i2c_dev_addr;
7996        ext_attr = (struct drxj_data *) demod->my_ext_attr;
7997        common_attr = (struct drx_common_attr *) demod->my_common_attr;
7998
7999        if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8000                if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8001                        switch (channel->constellation) {
8002                        case DRX_CONSTELLATION_QAM256:
8003                                iqm_rc_rate = 0x00AE3562;
8004                                lc_symbol_freq =
8005                                    QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
8006                                channel->symbolrate = 5360537;
8007                                iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
8008                                break;
8009                        case DRX_CONSTELLATION_QAM64:
8010                                iqm_rc_rate = 0x00C05A0E;
8011                                lc_symbol_freq = 409;
8012                                channel->symbolrate = 5056941;
8013                                iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
8014                                break;
8015                        default:
8016                                return -EINVAL;
8017                        }
8018                } else {
8019                        adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
8020                        if (channel->symbolrate == 0) {
8021                                pr_err("error: channel symbolrate is zero!\n");
8022                                return -EIO;
8023                        }
8024                        iqm_rc_rate =
8025                            (adc_frequency / channel->symbolrate) * (1 << 21) +
8026                            (frac28
8027                             ((adc_frequency % channel->symbolrate),
8028                              channel->symbolrate) >> 7) - (1 << 23);
8029                        lc_symbol_freq =
8030                            (u16) (frac28
8031                                     (channel->symbolrate +
8032                                      (adc_frequency >> 13),
8033                                      adc_frequency) >> 16);
8034                        if (lc_symbol_freq > 511)
8035                                lc_symbol_freq = 511;
8036
8037                        iqm_rc_stretch = 21;
8038                }
8039
8040                if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8041                        set_env_parameters = QAM_TOP_ANNEX_A;   /* annex             */
8042                        set_param_parameters[0] = channel->constellation;       /* constellation     */
8043                        set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
8044                } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8045                        set_env_parameters = QAM_TOP_ANNEX_B;   /* annex             */
8046                        set_param_parameters[0] = channel->constellation;       /* constellation     */
8047                        set_param_parameters[1] = channel->interleavemode;      /* interleave mode   */
8048                } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8049                        set_env_parameters = QAM_TOP_ANNEX_C;   /* annex             */
8050                        set_param_parameters[0] = channel->constellation;       /* constellation     */
8051                        set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
8052                } else {
8053                        return -EINVAL;
8054                }
8055        }
8056
8057        if (op & QAM_SET_OP_ALL) {
8058                /*
8059                   STEP 1: reset demodulator
8060                   resets IQM, QAM and FEC HW blocks
8061                   resets SCU variables
8062                 */
8063                /* stop all comm_exec */
8064                rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
8065                if (rc != 0) {
8066                        pr_err("error %d\n", rc);
8067                        goto rw_error;
8068                }
8069                rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
8070                if (rc != 0) {
8071                        pr_err("error %d\n", rc);
8072                        goto rw_error;
8073                }
8074                rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
8075                if (rc != 0) {
8076                        pr_err("error %d\n", rc);
8077                        goto rw_error;
8078                }
8079                rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
8080                if (rc != 0) {
8081                        pr_err("error %d\n", rc);
8082                        goto rw_error;
8083                }
8084                rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
8085                if (rc != 0) {
8086                        pr_err("error %d\n", rc);
8087                        goto rw_error;
8088                }
8089                rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
8090                if (rc != 0) {
8091                        pr_err("error %d\n", rc);
8092                        goto rw_error;
8093                }
8094                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
8095                if (rc != 0) {
8096                        pr_err("error %d\n", rc);
8097                        goto rw_error;
8098                }
8099
8100                cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8101                    SCU_RAM_COMMAND_CMD_DEMOD_RESET;
8102                cmd_scu.parameter_len = 0;
8103                cmd_scu.result_len = 1;
8104                cmd_scu.parameter = NULL;
8105                cmd_scu.result = &cmd_result;
8106                rc = scu_command(dev_addr, &cmd_scu);
8107                if (rc != 0) {
8108                        pr_err("error %d\n", rc);
8109                        goto rw_error;
8110                }
8111        }
8112
8113        if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8114                /*
8115                   STEP 2: configure demodulator
8116                   -set env
8117                   -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
8118                 */
8119                cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8120                    SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
8121                cmd_scu.parameter_len = 1;
8122                cmd_scu.result_len = 1;
8123                cmd_scu.parameter = &set_env_parameters;
8124                cmd_scu.result = &cmd_result;
8125                rc = scu_command(dev_addr, &cmd_scu);
8126                if (rc != 0) {
8127                        pr_err("error %d\n", rc);
8128                        goto rw_error;
8129                }
8130
8131                cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8132                    SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
8133                cmd_scu.parameter_len = 2;
8134                cmd_scu.result_len = 1;
8135                cmd_scu.parameter = set_param_parameters;
8136                cmd_scu.result = &cmd_result;
8137                rc = scu_command(dev_addr, &cmd_scu);
8138                if (rc != 0) {
8139                        pr_err("error %d\n", rc);
8140                        goto rw_error;
8141                }
8142                /* set symbol rate */
8143                rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
8144                if (rc != 0) {
8145                        pr_err("error %d\n", rc);
8146                        goto rw_error;
8147                }
8148                ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
8149                rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
8150                if (rc != 0) {
8151                        pr_err("error %d\n", rc);
8152                        goto rw_error;
8153                }
8154        }
8155        /* STEP 3: enable the system in a mode where the ADC provides valid signal
8156           setup constellation independent registers */
8157        /* from qam_cmd.py script (qam_driver_b) */
8158        /* TODO: remove re-writes of HW reset values */
8159        if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
8160                rc = set_frequency(demod, channel, tuner_freq_offset);
8161                if (rc != 0) {
8162                        pr_err("error %d\n", rc);
8163                        goto rw_error;
8164                }
8165        }
8166
8167        if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8168
8169                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
8170                if (rc != 0) {
8171                        pr_err("error %d\n", rc);
8172                        goto rw_error;
8173                }
8174                rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
8175                if (rc != 0) {
8176                        pr_err("error %d\n", rc);
8177                        goto rw_error;
8178                }
8179        }
8180
8181        if (op & QAM_SET_OP_ALL) {
8182                if (!ext_attr->has_lna) {
8183                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
8184                        if (rc != 0) {
8185                                pr_err("error %d\n", rc);
8186                                goto rw_error;
8187                        }
8188                }
8189                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
8190                if (rc != 0) {
8191                        pr_err("error %d\n", rc);
8192                        goto rw_error;
8193                }
8194                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
8195                if (rc != 0) {
8196                        pr_err("error %d\n", rc);
8197                        goto rw_error;
8198                }
8199                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
8200                if (rc != 0) {
8201                        pr_err("error %d\n", rc);
8202                        goto rw_error;
8203                }
8204
8205                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
8206                if (rc != 0) {
8207                        pr_err("error %d\n", rc);
8208                        goto rw_error;
8209                }       /* scu temporary shut down agc */
8210
8211                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
8212                if (rc != 0) {
8213                        pr_err("error %d\n", rc);
8214                        goto rw_error;
8215                }
8216                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
8217                if (rc != 0) {
8218                        pr_err("error %d\n", rc);
8219                        goto rw_error;
8220                }
8221                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
8222                if (rc != 0) {
8223                        pr_err("error %d\n", rc);
8224                        goto rw_error;
8225                }
8226                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
8227                if (rc != 0) {
8228                        pr_err("error %d\n", rc);
8229                        goto rw_error;
8230                }
8231                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);
8232                if (rc != 0) {
8233                        pr_err("error %d\n", rc);
8234                        goto rw_error;
8235                }
8236                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
8237                if (rc != 0) {
8238                        pr_err("error %d\n", rc);
8239                        goto rw_error;
8240                }
8241                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
8242                if (rc != 0) {
8243                        pr_err("error %d\n", rc);
8244                        goto rw_error;
8245                }
8246
8247                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
8248                if (rc != 0) {
8249                        pr_err("error %d\n", rc);
8250                        goto rw_error;
8251                }
8252                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
8253                if (rc != 0) {
8254                        pr_err("error %d\n", rc);
8255                        goto rw_error;
8256                }       /*! reset default val ! */
8257
8258                rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
8259                if (rc != 0) {
8260                        pr_err("error %d\n", rc);
8261                        goto rw_error;
8262                }       /*! reset default val ! */
8263                if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8264                        rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
8265                        if (rc != 0) {
8266                                pr_err("error %d\n", rc);
8267                                goto rw_error;
8268                        }       /*! reset default val ! */
8269                        rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
8270                        if (rc != 0) {
8271                                pr_err("error %d\n", rc);
8272                                goto rw_error;
8273                        }       /*! reset default val ! */
8274                        rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
8275                        if (rc != 0) {
8276                                pr_err("error %d\n", rc);
8277                                goto rw_error;
8278                        }       /*! reset default val ! */
8279                } else {
8280                        switch (channel->constellation) {
8281                        case DRX_CONSTELLATION_QAM16:
8282                        case DRX_CONSTELLATION_QAM64:
8283                        case DRX_CONSTELLATION_QAM256:
8284                                rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
8285                                if (rc != 0) {
8286                                        pr_err("error %d\n", rc);
8287                                        goto rw_error;
8288                                }
8289                                rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
8290                                if (rc != 0) {
8291                                        pr_err("error %d\n", rc);
8292                                        goto rw_error;
8293                                }
8294                                rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
8295                                if (rc != 0) {
8296                                        pr_err("error %d\n", rc);
8297                                        goto rw_error;
8298                                }       /*! reset default val ! */
8299                                break;
8300                        case DRX_CONSTELLATION_QAM32:
8301                        case DRX_CONSTELLATION_QAM128:
8302                                rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
8303                                if (rc != 0) {
8304                                        pr_err("error %d\n", rc);
8305                                        goto rw_error;
8306                                }
8307                                rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
8308                                if (rc != 0) {
8309                                        pr_err("error %d\n", rc);
8310                                        goto rw_error;
8311                                }
8312                                rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
8313                                if (rc != 0) {
8314                                        pr_err("error %d\n", rc);
8315                                        goto rw_error;
8316                                }
8317                                break;
8318                        default:
8319                                return -EIO;
8320                        }       /* switch */
8321                }
8322
8323                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
8324                if (rc != 0) {
8325                        pr_err("error %d\n", rc);
8326                        goto rw_error;
8327                }       /*! reset default val ! */
8328                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
8329                if (rc != 0) {
8330                        pr_err("error %d\n", rc);
8331                        goto rw_error;
8332                }
8333                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
8334                if (rc != 0) {
8335                        pr_err("error %d\n", rc);
8336                        goto rw_error;
8337                }
8338                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
8339                if (rc != 0) {
8340                        pr_err("error %d\n", rc);
8341                        goto rw_error;
8342                }
8343                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);
8344                if (rc != 0) {
8345                        pr_err("error %d\n", rc);
8346                        goto rw_error;
8347                }
8348                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
8349                if (rc != 0) {
8350                        pr_err("error %d\n", rc);
8351                        goto rw_error;
8352                }
8353                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
8354                if (rc != 0) {
8355                        pr_err("error %d\n", rc);
8356                        goto rw_error;
8357                }
8358                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
8359                if (rc != 0) {
8360                        pr_err("error %d\n", rc);
8361                        goto rw_error;
8362                }
8363                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
8364                if (rc != 0) {
8365                        pr_err("error %d\n", rc);
8366                        goto rw_error;
8367                }
8368                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
8369                if (rc != 0) {
8370                        pr_err("error %d\n", rc);
8371                        goto rw_error;
8372                }
8373                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
8374                if (rc != 0) {
8375                        pr_err("error %d\n", rc);
8376                        goto rw_error;
8377                }
8378                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
8379                if (rc != 0) {
8380                        pr_err("error %d\n", rc);
8381                        goto rw_error;
8382                }
8383                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
8384                if (rc != 0) {
8385                        pr_err("error %d\n", rc);
8386                        goto rw_error;
8387                }
8388                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
8389                if (rc != 0) {
8390                        pr_err("error %d\n", rc);
8391                        goto rw_error;
8392                }
8393                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
8394                if (rc != 0) {
8395                        pr_err("error %d\n", rc);
8396                        goto rw_error;
8397                }
8398                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
8399                if (rc != 0) {
8400                        pr_err("error %d\n", rc);
8401                        goto rw_error;
8402                }
8403                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
8404                if (rc != 0) {
8405                        pr_err("error %d\n", rc);
8406                        goto rw_error;
8407                }
8408                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
8409                if (rc != 0) {
8410                        pr_err("error %d\n", rc);
8411                        goto rw_error;
8412                }
8413                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
8414                if (rc != 0) {
8415                        pr_err("error %d\n", rc);
8416                        goto rw_error;
8417                }
8418                rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
8419                if (rc != 0) {
8420                        pr_err("error %d\n", rc);
8421                        goto rw_error;
8422                }
8423
8424                rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
8425                if (rc != 0) {
8426                        pr_err("error %d\n", rc);
8427                        goto rw_error;
8428                }
8429                rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
8430                if (rc != 0) {
8431                        pr_err("error %d\n", rc);
8432                        goto rw_error;
8433                }
8434                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
8435                if (rc != 0) {
8436                        pr_err("error %d\n", rc);
8437                        goto rw_error;
8438                }
8439                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
8440                if (rc != 0) {
8441                        pr_err("error %d\n", rc);
8442                        goto rw_error;
8443                }
8444                rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
8445                if (rc != 0) {
8446                        pr_err("error %d\n", rc);
8447                        goto rw_error;
8448                }
8449
8450                /* No more resets of the IQM, current standard correctly set =>
8451                   now AGCs can be configured. */
8452                /* turn on IQMAF. It has to be in front of setAgc**() */
8453                rc = set_iqm_af(demod, true);
8454                if (rc != 0) {
8455                        pr_err("error %d\n", rc);
8456                        goto rw_error;
8457                }
8458                rc = adc_synchronization(demod);
8459                if (rc != 0) {
8460                        pr_err("error %d\n", rc);
8461                        goto rw_error;
8462                }
8463
8464                rc = init_agc(demod);
8465                if (rc != 0) {
8466                        pr_err("error %d\n", rc);
8467                        goto rw_error;
8468                }
8469                rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
8470                if (rc != 0) {
8471                        pr_err("error %d\n", rc);
8472                        goto rw_error;
8473                }
8474                rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
8475                if (rc != 0) {
8476                        pr_err("error %d\n", rc);
8477                        goto rw_error;
8478                }
8479                {
8480                        /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
8481                           of only the gain */
8482                        struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
8483
8484                        qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
8485                        rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
8486                        if (rc != 0) {
8487                                pr_err("error %d\n", rc);
8488                                goto rw_error;
8489                        }
8490                }
8491                rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
8492                if (rc != 0) {
8493                        pr_err("error %d\n", rc);
8494                        goto rw_error;
8495                }
8496        }
8497
8498        if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8499                if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8500                        rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
8501                        if (rc != 0) {
8502                                pr_err("error %d\n", rc);
8503                                goto rw_error;
8504                        }
8505                        rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
8506                        if (rc != 0) {
8507                                pr_err("error %d\n", rc);
8508                                goto rw_error;
8509                        }
8510                } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8511                        switch (channel->constellation) {
8512                        case DRX_CONSTELLATION_QAM64:
8513                                rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
8514                                if (rc != 0) {
8515                                        pr_err("error %d\n", rc);
8516                                        goto rw_error;
8517                                }
8518                                rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
8519                                if (rc != 0) {
8520                                        pr_err("error %d\n", rc);
8521                                        goto rw_error;
8522                                }
8523                                break;
8524                        case DRX_CONSTELLATION_QAM256:
8525                                rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
8526                                if (rc != 0) {
8527                                        pr_err("error %d\n", rc);
8528                                        goto rw_error;
8529                                }
8530                                rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
8531                                if (rc != 0) {
8532                                        pr_err("error %d\n", rc);
8533                                        goto rw_error;
8534                                }
8535                                break;
8536                        default:
8537                                return -EIO;
8538                        }
8539                } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8540                        rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
8541                        if (rc != 0) {
8542                                pr_err("error %d\n", rc);
8543                                goto rw_error;
8544                        }
8545                        rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
8546                        if (rc != 0) {
8547                                pr_err("error %d\n", rc);
8548                                goto rw_error;
8549                        }
8550                }
8551
8552                /* SETP 4: constellation specific setup */
8553                switch (channel->constellation) {
8554                case DRX_CONSTELLATION_QAM16:
8555                        rc = set_qam16(demod);
8556                        if (rc != 0) {
8557                                pr_err("error %d\n", rc);
8558                                goto rw_error;
8559                        }
8560                        break;
8561                case DRX_CONSTELLATION_QAM32:
8562                        rc = set_qam32(demod);
8563                        if (rc != 0) {
8564                                pr_err("error %d\n", rc);
8565                                goto rw_error;
8566                        }
8567                        break;
8568                case DRX_CONSTELLATION_QAM64:
8569                        rc = set_qam64(demod);
8570                        if (rc != 0) {
8571                                pr_err("error %d\n", rc);
8572                                goto rw_error;
8573                        }
8574                        break;
8575                case DRX_CONSTELLATION_QAM128:
8576                        rc = set_qam128(demod);
8577                        if (rc != 0) {
8578                                pr_err("error %d\n", rc);
8579                                goto rw_error;
8580                        }
8581                        break;
8582                case DRX_CONSTELLATION_QAM256:
8583                        rc = set_qam256(demod);
8584                        if (rc != 0) {
8585                                pr_err("error %d\n", rc);
8586                                goto rw_error;
8587                        }
8588                        break;
8589                default:
8590                        return -EIO;
8591                }               /* switch */
8592        }
8593
8594        if ((op & QAM_SET_OP_ALL)) {
8595                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
8596                if (rc != 0) {
8597                        pr_err("error %d\n", rc);
8598                        goto rw_error;
8599                }
8600
8601                /* Mpeg output has to be in front of FEC active */
8602                rc = set_mpegtei_handling(demod);
8603                if (rc != 0) {
8604                        pr_err("error %d\n", rc);
8605                        goto rw_error;
8606                }
8607                rc = bit_reverse_mpeg_output(demod);
8608                if (rc != 0) {
8609                        pr_err("error %d\n", rc);
8610                        goto rw_error;
8611                }
8612                rc = set_mpeg_start_width(demod);
8613                if (rc != 0) {
8614                        pr_err("error %d\n", rc);
8615                        goto rw_error;
8616                }
8617                {
8618                        /* TODO: move to set_standard after hardware reset value problem is solved */
8619                        /* Configure initial MPEG output */
8620                        struct drx_cfg_mpeg_output cfg_mpeg_output;
8621
8622                        memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
8623                        cfg_mpeg_output.enable_mpeg_output = true;
8624
8625                        rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
8626                        if (rc != 0) {
8627                                pr_err("error %d\n", rc);
8628                                goto rw_error;
8629                        }
8630                }
8631        }
8632
8633        if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8634
8635                /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
8636                cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8637                    SCU_RAM_COMMAND_CMD_DEMOD_START;
8638                cmd_scu.parameter_len = 0;
8639                cmd_scu.result_len = 1;
8640                cmd_scu.parameter = NULL;
8641                cmd_scu.result = &cmd_result;
8642                rc = scu_command(dev_addr, &cmd_scu);
8643                if (rc != 0) {
8644                        pr_err("error %d\n", rc);
8645                        goto rw_error;
8646                }
8647        }
8648
8649        rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
8650        if (rc != 0) {
8651                pr_err("error %d\n", rc);
8652                goto rw_error;
8653        }
8654        rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
8655        if (rc != 0) {
8656                pr_err("error %d\n", rc);
8657                goto rw_error;
8658        }
8659        rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
8660        if (rc != 0) {
8661                pr_err("error %d\n", rc);
8662                goto rw_error;
8663        }
8664
8665        return 0;
8666rw_error:
8667        return rc;
8668}
8669
8670/*============================================================================*/
8671static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
8672
8673static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
8674{
8675        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8676        struct drxj_data *ext_attr = demod->my_ext_attr;
8677        int rc;
8678        u32 iqm_fs_rate_ofs = 0;
8679        u32 iqm_fs_rate_lo = 0;
8680        u16 qam_ctl_ena = 0;
8681        u16 data = 0;
8682        u16 equ_mode = 0;
8683        u16 fsm_state = 0;
8684        int i = 0;
8685        int ofsofs = 0;
8686
8687        /* Silence the controlling of lc, equ, and the acquisition state machine */
8688        rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
8689        if (rc != 0) {
8690                pr_err("error %d\n", rc);
8691                goto rw_error;
8692        }
8693        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), 0);
8694        if (rc != 0) {
8695                pr_err("error %d\n", rc);
8696                goto rw_error;
8697        }
8698
8699        /* freeze the frequency control loop */
8700        rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);
8701        if (rc != 0) {
8702                pr_err("error %d\n", rc);
8703                goto rw_error;
8704        }
8705        rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);
8706        if (rc != 0) {
8707                pr_err("error %d\n", rc);
8708                goto rw_error;
8709        }
8710
8711        rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
8712        if (rc != 0) {
8713                pr_err("error %d\n", rc);
8714                goto rw_error;
8715        }
8716        rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
8717        if (rc != 0) {
8718                pr_err("error %d\n", rc);
8719                goto rw_error;
8720        }
8721        ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
8722        iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
8723        iqm_fs_rate_ofs -= 2 * ofsofs;
8724
8725        /* freeze dq/fq updating */
8726        rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
8727        if (rc != 0) {
8728                pr_err("error %d\n", rc);
8729                goto rw_error;
8730        }
8731        data = (data & 0xfff9);
8732        rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8733        if (rc != 0) {
8734                pr_err("error %d\n", rc);
8735                goto rw_error;
8736        }
8737        rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8738        if (rc != 0) {
8739                pr_err("error %d\n", rc);
8740                goto rw_error;
8741        }
8742
8743        /* lc_cp / _ci / _ca */
8744        rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);
8745        if (rc != 0) {
8746                pr_err("error %d\n", rc);
8747                goto rw_error;
8748        }
8749        rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);
8750        if (rc != 0) {
8751                pr_err("error %d\n", rc);
8752                goto rw_error;
8753        }
8754        rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
8755        if (rc != 0) {
8756                pr_err("error %d\n", rc);
8757                goto rw_error;
8758        }
8759
8760        /* flip the spec */
8761        rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
8762        if (rc != 0) {
8763                pr_err("error %d\n", rc);
8764                goto rw_error;
8765        }
8766        ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
8767        ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
8768
8769        /* freeze dq/fq updating */
8770        rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
8771        if (rc != 0) {
8772                pr_err("error %d\n", rc);
8773                goto rw_error;
8774        }
8775        equ_mode = data;
8776        data = (data & 0xfff9);
8777        rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8778        if (rc != 0) {
8779                pr_err("error %d\n", rc);
8780                goto rw_error;
8781        }
8782        rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8783        if (rc != 0) {
8784                pr_err("error %d\n", rc);
8785                goto rw_error;
8786        }
8787
8788        for (i = 0; i < 28; i++) {
8789                rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
8790                if (rc != 0) {
8791                        pr_err("error %d\n", rc);
8792                        goto rw_error;
8793                }
8794                rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
8795                if (rc != 0) {
8796                        pr_err("error %d\n", rc);
8797                        goto rw_error;
8798                }
8799        }
8800
8801        for (i = 0; i < 24; i++) {
8802                rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
8803                if (rc != 0) {
8804                        pr_err("error %d\n", rc);
8805                        goto rw_error;
8806                }
8807                rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
8808                if (rc != 0) {
8809                        pr_err("error %d\n", rc);
8810                        goto rw_error;
8811                }
8812        }
8813
8814        data = equ_mode;
8815        rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8816        if (rc != 0) {
8817                pr_err("error %d\n", rc);
8818                goto rw_error;
8819        }
8820        rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8821        if (rc != 0) {
8822                pr_err("error %d\n", rc);
8823                goto rw_error;
8824        }
8825
8826        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
8827        if (rc != 0) {
8828                pr_err("error %d\n", rc);
8829                goto rw_error;
8830        }
8831
8832        i = 0;
8833        while ((fsm_state != 4) && (i++ < 100)) {
8834                rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
8835                if (rc != 0) {
8836                        pr_err("error %d\n", rc);
8837                        goto rw_error;
8838                }
8839        }
8840        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
8841        if (rc != 0) {
8842                pr_err("error %d\n", rc);
8843                goto rw_error;
8844        }
8845
8846        return 0;
8847rw_error:
8848        return rc;
8849
8850}
8851
8852#define  NO_LOCK        0x0
8853#define  DEMOD_LOCKED   0x1
8854#define  SYNC_FLIPPED   0x2
8855#define  SPEC_MIRRORED  0x4
8856/*
8857* \fn int qam64auto ()
8858* \brief auto do sync pattern switching and mirroring.
8859* \param demod:   instance of demod.
8860* \param channel: pointer to channel data.
8861* \param tuner_freq_offset: tuner frequency offset.
8862* \param lock_status: pointer to lock status.
8863* \return int.
8864*/
8865static int
8866qam64auto(struct drx_demod_instance *demod,
8867          struct drx_channel *channel,
8868          s32 tuner_freq_offset, enum drx_lock_status *lock_status)
8869{
8870        struct drxj_data *ext_attr = demod->my_ext_attr;
8871        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8872        struct drx39xxj_state *state = dev_addr->user_data;
8873        struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
8874        int rc;
8875        u32 lck_state = NO_LOCK;
8876        u32 start_time = 0;
8877        u32 d_locked_time = 0;
8878        u32 timeout_ofs = 0;
8879        u16 data = 0;
8880
8881        /* external attributes for storing acquired channel constellation */
8882        *lock_status = DRX_NOT_LOCKED;
8883        start_time = jiffies_to_msecs(jiffies);
8884        lck_state = NO_LOCK;
8885        do {
8886                rc = ctrl_lock_status(demod, lock_status);
8887                if (rc != 0) {
8888                        pr_err("error %d\n", rc);
8889                        goto rw_error;
8890                }
8891
8892                switch (lck_state) {
8893                case NO_LOCK:
8894                        if (*lock_status == DRXJ_DEMOD_LOCK) {
8895                                rc = ctrl_get_qam_sig_quality(demod);
8896                                if (rc != 0) {
8897                                        pr_err("error %d\n", rc);
8898                                        goto rw_error;
8899                                }
8900                                if (p->cnr.stat[0].svalue > 20800) {
8901                                        lck_state = DEMOD_LOCKED;
8902                                        /* some delay to see if fec_lock possible TODO find the right value */
8903                                        timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, waiting longer */
8904                                        d_locked_time = jiffies_to_msecs(jiffies);
8905                                }
8906                        }
8907                        break;
8908                case DEMOD_LOCKED:
8909                        if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
8910                            ((jiffies_to_msecs(jiffies) - d_locked_time) >
8911                             DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8912                                rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8913                                if (rc != 0) {
8914                                        pr_err("error %d\n", rc);
8915                                        goto rw_error;
8916                                }
8917                                rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
8918                                if (rc != 0) {
8919                                        pr_err("error %d\n", rc);
8920                                        goto rw_error;
8921                                }
8922                                lck_state = SYNC_FLIPPED;
8923                                msleep(10);
8924                        }
8925                        break;
8926                case SYNC_FLIPPED:
8927                        if (*lock_status == DRXJ_DEMOD_LOCK) {
8928                                if (channel->mirror == DRX_MIRROR_AUTO) {
8929                                        /* flip sync pattern back */
8930                                        rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8931                                        if (rc != 0) {
8932                                                pr_err("error %d\n", rc);
8933                                                goto rw_error;
8934                                        }
8935                                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
8936                                        if (rc != 0) {
8937                                                pr_err("error %d\n", rc);
8938                                                goto rw_error;
8939                                        }
8940                                        /* flip spectrum */
8941                                        ext_attr->mirror = DRX_MIRROR_YES;
8942                                        rc = qam_flip_spec(demod, channel);
8943                                        if (rc != 0) {
8944                                                pr_err("error %d\n", rc);
8945                                                goto rw_error;
8946                                        }
8947                                        lck_state = SPEC_MIRRORED;
8948                                        /* reset timer TODO: still need 500ms? */
8949                                        start_time = d_locked_time =
8950                                            jiffies_to_msecs(jiffies);
8951                                        timeout_ofs = 0;
8952                                } else {        /* no need to wait lock */
8953
8954                                        start_time =
8955                                            jiffies_to_msecs(jiffies) -
8956                                            DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8957                                }
8958                        }
8959                        break;
8960                case SPEC_MIRRORED:
8961                        if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
8962                            ((jiffies_to_msecs(jiffies) - d_locked_time) >
8963                             DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8964                                rc = ctrl_get_qam_sig_quality(demod);
8965                                if (rc != 0) {
8966                                        pr_err("error %d\n", rc);
8967                                        goto rw_error;
8968                                }
8969                                if (p->cnr.stat[0].svalue > 20800) {
8970                                        rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8971                                        if (rc != 0) {
8972                                                pr_err("error %d\n", rc);
8973                                                goto rw_error;
8974                                        }
8975                                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
8976                                        if (rc != 0) {
8977                                                pr_err("error %d\n", rc);
8978                                                goto rw_error;
8979                                        }
8980                                        /* no need to wait lock */
8981                                        start_time =
8982                                            jiffies_to_msecs(jiffies) -
8983                                            DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8984                                }
8985                        }
8986                        break;
8987                default:
8988                        break;
8989                }
8990                msleep(10);
8991        } while
8992            ((*lock_status != DRX_LOCKED) &&
8993             (*lock_status != DRX_NEVER_LOCK) &&
8994             ((jiffies_to_msecs(jiffies) - start_time) <
8995              (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
8996            );
8997        /* Returning control to application ... */
8998
8999        return 0;
9000rw_error:
9001        return rc;
9002}
9003
9004/*
9005* \fn int qam256auto ()
9006* \brief auto do sync pattern switching and mirroring.
9007* \param demod:   instance of demod.
9008* \param channel: pointer to channel data.
9009* \param tuner_freq_offset: tuner frequency offset.
9010* \param lock_status: pointer to lock status.
9011* \return int.
9012*/
9013static int
9014qam256auto(struct drx_demod_instance *demod,
9015           struct drx_channel *channel,
9016           s32 tuner_freq_offset, enum drx_lock_status *lock_status)
9017{
9018        struct drxj_data *ext_attr = demod->my_ext_attr;
9019        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9020        struct drx39xxj_state *state = dev_addr->user_data;
9021        struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9022        int rc;
9023        u32 lck_state = NO_LOCK;
9024        u32 start_time = 0;
9025        u32 d_locked_time = 0;
9026        u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
9027
9028        /* external attributes for storing acquired channel constellation */
9029        *lock_status = DRX_NOT_LOCKED;
9030        start_time = jiffies_to_msecs(jiffies);
9031        lck_state = NO_LOCK;
9032        do {
9033                rc = ctrl_lock_status(demod, lock_status);
9034                if (rc != 0) {
9035                        pr_err("error %d\n", rc);
9036                        goto rw_error;
9037                }
9038                switch (lck_state) {
9039                case NO_LOCK:
9040                        if (*lock_status == DRXJ_DEMOD_LOCK) {
9041                                rc = ctrl_get_qam_sig_quality(demod);
9042                                if (rc != 0) {
9043                                        pr_err("error %d\n", rc);
9044                                        goto rw_error;
9045                                }
9046                                if (p->cnr.stat[0].svalue > 26800) {
9047                                        lck_state = DEMOD_LOCKED;
9048                                        timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, wait longer */
9049                                        d_locked_time = jiffies_to_msecs(jiffies);
9050                                }
9051                        }
9052                        break;
9053                case DEMOD_LOCKED:
9054                        if (*lock_status == DRXJ_DEMOD_LOCK) {
9055                                if ((channel->mirror == DRX_MIRROR_AUTO) &&
9056                                    ((jiffies_to_msecs(jiffies) - d_locked_time) >
9057                                     DRXJ_QAM_FEC_LOCK_WAITTIME)) {
9058                                        ext_attr->mirror = DRX_MIRROR_YES;
9059                                        rc = qam_flip_spec(demod, channel);
9060                                        if (rc != 0) {
9061                                                pr_err("error %d\n", rc);
9062                                                goto rw_error;
9063                                        }
9064                                        lck_state = SPEC_MIRRORED;
9065                                        /* reset timer TODO: still need 300ms? */
9066                                        start_time = jiffies_to_msecs(jiffies);
9067                                        timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
9068                                }
9069                        }
9070                        break;
9071                case SPEC_MIRRORED:
9072                        break;
9073                default:
9074                        break;
9075                }
9076                msleep(10);
9077        } while
9078            ((*lock_status < DRX_LOCKED) &&
9079             (*lock_status != DRX_NEVER_LOCK) &&
9080             ((jiffies_to_msecs(jiffies) - start_time) <
9081              (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
9082
9083        return 0;
9084rw_error:
9085        return rc;
9086}
9087
9088/*
9089* \fn int set_qam_channel ()
9090* \brief Set QAM channel according to the requested constellation.
9091* \param demod:   instance of demod.
9092* \param channel: pointer to channel data.
9093* \return int.
9094*/
9095static int
9096set_qam_channel(struct drx_demod_instance *demod,
9097               struct drx_channel *channel, s32 tuner_freq_offset)
9098{
9099        struct drxj_data *ext_attr = NULL;
9100        int rc;
9101        enum drx_lock_status lock_status = DRX_NOT_LOCKED;
9102        bool auto_flag = false;
9103
9104        /* external attributes for storing acquired channel constellation */
9105        ext_attr = (struct drxj_data *) demod->my_ext_attr;
9106
9107        /* set QAM channel constellation */
9108        switch (channel->constellation) {
9109        case DRX_CONSTELLATION_QAM16:
9110        case DRX_CONSTELLATION_QAM32:
9111        case DRX_CONSTELLATION_QAM128:
9112                return -EINVAL;
9113        case DRX_CONSTELLATION_QAM64:
9114        case DRX_CONSTELLATION_QAM256:
9115                if (ext_attr->standard != DRX_STANDARD_ITU_B)
9116                        return -EINVAL;
9117
9118                ext_attr->constellation = channel->constellation;
9119                if (channel->mirror == DRX_MIRROR_AUTO)
9120                        ext_attr->mirror = DRX_MIRROR_NO;
9121                else
9122                        ext_attr->mirror = channel->mirror;
9123
9124                rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
9125                if (rc != 0) {
9126                        pr_err("error %d\n", rc);
9127                        goto rw_error;
9128                }
9129
9130                if (channel->constellation == DRX_CONSTELLATION_QAM64)
9131                        rc = qam64auto(demod, channel, tuner_freq_offset,
9132                                       &lock_status);
9133                else
9134                        rc = qam256auto(demod, channel, tuner_freq_offset,
9135                                        &lock_status);
9136                if (rc != 0) {
9137                        pr_err("error %d\n", rc);
9138                        goto rw_error;
9139                }
9140                break;
9141        case DRX_CONSTELLATION_AUTO:    /* for channel scan */
9142                if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9143                        u16 qam_ctl_ena = 0;
9144
9145                        auto_flag = true;
9146
9147                        /* try to lock default QAM constellation: QAM256 */
9148                        channel->constellation = DRX_CONSTELLATION_QAM256;
9149                        ext_attr->constellation = DRX_CONSTELLATION_QAM256;
9150                        if (channel->mirror == DRX_MIRROR_AUTO)
9151                                ext_attr->mirror = DRX_MIRROR_NO;
9152                        else
9153                                ext_attr->mirror = channel->mirror;
9154                        rc = set_qam(demod, channel, tuner_freq_offset,
9155                                     QAM_SET_OP_ALL);
9156                        if (rc != 0) {
9157                                pr_err("error %d\n", rc);
9158                                goto rw_error;
9159                        }
9160                        rc = qam256auto(demod, channel, tuner_freq_offset,
9161                                        &lock_status);
9162                        if (rc != 0) {
9163                                pr_err("error %d\n", rc);
9164                                goto rw_error;
9165                        }
9166
9167                        if (lock_status >= DRX_LOCKED) {
9168                                channel->constellation = DRX_CONSTELLATION_AUTO;
9169                                break;
9170                        }
9171
9172                        /* QAM254 not locked. Try QAM64 constellation */
9173                        channel->constellation = DRX_CONSTELLATION_QAM64;
9174                        ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9175                        if (channel->mirror == DRX_MIRROR_AUTO)
9176                                ext_attr->mirror = DRX_MIRROR_NO;
9177                        else
9178                                ext_attr->mirror = channel->mirror;
9179
9180                        rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
9181                                                     SCU_RAM_QAM_CTL_ENA__A,
9182                                                     &qam_ctl_ena, 0);
9183                        if (rc != 0) {
9184                                pr_err("error %d\n", rc);
9185                                goto rw_error;
9186                        }
9187                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9188                                                      SCU_RAM_QAM_CTL_ENA__A,
9189                                                      qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9190                        if (rc != 0) {
9191                                pr_err("error %d\n", rc);
9192                                goto rw_error;
9193                        }
9194                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9195                                                      SCU_RAM_QAM_FSM_STATE_TGT__A,
9196                                                      0x2, 0);
9197                        if (rc != 0) {
9198                                pr_err("error %d\n", rc);
9199                                goto rw_error;
9200                        }       /* force to rate hunting */
9201
9202                        rc = set_qam(demod, channel, tuner_freq_offset,
9203                                     QAM_SET_OP_CONSTELLATION);
9204                        if (rc != 0) {
9205                                pr_err("error %d\n", rc);
9206                                goto rw_error;
9207                        }
9208                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9209                                                      SCU_RAM_QAM_CTL_ENA__A,
9210                                                      qam_ctl_ena, 0);
9211                        if (rc != 0) {
9212                                pr_err("error %d\n", rc);
9213                                goto rw_error;
9214                        }
9215
9216                        rc = qam64auto(demod, channel, tuner_freq_offset,
9217                                       &lock_status);
9218                        if (rc != 0) {
9219                                pr_err("error %d\n", rc);
9220                                goto rw_error;
9221                        }
9222
9223                        channel->constellation = DRX_CONSTELLATION_AUTO;
9224                } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9225                        u16 qam_ctl_ena = 0;
9226
9227                        channel->constellation = DRX_CONSTELLATION_QAM64;
9228                        ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9229                        auto_flag = true;
9230
9231                        if (channel->mirror == DRX_MIRROR_AUTO)
9232                                ext_attr->mirror = DRX_MIRROR_NO;
9233                        else
9234                                ext_attr->mirror = channel->mirror;
9235                        rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
9236                                                     SCU_RAM_QAM_CTL_ENA__A,
9237                                                     &qam_ctl_ena, 0);
9238                        if (rc != 0) {
9239                                pr_err("error %d\n", rc);
9240                                goto rw_error;
9241                        }
9242                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9243                                                      SCU_RAM_QAM_CTL_ENA__A,
9244                                                      qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9245                        if (rc != 0) {
9246                                pr_err("error %d\n", rc);
9247                                goto rw_error;
9248                        }
9249                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9250                                                      SCU_RAM_QAM_FSM_STATE_TGT__A,
9251                                                      0x2, 0);
9252                        if (rc != 0) {
9253                                pr_err("error %d\n", rc);
9254                                goto rw_error;
9255                        }       /* force to rate hunting */
9256
9257                        rc = set_qam(demod, channel, tuner_freq_offset,
9258                                     QAM_SET_OP_CONSTELLATION);
9259                        if (rc != 0) {
9260                                pr_err("error %d\n", rc);
9261                                goto rw_error;
9262                        }
9263                        rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9264                                                      SCU_RAM_QAM_CTL_ENA__A,
9265                                                      qam_ctl_ena, 0);
9266                        if (rc != 0) {
9267                                pr_err("error %d\n", rc);
9268                                goto rw_error;
9269                        }
9270                        rc = qam64auto(demod, channel, tuner_freq_offset,
9271                                       &lock_status);
9272                        if (rc != 0) {
9273                                pr_err("error %d\n", rc);
9274                                goto rw_error;
9275                        }
9276                        channel->constellation = DRX_CONSTELLATION_AUTO;
9277                } else {
9278                        return -EINVAL;
9279                }
9280                break;
9281        default:
9282                return -EINVAL;
9283        }
9284
9285        return 0;
9286rw_error:
9287        /* restore starting value */
9288        if (auto_flag)
9289                channel->constellation = DRX_CONSTELLATION_AUTO;
9290        return rc;
9291}
9292
9293/*============================================================================*/
9294
9295/*
9296* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
9297* \brief Get RS error count in QAM mode (used for post RS BER calculation)
9298* \return Error code
9299*
9300* precondition: measurement period & measurement prescale must be set
9301*
9302*/
9303static int
9304get_qamrs_err_count(struct i2c_device_addr *dev_addr,
9305                    struct drxjrs_errors *rs_errors)
9306{
9307        int rc;
9308        u16 nr_bit_errors = 0,
9309            nr_symbol_errors = 0,
9310            nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
9311
9312        /* check arguments */
9313        if (dev_addr == NULL)
9314                return -EINVAL;
9315
9316        /* all reported errors are received in the  */
9317        /* most recently finished measurement period */
9318        /*   no of pre RS bit errors */
9319        rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
9320        if (rc != 0) {
9321                pr_err("error %d\n", rc);
9322                goto rw_error;
9323        }
9324        /*   no of symbol errors      */
9325        rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
9326        if (rc != 0) {
9327                pr_err("error %d\n", rc);
9328                goto rw_error;
9329        }
9330        /*   no of packet errors      */
9331        rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
9332        if (rc != 0) {
9333                pr_err("error %d\n", rc);
9334                goto rw_error;
9335        }
9336        /*   no of failures to decode */
9337        rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
9338        if (rc != 0) {
9339                pr_err("error %d\n", rc);
9340                goto rw_error;
9341        }
9342        /*   no of post RS bit erros  */
9343        rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
9344        if (rc != 0) {
9345                pr_err("error %d\n", rc);
9346                goto rw_error;
9347        }
9348        /* TODO: NOTE */
9349        /* These register values are fetched in non-atomic fashion           */
9350        /* It is possible that the read values contain unrelated information */
9351
9352        rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
9353        rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
9354        rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
9355        rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
9356        rs_errors->nr_snc_par_fail_count =
9357            nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
9358
9359        return 0;
9360rw_error:
9361        return rc;
9362}
9363
9364/*============================================================================*/
9365
9366/*
9367 * \fn int get_sig_strength()
9368 * \brief Retrieve signal strength for VSB and QAM.
9369 * \param demod Pointer to demod instance
9370 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
9371 * \return int.
9372 * \retval 0 sig_strength contains valid data.
9373 * \retval -EINVAL sig_strength is NULL.
9374 * \retval -EIO Erroneous data, sig_strength contains invalid data.
9375 */
9376#define DRXJ_AGC_TOP    0x2800
9377#define DRXJ_AGC_SNS    0x1600
9378#define DRXJ_RFAGC_MAX  0x3fff
9379#define DRXJ_RFAGC_MIN  0x800
9380
9381static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
9382{
9383        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9384        int rc;
9385        u16 rf_gain = 0;
9386        u16 if_gain = 0;
9387        u16 if_agc_sns = 0;
9388        u16 if_agc_top = 0;
9389        u16 rf_agc_max = 0;
9390        u16 rf_agc_min = 0;
9391
9392        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
9393        if (rc != 0) {
9394                pr_err("error %d\n", rc);
9395                goto rw_error;
9396        }
9397        if_gain &= IQM_AF_AGC_IF__M;
9398        rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
9399        if (rc != 0) {
9400                pr_err("error %d\n", rc);
9401                goto rw_error;
9402        }
9403        rf_gain &= IQM_AF_AGC_RF__M;
9404
9405        if_agc_sns = DRXJ_AGC_SNS;
9406        if_agc_top = DRXJ_AGC_TOP;
9407        rf_agc_max = DRXJ_RFAGC_MAX;
9408        rf_agc_min = DRXJ_RFAGC_MIN;
9409
9410        if (if_gain > if_agc_top) {
9411                if (rf_gain > rf_agc_max)
9412                        *sig_strength = 100;
9413                else if (rf_gain > rf_agc_min) {
9414                        if (rf_agc_max == rf_agc_min) {
9415                                pr_err("error: rf_agc_max == rf_agc_min\n");
9416                                return -EIO;
9417                        }
9418                        *sig_strength =
9419                        75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
9420                                                                rf_agc_min);
9421                } else
9422                        *sig_strength = 75;
9423        } else if (if_gain > if_agc_sns) {
9424                if (if_agc_top == if_agc_sns) {
9425                        pr_err("error: if_agc_top == if_agc_sns\n");
9426                        return -EIO;
9427                }
9428                *sig_strength =
9429                20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
9430        } else {
9431                if (!if_agc_sns) {
9432                        pr_err("error: if_agc_sns is zero!\n");
9433                        return -EIO;
9434                }
9435                *sig_strength = (20 * if_gain / if_agc_sns);
9436        }
9437
9438        if (*sig_strength <= 7)
9439                *sig_strength = 0;
9440
9441        return 0;
9442rw_error:
9443        return rc;
9444}
9445
9446/*
9447* \fn int ctrl_get_qam_sig_quality()
9448* \brief Retrieve QAM signal quality from device.
9449* \param devmod Pointer to demodulator instance.
9450* \param sig_quality Pointer to signal quality data.
9451* \return int.
9452* \retval 0 sig_quality contains valid data.
9453* \retval -EINVAL sig_quality is NULL.
9454* \retval -EIO Erroneous data, sig_quality contains invalid data.
9455
9456*  Pre-condition: Device must be started and in lock.
9457*/
9458static int
9459ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9460{
9461        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9462        struct drxj_data *ext_attr = demod->my_ext_attr;
9463        struct drx39xxj_state *state = dev_addr->user_data;
9464        struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9465        struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
9466        enum drx_modulation constellation = ext_attr->constellation;
9467        int rc;
9468
9469        u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
9470        u32 post_bit_err_rs = 0;        /* post RedSolomon Bit Error Rate */
9471        u32 pkt_errs = 0;       /* no of packet errors in RS */
9472        u16 qam_sl_err_power = 0;       /* accumulated error between raw and sliced symbols */
9473        u16 qsym_err_vd = 0;    /* quadrature symbol errors in QAM_VD */
9474        u16 fec_oc_period = 0;  /* SNC sync failure measurement period */
9475        u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
9476        u16 fec_rs_period = 0;  /* Value for corresponding I2C register */
9477        /* calculation constants */
9478        u32 rs_bit_cnt = 0;     /* RedSolomon Bit Count */
9479        u32 qam_sl_sig_power = 0;       /* used for MER, depends of QAM constellation */
9480        /* intermediate results */
9481        u32 e = 0;              /* exponent value used for QAM BER/SER */
9482        u32 m = 0;              /* mantisa value used for QAM BER/SER */
9483        u32 ber_cnt = 0;        /* BER count */
9484        /* signal quality info */
9485        u32 qam_sl_mer = 0;     /* QAM MER */
9486        u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
9487        u32 qam_post_rs_ber = 0;        /* Post RedSolomon BER */
9488        u32 qam_vd_ser = 0;     /* ViterbiDecoder SER */
9489        u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
9490        u16 qam_vd_period = 0;  /* Viterbi Measurement period */
9491        u32 vd_bit_cnt = 0;     /* ViterbiDecoder Bit Count */
9492
9493        p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9494
9495        /* read the physical registers */
9496        /*   Get the RS error data */
9497        rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
9498        if (rc != 0) {
9499                pr_err("error %d\n", rc);
9500                goto rw_error;
9501        }
9502        /* get the register value needed for MER */
9503        rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
9504        if (rc != 0) {
9505                pr_err("error %d\n", rc);
9506                goto rw_error;
9507        }
9508        /* get the register value needed for post RS BER */
9509        rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
9510        if (rc != 0) {
9511                pr_err("error %d\n", rc);
9512                goto rw_error;
9513        }
9514
9515        /* get constants needed for signal quality calculation */
9516        fec_rs_period = ext_attr->fec_rs_period;
9517        fec_rs_prescale = ext_attr->fec_rs_prescale;
9518        rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
9519        qam_vd_period = ext_attr->qam_vd_period;
9520        qam_vd_prescale = ext_attr->qam_vd_prescale;
9521        vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
9522
9523        /* DRXJ_QAM_SL_SIG_POWER_QAMxxx  * 4     */
9524        switch (constellation) {
9525        case DRX_CONSTELLATION_QAM16:
9526                qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
9527                break;
9528        case DRX_CONSTELLATION_QAM32:
9529                qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
9530                break;
9531        case DRX_CONSTELLATION_QAM64:
9532                qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
9533                break;
9534        case DRX_CONSTELLATION_QAM128:
9535                qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
9536                break;
9537        case DRX_CONSTELLATION_QAM256:
9538                qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
9539                break;
9540        default:
9541                return -EIO;
9542        }
9543
9544        /* ------------------------------ */
9545        /* MER Calculation                */
9546        /* ------------------------------ */
9547        /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
9548
9549        /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
9550        if (qam_sl_err_power == 0)
9551                qam_sl_mer = 0;
9552        else
9553                qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
9554
9555        /* ----------------------------------------- */
9556        /* Pre Viterbi Symbol Error Rate Calculation */
9557        /* ----------------------------------------- */
9558        /* pre viterbi SER is good if it is below 0.025 */
9559
9560        /* get the register value */
9561        /*   no of quadrature symbol errors */
9562        rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
9563        if (rc != 0) {
9564                pr_err("error %d\n", rc);
9565                goto rw_error;
9566        }
9567        /* Extract the Exponent and the Mantisa  */
9568        /* of number of quadrature symbol errors */
9569        e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
9570            QAM_VD_NR_QSYM_ERRORS_EXP__B;
9571        m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
9572            QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
9573
9574        if ((m << e) >> 3 > 549752)
9575                qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9576        else
9577                qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
9578
9579        /* --------------------------------------- */
9580        /* pre and post RedSolomon BER Calculation */
9581        /* --------------------------------------- */
9582        /* pre RS BER is good if it is below 3.5e-4 */
9583
9584        /* get the register values */
9585        pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
9586        pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
9587
9588        /* Extract the Exponent and the Mantisa of the */
9589        /* pre Reed-Solomon bit error count            */
9590        e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
9591            FEC_RS_NR_BIT_ERRORS_EXP__B;
9592        m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
9593            FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
9594
9595        ber_cnt = m << e;
9596
9597        /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
9598        if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
9599                qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
9600        else
9601                qam_pre_rs_ber = ber_cnt;
9602
9603        /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) /  */
9604        /*               (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A)  */
9605        /*
9606           => c = (1000000*100*11.17)/1504 =
9607           post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
9608           (100 * FEC_OC_SNC_FAIL_PERIOD__A)
9609           *100 and /100 is for more precision.
9610           => (20 bits * 12 bits) /(16 bits * 7 bits)  => safe in 32 bits computation
9611
9612           Precision errors still possible.
9613         */
9614        if (!fec_oc_period) {
9615                qam_post_rs_ber = 0xFFFFFFFF;
9616        } else {
9617                e = post_bit_err_rs * 742686;
9618                m = fec_oc_period * 100;
9619                qam_post_rs_ber = e / m;
9620        }
9621
9622        /* fill signal quality data structure */
9623        p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9624        p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9625        p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9626        p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9627        p->block_error.stat[0].scale = FE_SCALE_COUNTER;
9628        p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9629
9630        p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
9631        if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9632                p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
9633                p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9634        } else {
9635                p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
9636                p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9637        }
9638
9639        p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
9640        p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9641
9642        p->block_error.stat[0].uvalue += pkt_errs;
9643
9644#ifdef DRXJ_SIGNAL_ACCUM_ERR
9645        rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
9646        if (rc != 0) {
9647                pr_err("error %d\n", rc);
9648                goto rw_error;
9649        }
9650#endif
9651
9652        return 0;
9653rw_error:
9654        p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9655        p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9656        p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9657        p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9658        p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9659        p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9660
9661        return rc;
9662}
9663
9664#endif /* #ifndef DRXJ_VSB_ONLY */
9665
9666/*============================================================================*/
9667/*==                     END QAM DATAPATH FUNCTIONS                         ==*/
9668/*============================================================================*/
9669
9670/*============================================================================*/
9671/*============================================================================*/
9672/*==                       ATV DATAPATH FUNCTIONS                           ==*/
9673/*============================================================================*/
9674/*============================================================================*/
9675
9676/*
9677   Implementation notes.
9678
9679   NTSC/FM AGCs
9680
9681      Four AGCs are used for NTSC:
9682      (1) RF (used to attenuate the input signal in case of to much power)
9683      (2) IF (used to attenuate the input signal in case of to much power)
9684      (3) Video AGC (used to amplify the output signal in case input to low)
9685      (4) SIF AGC (used to amplify the output signal in case input to low)
9686
9687      Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
9688      that the coupling between Video AGC and the RF and IF AGCs also works in
9689      favor of the SIF AGC.
9690
9691      Three AGCs are used for FM:
9692      (1) RF (used to attenuate the input signal in case of to much power)
9693      (2) IF (used to attenuate the input signal in case of to much power)
9694      (3) SIF AGC (used to amplify the output signal in case input to low)
9695
9696      The SIF AGC is now coupled to the RF/IF AGCs.
9697      The SIF AGC is needed for both SIF output and the internal SIF signal to
9698      the AUD block.
9699
9700      RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
9701      the ATV block. The AGC control algorithms are all implemented in
9702      microcode.
9703
9704   ATV SETTINGS
9705
9706      (Shadow settings will not be used for now, they will be implemented
9707       later on because of the schedule)
9708
9709      Several HW/SCU "settings" can be used for ATV. The standard selection
9710      will reset most of these settings. To avoid that the end user application
9711      has to perform these settings each time the ATV or FM standards is
9712      selected the driver will shadow these settings. This enables the end user
9713      to perform the settings only once after a drx_open(). The driver must
9714      write the shadow settings to HW/SCU in case:
9715         ( setstandard FM/ATV) ||
9716         ( settings have changed && FM/ATV standard is active)
9717      The shadow settings will be stored in the device specific data container.
9718      A set of flags will be defined to flag changes in shadow settings.
9719      A routine will be implemented to write all changed shadow settings to
9720      HW/SCU.
9721
9722      The "settings" will consist of: AGC settings, filter settings etc.
9723
9724      Disadvantage of use of shadow settings:
9725      Direct changes in HW/SCU registers will not be reflected in the
9726      shadow settings and these changes will be overwritten during a next
9727      update. This can happen during evaluation. This will not be a problem
9728      for normal customer usage.
9729*/
9730/* -------------------------------------------------------------------------- */
9731
9732/*
9733* \fn int power_down_atv ()
9734* \brief Power down ATV.
9735* \param demod instance of demodulator
9736* \param standard either NTSC or FM (sub strandard for ATV )
9737* \return int.
9738*
9739*  Stops and thus resets ATV and IQM block
9740*  SIF and CVBS ADC are powered down
9741*  Calls audio power down
9742*/
9743static int
9744power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
9745{
9746        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9747        struct drxjscu_cmd cmd_scu = { /* command      */ 0,
9748                /* parameter_len */ 0,
9749                /* result_len    */ 0,
9750                /* *parameter   */ NULL,
9751                /* *result      */ NULL
9752        };
9753        int rc;
9754        u16 cmd_result = 0;
9755
9756        /* ATV NTSC */
9757
9758        /* Stop ATV SCU (will reset ATV and IQM hardware */
9759        cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
9760            SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9761        cmd_scu.parameter_len = 0;
9762        cmd_scu.result_len = 1;
9763        cmd_scu.parameter = NULL;
9764        cmd_scu.result = &cmd_result;
9765        rc = scu_command(dev_addr, &cmd_scu);
9766        if (rc != 0) {
9767                pr_err("error %d\n", rc);
9768                goto rw_error;
9769        }
9770        /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
9771        rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
9772        if (rc != 0) {
9773                pr_err("error %d\n", rc);
9774                goto rw_error;
9775        }
9776
9777        rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
9778        if (rc != 0) {
9779                pr_err("error %d\n", rc);
9780                goto rw_error;
9781        }
9782        if (primary) {
9783                rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9784                if (rc != 0) {
9785                        pr_err("error %d\n", rc);
9786                        goto rw_error;
9787                }
9788                rc = set_iqm_af(demod, false);
9789                if (rc != 0) {
9790                        pr_err("error %d\n", rc);
9791                        goto rw_error;
9792                }
9793        } else {
9794                rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9795                if (rc != 0) {
9796                        pr_err("error %d\n", rc);
9797                        goto rw_error;
9798                }
9799                rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9800                if (rc != 0) {
9801                        pr_err("error %d\n", rc);
9802                        goto rw_error;
9803                }
9804                rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9805                if (rc != 0) {
9806                        pr_err("error %d\n", rc);
9807                        goto rw_error;
9808                }
9809                rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9810                if (rc != 0) {
9811                        pr_err("error %d\n", rc);
9812                        goto rw_error;
9813                }
9814                rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9815                if (rc != 0) {
9816                        pr_err("error %d\n", rc);
9817                        goto rw_error;
9818                }
9819        }
9820        rc = power_down_aud(demod);
9821        if (rc != 0) {
9822                pr_err("error %d\n", rc);
9823                goto rw_error;
9824        }
9825
9826        return 0;
9827rw_error:
9828        return rc;
9829}
9830
9831/*============================================================================*/
9832
9833/*
9834* \brief Power up AUD.
9835* \param demod instance of demodulator
9836* \return int.
9837*
9838*/
9839static int power_down_aud(struct drx_demod_instance *demod)
9840{
9841        struct i2c_device_addr *dev_addr = NULL;
9842        struct drxj_data *ext_attr = NULL;
9843        int rc;
9844
9845        dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
9846        ext_attr = (struct drxj_data *) demod->my_ext_attr;
9847
9848        rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
9849        if (rc != 0) {
9850                pr_err("error %d\n", rc);
9851                goto rw_error;
9852        }
9853
9854        ext_attr->aud_data.audio_is_active = false;
9855
9856        return 0;
9857rw_error:
9858        return rc;
9859}
9860
9861/*
9862* \fn int set_orx_nsu_aox()
9863* \brief Configure OrxNsuAox for OOB
9864* \param demod instance of demodulator.
9865* \param active
9866* \return int.
9867*/
9868static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
9869{
9870        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9871        int rc;
9872        u16 data = 0;
9873
9874        /* Configure NSU_AOX */
9875        rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
9876        if (rc != 0) {
9877                pr_err("error %d\n", rc);
9878                goto rw_error;
9879        }
9880        if (!active)
9881                data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
9882        else
9883                data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
9884        rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
9885        if (rc != 0) {
9886                pr_err("error %d\n", rc);
9887                goto rw_error;
9888        }
9889
9890        return 0;
9891rw_error:
9892        return rc;
9893}
9894
9895/*
9896* \fn int ctrl_set_oob()
9897* \brief Set OOB channel to be used.
9898* \param demod instance of demodulator
9899* \param oob_param OOB parameters for channel setting.
9900* \frequency should be in KHz
9901* \return int.
9902*
9903* Accepts  only. Returns error otherwise.
9904* Demapper value is written after scu_command START
9905* because START command causes COMM_EXEC transition
9906* from 0 to 1 which causes all registers to be
9907* overwritten with initial value
9908*
9909*/
9910
9911/* Nyquist filter impulse response */
9912#define IMPULSE_COSINE_ALPHA_0_3    {-3, -4, -1, 6, 10, 7, -5, -20, -25, -10, 29, 79, 123, 140} /*sqrt raised-cosine filter with alpha=0.3 */
9913#define IMPULSE_COSINE_ALPHA_0_5    { 2, 0, -2, -2, 2, 5, 2, -10, -20, -14, 20, 74, 125, 145}   /*sqrt raised-cosine filter with alpha=0.5 */
9914#define IMPULSE_COSINE_ALPHA_RO_0_5 { 0, 0, 1, 2, 3, 0, -7, -15, -16,  0, 34, 77, 114, 128}     /*full raised-cosine filter with alpha=0.5 (receiver only) */
9915
9916/* Coefficients for the nyquist filter (total: 27 taps) */
9917#define NYQFILTERLEN 27
9918
9919static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
9920{
9921        int rc;
9922        s32 freq = 0;   /* KHz */
9923        struct i2c_device_addr *dev_addr = NULL;
9924        struct drxj_data *ext_attr = NULL;
9925        u16 i = 0;
9926        bool mirror_freq_spect_oob = false;
9927        u16 trk_filter_value = 0;
9928        struct drxjscu_cmd scu_cmd;
9929        u16 set_param_parameters[3];
9930        u16 cmd_result[2] = { 0, 0 };
9931        s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
9932                IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 0 */
9933                IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 1 */
9934                IMPULSE_COSINE_ALPHA_0_5,       /* Target Mode 2 */
9935                IMPULSE_COSINE_ALPHA_RO_0_5     /* Target Mode 3 */
9936        };
9937        u8 mode_val[4] = { 2, 2, 0, 1 };
9938        u8 pfi_coeffs[4][6] = {
9939                {DRXJ_16TO8(-92), DRXJ_16TO8(-108), DRXJ_16TO8(100)},   /* TARGET_MODE = 0:     PFI_A = -23/32; PFI_B = -54/32;  PFI_C = 25/32; fg = 0.5 MHz (Att=26dB) */
9940                {DRXJ_16TO8(-64), DRXJ_16TO8(-80), DRXJ_16TO8(80)},     /* TARGET_MODE = 1:     PFI_A = -16/32; PFI_B = -40/32;  PFI_C = 20/32; fg = 1.0 MHz (Att=28dB) */
9941                {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)},     /* TARGET_MODE = 2, 3:  PFI_A = -20/32; PFI_B = -49/32;  PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
9942                {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}      /* TARGET_MODE = 2, 3:  PFI_A = -20/32; PFI_B = -49/32;  PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
9943        };
9944        u16 mode_index;
9945
9946        dev_addr = demod->my_i2c_dev_addr;
9947        ext_attr = (struct drxj_data *) demod->my_ext_attr;
9948        mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
9949
9950        /* Check parameters */
9951        if (oob_param == NULL) {
9952                /* power off oob module  */
9953                scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
9954                    | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9955                scu_cmd.parameter_len = 0;
9956                scu_cmd.result_len = 1;
9957                scu_cmd.result = cmd_result;
9958                rc = scu_command(dev_addr, &scu_cmd);
9959                if (rc != 0) {
9960                        pr_err("error %d\n", rc);
9961                        goto rw_error;
9962                }
9963                rc = set_orx_nsu_aox(demod, false);
9964                if (rc != 0) {
9965                        pr_err("error %d\n", rc);
9966                        goto rw_error;
9967                }
9968                rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
9969                if (rc != 0) {
9970                        pr_err("error %d\n", rc);
9971                        goto rw_error;
9972                }
9973
9974                ext_attr->oob_power_on = false;
9975                return 0;
9976        }
9977
9978        freq = oob_param->frequency;
9979        if ((freq < 70000) || (freq > 130000))
9980                return -EIO;
9981        freq = (freq - 50000) / 50;
9982
9983        {
9984                u16 index = 0;
9985                u16 remainder = 0;
9986                u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
9987
9988                index = (u16) ((freq - 400) / 200);
9989                remainder = (u16) ((freq - 400) % 200);
9990                trk_filter_value =
9991                    trk_filtercfg[index] - (trk_filtercfg[index] -
9992                                           trk_filtercfg[index +
9993                                                        1]) / 10 * remainder /
9994                    20;
9995        }
9996
9997   /********/
9998        /* Stop  */
9999   /********/
10000        rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
10001        if (rc != 0) {
10002                pr_err("error %d\n", rc);
10003                goto rw_error;
10004        }
10005        scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10006            | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
10007        scu_cmd.parameter_len = 0;
10008        scu_cmd.result_len = 1;
10009        scu_cmd.result = cmd_result;
10010        rc = scu_command(dev_addr, &scu_cmd);
10011        if (rc != 0) {
10012                pr_err("error %d\n", rc);
10013                goto rw_error;
10014        }
10015   /********/
10016        /* Reset */
10017   /********/
10018        scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10019            | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
10020        scu_cmd.parameter_len = 0;
10021        scu_cmd.result_len = 1;
10022        scu_cmd.result = cmd_result;
10023        rc = scu_command(dev_addr, &scu_cmd);
10024        if (rc != 0) {
10025                pr_err("error %d\n", rc);
10026                goto rw_error;
10027        }
10028   /**********/
10029        /* SET_ENV */
10030   /**********/
10031        /* set frequency, spectrum inversion and data rate */
10032        scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10033            | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
10034        scu_cmd.parameter_len = 3;
10035        /* 1-data rate;2-frequency */
10036        switch (oob_param->standard) {
10037        case DRX_OOB_MODE_A:
10038                if (
10039                           /* signal is transmitted inverted */
10040                           ((oob_param->spectrum_inverted == true) &&
10041                            /* and tuner is not mirroring the signal */
10042                            (!mirror_freq_spect_oob)) |
10043                           /* or */
10044                           /* signal is transmitted noninverted */
10045                           ((oob_param->spectrum_inverted == false) &&
10046                            /* and tuner is mirroring the signal */
10047                            (mirror_freq_spect_oob))
10048                    )
10049                        set_param_parameters[0] =
10050                            SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
10051                else
10052                        set_param_parameters[0] =
10053                            SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
10054                break;
10055        case DRX_OOB_MODE_B_GRADE_A:
10056                if (
10057                           /* signal is transmitted inverted */
10058                           ((oob_param->spectrum_inverted == true) &&
10059                            /* and tuner is not mirroring the signal */
10060                            (!mirror_freq_spect_oob)) |
10061                           /* or */
10062                           /* signal is transmitted noninverted */
10063                           ((oob_param->spectrum_inverted == false) &&
10064                            /* and tuner is mirroring the signal */
10065                            (mirror_freq_spect_oob))
10066                    )
10067                        set_param_parameters[0] =
10068                            SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
10069                else
10070                        set_param_parameters[0] =
10071                            SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
10072                break;
10073        case DRX_OOB_MODE_B_GRADE_B:
10074        default:
10075                if (
10076                           /* signal is transmitted inverted */
10077                           ((oob_param->spectrum_inverted == true) &&
10078                            /* and tuner is not mirroring the signal */
10079                            (!mirror_freq_spect_oob)) |
10080                           /* or */
10081                           /* signal is transmitted noninverted */
10082                           ((oob_param->spectrum_inverted == false) &&
10083                            /* and tuner is mirroring the signal */
10084                            (mirror_freq_spect_oob))
10085                    )
10086                        set_param_parameters[0] =
10087                            SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
10088                else
10089                        set_param_parameters[0] =
10090                            SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
10091                break;
10092        }
10093        set_param_parameters[1] = (u16) (freq & 0xFFFF);
10094        set_param_parameters[2] = trk_filter_value;
10095        scu_cmd.parameter = set_param_parameters;
10096        scu_cmd.result_len = 1;
10097        scu_cmd.result = cmd_result;
10098        mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
10099        rc = scu_command(dev_addr, &scu_cmd);
10100        if (rc != 0) {
10101                pr_err("error %d\n", rc);
10102                goto rw_error;
10103        }
10104
10105        rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
10106        if (rc != 0) {
10107                pr_err("error %d\n", rc);
10108                goto rw_error;
10109        }       /*  Write magic word to enable pdr reg write  */
10110        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
10111        if (rc != 0) {
10112                pr_err("error %d\n", rc);
10113                goto rw_error;
10114        }
10115        rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
10116        if (rc != 0) {
10117                pr_err("error %d\n", rc);
10118                goto rw_error;
10119        }
10120        rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
10121        if (rc != 0) {
10122                pr_err("error %d\n", rc);
10123                goto rw_error;
10124        }       /*  Write magic word to disable pdr reg write */
10125
10126        rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
10127        if (rc != 0) {
10128                pr_err("error %d\n", rc);
10129                goto rw_error;
10130        }
10131        rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
10132        if (rc != 0) {
10133                pr_err("error %d\n", rc);
10134                goto rw_error;
10135        }
10136        rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
10137        if (rc != 0) {
10138                pr_err("error %d\n", rc);
10139                goto rw_error;
10140        }
10141
10142        /* ddc */
10143        rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
10144        if (rc != 0) {
10145                pr_err("error %d\n", rc);
10146                goto rw_error;
10147        }
10148
10149        /* nsu */
10150        rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
10151        if (rc != 0) {
10152                pr_err("error %d\n", rc);
10153                goto rw_error;
10154        }
10155
10156        /* initialization for target mode */
10157        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
10158        if (rc != 0) {
10159                pr_err("error %d\n", rc);
10160                goto rw_error;
10161        }
10162        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
10163        if (rc != 0) {
10164                pr_err("error %d\n", rc);
10165                goto rw_error;
10166        }
10167
10168        /* Reset bits for timing and freq. recovery */
10169        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
10170        if (rc != 0) {
10171                pr_err("error %d\n", rc);
10172                goto rw_error;
10173        }
10174        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
10175        if (rc != 0) {
10176                pr_err("error %d\n", rc);
10177                goto rw_error;
10178        }
10179        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
10180        if (rc != 0) {
10181                pr_err("error %d\n", rc);
10182                goto rw_error;
10183        }
10184        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
10185        if (rc != 0) {
10186                pr_err("error %d\n", rc);
10187                goto rw_error;
10188        }
10189
10190        /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
10191        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
10192        if (rc != 0) {
10193                pr_err("error %d\n", rc);
10194                goto rw_error;
10195        }
10196        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
10197        if (rc != 0) {
10198                pr_err("error %d\n", rc);
10199                goto rw_error;
10200        }
10201        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
10202        if (rc != 0) {
10203                pr_err("error %d\n", rc);
10204                goto rw_error;
10205        }
10206        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
10207        if (rc != 0) {
10208                pr_err("error %d\n", rc);
10209                goto rw_error;
10210        }
10211        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
10212        if (rc != 0) {
10213                pr_err("error %d\n", rc);
10214                goto rw_error;
10215        }
10216
10217        /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
10218        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
10219        if (rc != 0) {
10220                pr_err("error %d\n", rc);
10221                goto rw_error;
10222        }
10223        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
10224        if (rc != 0) {
10225                pr_err("error %d\n", rc);
10226                goto rw_error;
10227        }
10228        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
10229        if (rc != 0) {
10230                pr_err("error %d\n", rc);
10231                goto rw_error;
10232        }
10233        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
10234        if (rc != 0) {
10235                pr_err("error %d\n", rc);
10236                goto rw_error;
10237        }
10238        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
10239        if (rc != 0) {
10240                pr_err("error %d\n", rc);
10241                goto rw_error;
10242        }
10243
10244        /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
10245        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
10246        if (rc != 0) {
10247                pr_err("error %d\n", rc);
10248                goto rw_error;
10249        }
10250        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
10251        if (rc != 0) {
10252                pr_err("error %d\n", rc);
10253                goto rw_error;
10254        }
10255        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
10256        if (rc != 0) {
10257                pr_err("error %d\n", rc);
10258                goto rw_error;
10259        }
10260        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
10261        if (rc != 0) {
10262                pr_err("error %d\n", rc);
10263                goto rw_error;
10264        }
10265        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
10266        if (rc != 0) {
10267                pr_err("error %d\n", rc);
10268                goto rw_error;
10269        }
10270
10271        /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
10272        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
10273        if (rc != 0) {
10274                pr_err("error %d\n", rc);
10275                goto rw_error;
10276        }
10277        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
10278        if (rc != 0) {
10279                pr_err("error %d\n", rc);
10280                goto rw_error;
10281        }
10282        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
10283        if (rc != 0) {
10284                pr_err("error %d\n", rc);
10285                goto rw_error;
10286        }
10287        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
10288        if (rc != 0) {
10289                pr_err("error %d\n", rc);
10290                goto rw_error;
10291        }
10292        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
10293        if (rc != 0) {
10294                pr_err("error %d\n", rc);
10295                goto rw_error;
10296        }
10297
10298        /* TIM_LOCK = {300,      -2048, 8, -8, 0, 1<<4}; */
10299        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
10300        if (rc != 0) {
10301                pr_err("error %d\n", rc);
10302                goto rw_error;
10303        }
10304        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
10305        if (rc != 0) {
10306                pr_err("error %d\n", rc);
10307                goto rw_error;
10308        }
10309        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
10310        if (rc != 0) {
10311                pr_err("error %d\n", rc);
10312                goto rw_error;
10313        }
10314        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
10315        if (rc != 0) {
10316                pr_err("error %d\n", rc);
10317                goto rw_error;
10318        }
10319        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
10320        if (rc != 0) {
10321                pr_err("error %d\n", rc);
10322                goto rw_error;
10323        }
10324
10325        /* EQU_LOCK = {20,      -2048, 8, -8, 0, 1<<5}; */
10326        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
10327        if (rc != 0) {
10328                pr_err("error %d\n", rc);
10329                goto rw_error;
10330        }
10331        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
10332        if (rc != 0) {
10333                pr_err("error %d\n", rc);
10334                goto rw_error;
10335        }
10336        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
10337        if (rc != 0) {
10338                pr_err("error %d\n", rc);
10339                goto rw_error;
10340        }
10341        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
10342        if (rc != 0) {
10343                pr_err("error %d\n", rc);
10344                goto rw_error;
10345        }
10346        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
10347        if (rc != 0) {
10348                pr_err("error %d\n", rc);
10349                goto rw_error;
10350        }
10351
10352        /* PRE-Filter coefficients (PFI) */
10353        rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
10354        if (rc != 0) {
10355                pr_err("error %d\n", rc);
10356                goto rw_error;
10357        }
10358        rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
10359        if (rc != 0) {
10360                pr_err("error %d\n", rc);
10361                goto rw_error;
10362        }
10363
10364        /* NYQUIST-Filter coefficients (NYQ) */
10365        for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
10366                rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
10367                if (rc != 0) {
10368                        pr_err("error %d\n", rc);
10369                        goto rw_error;
10370                }
10371                rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
10372                if (rc != 0) {
10373                        pr_err("error %d\n", rc);
10374                        goto rw_error;
10375                }
10376        }
10377        rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
10378        if (rc != 0) {
10379                pr_err("error %d\n", rc);
10380                goto rw_error;
10381        }
10382        rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
10383        if (rc != 0) {
10384                pr_err("error %d\n", rc);
10385                goto rw_error;
10386        }
10387        /********/
10388        /* Start */
10389        /********/
10390        scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10391            | SCU_RAM_COMMAND_CMD_DEMOD_START;
10392        scu_cmd.parameter_len = 0;
10393        scu_cmd.result_len = 1;
10394        scu_cmd.result = cmd_result;
10395        rc = scu_command(dev_addr, &scu_cmd);
10396        if (rc != 0) {
10397                pr_err("error %d\n", rc);
10398                goto rw_error;
10399        }
10400
10401        rc = set_orx_nsu_aox(demod, true);
10402        if (rc != 0) {
10403                pr_err("error %d\n", rc);
10404                goto rw_error;
10405        }
10406        rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
10407        if (rc != 0) {
10408                pr_err("error %d\n", rc);
10409                goto rw_error;
10410        }
10411
10412        ext_attr->oob_power_on = true;
10413
10414        return 0;
10415rw_error:
10416        return rc;
10417}
10418
10419/*============================================================================*/
10420/*==                     END OOB DATAPATH FUNCTIONS                         ==*/
10421/*============================================================================*/
10422
10423/*=============================================================================
10424  ===== MC command related functions ==========================================
10425  ===========================================================================*/
10426
10427/*=============================================================================
10428  ===== ctrl_set_channel() ==========================================================
10429  ===========================================================================*/
10430/*
10431* \fn int ctrl_set_channel()
10432* \brief Select a new transmission channel.
10433* \param demod instance of demod.
10434* \param channel Pointer to channel data.
10435* \return int.
10436*
10437* In case the tuner module is not used and in case of NTSC/FM the pogrammer
10438* must tune the tuner to the centre frequency of the NTSC/FM channel.
10439*
10440*/
10441static int
10442ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
10443{
10444        int rc;
10445        s32 tuner_freq_offset = 0;
10446        struct drxj_data *ext_attr = NULL;
10447        struct i2c_device_addr *dev_addr = NULL;
10448        enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10449#ifndef DRXJ_VSB_ONLY
10450        u32 min_symbol_rate = 0;
10451        u32 max_symbol_rate = 0;
10452        int bandwidth_temp = 0;
10453        int bandwidth = 0;
10454#endif
10455   /*== check arguments ======================================================*/
10456        if ((demod == NULL) || (channel == NULL))
10457                return -EINVAL;
10458
10459        dev_addr = demod->my_i2c_dev_addr;
10460        ext_attr = (struct drxj_data *) demod->my_ext_attr;
10461        standard = ext_attr->standard;
10462
10463        /* check valid standards */
10464        switch (standard) {
10465        case DRX_STANDARD_8VSB:
10466#ifndef DRXJ_VSB_ONLY
10467        case DRX_STANDARD_ITU_A:
10468        case DRX_STANDARD_ITU_B:
10469        case DRX_STANDARD_ITU_C:
10470#endif /* DRXJ_VSB_ONLY */
10471                break;
10472        case DRX_STANDARD_UNKNOWN:
10473        default:
10474                return -EINVAL;
10475        }
10476
10477        /* check bandwidth QAM annex B, NTSC and 8VSB */
10478        if ((standard == DRX_STANDARD_ITU_B) ||
10479            (standard == DRX_STANDARD_8VSB) ||
10480            (standard == DRX_STANDARD_NTSC)) {
10481                switch (channel->bandwidth) {
10482                case DRX_BANDWIDTH_6MHZ:
10483                case DRX_BANDWIDTH_UNKNOWN:
10484                        channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10485                        break;
10486                case DRX_BANDWIDTH_8MHZ:
10487                case DRX_BANDWIDTH_7MHZ:
10488                default:
10489                        return -EINVAL;
10490                }
10491        }
10492
10493        /* For QAM annex A and annex C:
10494           -check symbolrate and constellation
10495           -derive bandwidth from symbolrate (input bandwidth is ignored)
10496         */
10497#ifndef DRXJ_VSB_ONLY
10498        if ((standard == DRX_STANDARD_ITU_A) ||
10499            (standard == DRX_STANDARD_ITU_C)) {
10500                struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
10501                int bw_rolloff_factor = 0;
10502
10503                bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
10504                min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
10505                max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
10506                /* config SMA_TX pin to SAW switch mode */
10507                rc = ctrl_set_uio_cfg(demod, &uio_cfg);
10508                if (rc != 0) {
10509                        pr_err("error %d\n", rc);
10510                        goto rw_error;
10511                }
10512
10513                if (channel->symbolrate < min_symbol_rate ||
10514                    channel->symbolrate > max_symbol_rate) {
10515                        return -EINVAL;
10516                }
10517
10518                switch (channel->constellation) {
10519                case DRX_CONSTELLATION_QAM16:
10520                case DRX_CONSTELLATION_QAM32:
10521                case DRX_CONSTELLATION_QAM64:
10522                case DRX_CONSTELLATION_QAM128:
10523                case DRX_CONSTELLATION_QAM256:
10524                        bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
10525                        bandwidth = bandwidth_temp / 100;
10526
10527                        if ((bandwidth_temp % 100) >= 50)
10528                                bandwidth++;
10529
10530                        if (bandwidth <= 6100000) {
10531                                channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10532                        } else if ((bandwidth > 6100000)
10533                                   && (bandwidth <= 7100000)) {
10534                                channel->bandwidth = DRX_BANDWIDTH_7MHZ;
10535                        } else if (bandwidth > 7100000) {
10536                                channel->bandwidth = DRX_BANDWIDTH_8MHZ;
10537                        }
10538                        break;
10539                default:
10540                        return -EINVAL;
10541                }
10542        }
10543
10544        /* For QAM annex B:
10545           -check constellation
10546         */
10547        if (standard == DRX_STANDARD_ITU_B) {
10548                switch (channel->constellation) {
10549                case DRX_CONSTELLATION_AUTO:
10550                case DRX_CONSTELLATION_QAM256:
10551                case DRX_CONSTELLATION_QAM64:
10552                        break;
10553                default:
10554                        return -EINVAL;
10555                }
10556
10557                switch (channel->interleavemode) {
10558                case DRX_INTERLEAVEMODE_I128_J1:
10559                case DRX_INTERLEAVEMODE_I128_J1_V2:
10560                case DRX_INTERLEAVEMODE_I128_J2:
10561                case DRX_INTERLEAVEMODE_I64_J2:
10562                case DRX_INTERLEAVEMODE_I128_J3:
10563                case DRX_INTERLEAVEMODE_I32_J4:
10564                case DRX_INTERLEAVEMODE_I128_J4:
10565                case DRX_INTERLEAVEMODE_I16_J8:
10566                case DRX_INTERLEAVEMODE_I128_J5:
10567                case DRX_INTERLEAVEMODE_I8_J16:
10568                case DRX_INTERLEAVEMODE_I128_J6:
10569                case DRX_INTERLEAVEMODE_I128_J7:
10570                case DRX_INTERLEAVEMODE_I128_J8:
10571                case DRX_INTERLEAVEMODE_I12_J17:
10572                case DRX_INTERLEAVEMODE_I5_J4:
10573                case DRX_INTERLEAVEMODE_B52_M240:
10574                case DRX_INTERLEAVEMODE_B52_M720:
10575                case DRX_INTERLEAVEMODE_UNKNOWN:
10576                case DRX_INTERLEAVEMODE_AUTO:
10577                        break;
10578                default:
10579                        return -EINVAL;
10580                }
10581        }
10582
10583        if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
10584                /* SAW SW, user UIO is used for switchable SAW */
10585                struct drxuio_data uio1 = { DRX_UIO1, false };
10586
10587                switch (channel->bandwidth) {
10588                case DRX_BANDWIDTH_8MHZ:
10589                        uio1.value = true;
10590                        break;
10591                case DRX_BANDWIDTH_7MHZ:
10592                        uio1.value = false;
10593                        break;
10594                case DRX_BANDWIDTH_6MHZ:
10595                        uio1.value = false;
10596                        break;
10597                case DRX_BANDWIDTH_UNKNOWN:
10598                default:
10599                        return -EINVAL;
10600                }
10601
10602                rc = ctrl_uio_write(demod, &uio1);
10603                if (rc != 0) {
10604                        pr_err("error %d\n", rc);
10605                        goto rw_error;
10606                }
10607        }
10608#endif /* DRXJ_VSB_ONLY */
10609        rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
10610        if (rc != 0) {
10611                pr_err("error %d\n", rc);
10612                goto rw_error;
10613        }
10614
10615        tuner_freq_offset = 0;
10616
10617   /*== Setup demod for specific standard ====================================*/
10618        switch (standard) {
10619        case DRX_STANDARD_8VSB:
10620                if (channel->mirror == DRX_MIRROR_AUTO)
10621                        ext_attr->mirror = DRX_MIRROR_NO;
10622                else
10623                        ext_attr->mirror = channel->mirror;
10624                rc = set_vsb(demod);
10625                if (rc != 0) {
10626                        pr_err("error %d\n", rc);
10627                        goto rw_error;
10628                }
10629                rc = set_frequency(demod, channel, tuner_freq_offset);
10630                if (rc != 0) {
10631                        pr_err("error %d\n", rc);
10632                        goto rw_error;
10633                }
10634                break;
10635#ifndef DRXJ_VSB_ONLY
10636        case DRX_STANDARD_ITU_A:
10637        case DRX_STANDARD_ITU_B:
10638        case DRX_STANDARD_ITU_C:
10639                rc = set_qam_channel(demod, channel, tuner_freq_offset);
10640                if (rc != 0) {
10641                        pr_err("error %d\n", rc);
10642                        goto rw_error;
10643                }
10644                break;
10645#endif
10646        case DRX_STANDARD_UNKNOWN:
10647        default:
10648                return -EIO;
10649        }
10650
10651        /* flag the packet error counter reset */
10652        ext_attr->reset_pkt_err_acc = true;
10653
10654        return 0;
10655rw_error:
10656        return rc;
10657}
10658
10659/*=============================================================================
10660  ===== SigQuality() ==========================================================
10661  ===========================================================================*/
10662
10663/*
10664* \fn int ctrl_sig_quality()
10665* \brief Retrieve signal quality form device.
10666* \param devmod Pointer to demodulator instance.
10667* \param sig_quality Pointer to signal quality data.
10668* \return int.
10669* \retval 0 sig_quality contains valid data.
10670* \retval -EINVAL sig_quality is NULL.
10671* \retval -EIO Erroneous data, sig_quality contains invalid data.
10672
10673*/
10674static int
10675ctrl_sig_quality(struct drx_demod_instance *demod,
10676                 enum drx_lock_status lock_status)
10677{
10678        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
10679        struct drxj_data *ext_attr = demod->my_ext_attr;
10680        struct drx39xxj_state *state = dev_addr->user_data;
10681        struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10682        enum drx_standard standard = ext_attr->standard;
10683        int rc;
10684        u32 ber, cnt, err, pkt;
10685        u16 mer, strength = 0;
10686
10687        rc = get_sig_strength(demod, &strength);
10688        if (rc < 0) {
10689                pr_err("error getting signal strength %d\n", rc);
10690                p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10691        } else {
10692                p->strength.stat[0].scale = FE_SCALE_RELATIVE;
10693                p->strength.stat[0].uvalue = 65535UL *  strength/ 100;
10694        }
10695
10696        switch (standard) {
10697        case DRX_STANDARD_8VSB:
10698#ifdef DRXJ_SIGNAL_ACCUM_ERR
10699                rc = get_acc_pkt_err(demod, &pkt);
10700                if (rc != 0) {
10701                        pr_err("error %d\n", rc);
10702                        goto rw_error;
10703                }
10704#endif
10705                if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
10706                        p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10707                        p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10708                        p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10709                        p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10710                        p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10711                        p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10712                        p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10713                } else {
10714                        rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
10715                        if (rc != 0) {
10716                                pr_err("error %d getting UCB\n", rc);
10717                                p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10718                        } else {
10719                                p->block_error.stat[0].scale = FE_SCALE_COUNTER;
10720                                p->block_error.stat[0].uvalue += err;
10721                                p->block_count.stat[0].scale = FE_SCALE_COUNTER;
10722                                p->block_count.stat[0].uvalue += pkt;
10723                        }
10724
10725                        /* PostViterbi is compute in steps of 10^(-6) */
10726                        rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
10727                        if (rc != 0) {
10728                                pr_err("error %d getting pre-ber\n", rc);
10729                                p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10730                        } else {
10731                                p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10732                                p->pre_bit_error.stat[0].uvalue += ber;
10733                                p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10734                                p->pre_bit_count.stat[0].uvalue += cnt;
10735                        }
10736
10737                        rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
10738                        if (rc != 0) {
10739                                pr_err("error %d getting post-ber\n", rc);
10740                                p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10741                        } else {
10742                                p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10743                                p->post_bit_error.stat[0].uvalue += ber;
10744                                p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10745                                p->post_bit_count.stat[0].uvalue += cnt;
10746                        }
10747                        rc = get_vsbmer(dev_addr, &mer);
10748                        if (rc != 0) {
10749                                pr_err("error %d getting MER\n", rc);
10750                                p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10751                        } else {
10752                                p->cnr.stat[0].svalue = mer * 100;
10753                                p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
10754                        }
10755                }
10756                break;
10757#ifndef DRXJ_VSB_ONLY
10758        case DRX_STANDARD_ITU_A:
10759        case DRX_STANDARD_ITU_B:
10760        case DRX_STANDARD_ITU_C:
10761                rc = ctrl_get_qam_sig_quality(demod);
10762                if (rc != 0) {
10763                        pr_err("error %d\n", rc);
10764                        goto rw_error;
10765                }
10766                break;
10767#endif
10768        default:
10769                return -EIO;
10770        }
10771
10772        return 0;
10773rw_error:
10774        return rc;
10775}
10776
10777/*============================================================================*/
10778
10779/*
10780* \fn int ctrl_lock_status()
10781* \brief Retrieve lock status .
10782* \param dev_addr Pointer to demodulator device address.
10783* \param lock_stat Pointer to lock status structure.
10784* \return int.
10785*
10786*/
10787static int
10788ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
10789{
10790        enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10791        struct drxj_data *ext_attr = NULL;
10792        struct i2c_device_addr *dev_addr = NULL;
10793        struct drxjscu_cmd cmd_scu = { /* command      */ 0,
10794                /* parameter_len */ 0,
10795                /* result_len    */ 0,
10796                /* *parameter   */ NULL,
10797                /* *result      */ NULL
10798        };
10799        int rc;
10800        u16 cmd_result[2] = { 0, 0 };
10801        u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
10802
10803        /* check arguments */
10804        if ((demod == NULL) || (lock_stat == NULL))
10805                return -EINVAL;
10806
10807        dev_addr = demod->my_i2c_dev_addr;
10808        ext_attr = (struct drxj_data *) demod->my_ext_attr;
10809        standard = ext_attr->standard;
10810
10811        *lock_stat = DRX_NOT_LOCKED;
10812
10813        /* define the SCU command code */
10814        switch (standard) {
10815        case DRX_STANDARD_8VSB:
10816                cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
10817                    SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10818                demod_lock |= 0x6;
10819                break;
10820#ifndef DRXJ_VSB_ONLY
10821        case DRX_STANDARD_ITU_A:
10822        case DRX_STANDARD_ITU_B:
10823        case DRX_STANDARD_ITU_C:
10824                cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10825                    SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10826                break;
10827#endif
10828        case DRX_STANDARD_UNKNOWN:
10829        default:
10830                return -EIO;
10831        }
10832
10833        /* define the SCU command parameters and execute the command */
10834        cmd_scu.parameter_len = 0;
10835        cmd_scu.result_len = 2;
10836        cmd_scu.parameter = NULL;
10837        cmd_scu.result = cmd_result;
10838        rc = scu_command(dev_addr, &cmd_scu);
10839        if (rc != 0) {
10840                pr_err("error %d\n", rc);
10841                goto rw_error;
10842        }
10843
10844        /* set the lock status */
10845        if (cmd_scu.result[1] < demod_lock) {
10846                /* 0x0000 NOT LOCKED */
10847                *lock_stat = DRX_NOT_LOCKED;
10848        } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
10849                *lock_stat = DRXJ_DEMOD_LOCK;
10850        } else if (cmd_scu.result[1] <
10851                   SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
10852                /* 0x8000 DEMOD + FEC LOCKED (system lock) */
10853                *lock_stat = DRX_LOCKED;
10854        } else {
10855                /* 0xC000 NEVER LOCKED */
10856                /* (system will never be able to lock to the signal) */
10857                *lock_stat = DRX_NEVER_LOCK;
10858        }
10859
10860        return 0;
10861rw_error:
10862        return rc;
10863}
10864
10865/*============================================================================*/
10866
10867/*
10868* \fn int ctrl_set_standard()
10869* \brief Set modulation standard to be used.
10870* \param standard Modulation standard.
10871* \return int.
10872*
10873* Setup stuff for the desired demodulation standard.
10874* Disable and power down the previous selected demodulation standard
10875*
10876*/
10877static int
10878ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
10879{
10880        struct drxj_data *ext_attr = NULL;
10881        int rc;
10882        enum drx_standard prev_standard;
10883
10884        /* check arguments */
10885        if ((standard == NULL) || (demod == NULL))
10886                return -EINVAL;
10887
10888        ext_attr = (struct drxj_data *) demod->my_ext_attr;
10889        prev_standard = ext_attr->standard;
10890
10891        /*
10892           Stop and power down previous standard
10893         */
10894        switch (prev_standard) {
10895#ifndef DRXJ_VSB_ONLY
10896        case DRX_STANDARD_ITU_A:
10897        case DRX_STANDARD_ITU_B:
10898        case DRX_STANDARD_ITU_C:
10899                rc = power_down_qam(demod, false);
10900                if (rc != 0) {
10901                        pr_err("error %d\n", rc);
10902                        goto rw_error;
10903                }
10904                break;
10905#endif
10906        case DRX_STANDARD_8VSB:
10907                rc = power_down_vsb(demod, false);
10908                if (rc != 0) {
10909                        pr_err("error %d\n", rc);
10910                        goto rw_error;
10911                }
10912                break;
10913        case DRX_STANDARD_UNKNOWN:
10914                /* Do nothing */
10915                break;
10916        case DRX_STANDARD_AUTO:
10917        default:
10918                return -EINVAL;
10919        }
10920
10921        /*
10922           Initialize channel independent registers
10923           Power up new standard
10924         */
10925        ext_attr->standard = *standard;
10926
10927        switch (*standard) {
10928#ifndef DRXJ_VSB_ONLY
10929        case DRX_STANDARD_ITU_A:
10930        case DRX_STANDARD_ITU_B:
10931        case DRX_STANDARD_ITU_C:
10932                do {
10933                        u16 dummy;
10934                        rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
10935                        if (rc != 0) {
10936                                pr_err("error %d\n", rc);
10937                                goto rw_error;
10938                        }
10939                } while (0);
10940                break;
10941#endif
10942        case DRX_STANDARD_8VSB:
10943                rc = set_vsb_leak_n_gain(demod);
10944                if (rc != 0) {
10945                        pr_err("error %d\n", rc);
10946                        goto rw_error;
10947                }
10948                break;
10949        default:
10950                ext_attr->standard = DRX_STANDARD_UNKNOWN;
10951                return -EINVAL;
10952        }
10953
10954        return 0;
10955rw_error:
10956        /* Don't know what the standard is now ... try again */
10957        ext_attr->standard = DRX_STANDARD_UNKNOWN;
10958        return rc;
10959}
10960
10961/*============================================================================*/
10962
10963static void drxj_reset_mode(struct drxj_data *ext_attr)
10964{
10965        /* Initialize default AFE configuration for QAM */
10966        if (ext_attr->has_lna) {
10967                /* IF AGC off, PGA active */
10968#ifndef DRXJ_VSB_ONLY
10969                ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10970                ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10971                ext_attr->qam_pga_cfg = 140 + (11 * 13);
10972#endif
10973                ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10974                ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10975                ext_attr->vsb_pga_cfg = 140 + (11 * 13);
10976        } else {
10977                /* IF AGC on, PGA not active */
10978#ifndef DRXJ_VSB_ONLY
10979                ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10980                ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10981                ext_attr->qam_if_agc_cfg.min_output_level = 0;
10982                ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
10983                ext_attr->qam_if_agc_cfg.speed = 3;
10984                ext_attr->qam_if_agc_cfg.top = 1297;
10985                ext_attr->qam_pga_cfg = 140;
10986#endif
10987                ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10988                ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10989                ext_attr->vsb_if_agc_cfg.min_output_level = 0;
10990                ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
10991                ext_attr->vsb_if_agc_cfg.speed = 3;
10992                ext_attr->vsb_if_agc_cfg.top = 1024;
10993                ext_attr->vsb_pga_cfg = 140;
10994        }
10995        /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
10996        /* mc has not used them */
10997#ifndef DRXJ_VSB_ONLY
10998        ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
10999        ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11000        ext_attr->qam_rf_agc_cfg.min_output_level = 0;
11001        ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
11002        ext_attr->qam_rf_agc_cfg.speed = 3;
11003        ext_attr->qam_rf_agc_cfg.top = 9500;
11004        ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
11005        ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
11006        ext_attr->qam_pre_saw_cfg.reference = 0x07;
11007        ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
11008#endif
11009        /* Initialize default AFE configuration for VSB */
11010        ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
11011        ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11012        ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
11013        ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
11014        ext_attr->vsb_rf_agc_cfg.speed = 3;
11015        ext_attr->vsb_rf_agc_cfg.top = 9500;
11016        ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
11017        ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
11018        ext_attr->vsb_pre_saw_cfg.reference = 0x07;
11019        ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
11020}
11021
11022/*
11023* \fn int ctrl_power_mode()
11024* \brief Set the power mode of the device to the specified power mode
11025* \param demod Pointer to demodulator instance.
11026* \param mode  Pointer to new power mode.
11027* \return int.
11028* \retval 0          Success
11029* \retval -EIO       I2C error or other failure
11030* \retval -EINVAL Invalid mode argument.
11031*
11032*
11033*/
11034static int
11035ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
11036{
11037        struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
11038        struct drxj_data *ext_attr = (struct drxj_data *) NULL;
11039        struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
11040        int rc;
11041        u16 sio_cc_pwd_mode = 0;
11042
11043        common_attr = (struct drx_common_attr *) demod->my_common_attr;
11044        ext_attr = (struct drxj_data *) demod->my_ext_attr;
11045        dev_addr = demod->my_i2c_dev_addr;
11046
11047        /* Check arguments */
11048        if (mode == NULL)
11049                return -EINVAL;
11050
11051        /* If already in requested power mode, do nothing */
11052        if (common_attr->current_power_mode == *mode)
11053                return 0;
11054
11055        switch (*mode) {
11056        case DRX_POWER_UP:
11057        case DRXJ_POWER_DOWN_MAIN_PATH:
11058                sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
11059                break;
11060        case DRXJ_POWER_DOWN_CORE:
11061                sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
11062                break;
11063        case DRXJ_POWER_DOWN_PLL:
11064                sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
11065                break;
11066        case DRX_POWER_DOWN:
11067                sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
11068                break;
11069        default:
11070                /* Unknow sleep mode */
11071                return -EINVAL;
11072        }
11073
11074        /* Check if device needs to be powered up */
11075        if ((common_attr->current_power_mode != DRX_POWER_UP)) {
11076                rc = power_up_device(demod);
11077                if (rc != 0) {
11078                        pr_err("error %d\n", rc);
11079                        goto rw_error;
11080                }
11081        }
11082
11083        if (*mode == DRX_POWER_UP) {
11084                /* Restore analog & pin configuration */
11085
11086                /* Initialize default AFE configuration for VSB */
11087                drxj_reset_mode(ext_attr);
11088        } else {
11089                /* Power down to requested mode */
11090                /* Backup some register settings */
11091                /* Set pins with possible pull-ups connected to them in input mode */
11092                /* Analog power down */
11093                /* ADC power down */
11094                /* Power down device */
11095                /* stop all comm_exec */
11096                /*
11097                   Stop and power down previous standard
11098                 */
11099
11100                switch (ext_attr->standard) {
11101                case DRX_STANDARD_ITU_A:
11102                case DRX_STANDARD_ITU_B:
11103                case DRX_STANDARD_ITU_C:
11104                        rc = power_down_qam(demod, true);
11105                        if (rc != 0) {
11106                                pr_err("error %d\n", rc);
11107                                goto rw_error;
11108                        }
11109                        break;
11110                case DRX_STANDARD_8VSB:
11111                        rc = power_down_vsb(demod, true);
11112                        if (rc != 0) {
11113                                pr_err("error %d\n", rc);
11114                                goto rw_error;
11115                        }
11116                        break;
11117                case DRX_STANDARD_PAL_SECAM_BG:
11118                case DRX_STANDARD_PAL_SECAM_DK:
11119                case DRX_STANDARD_PAL_SECAM_I:
11120                case DRX_STANDARD_PAL_SECAM_L:
11121                case DRX_STANDARD_PAL_SECAM_LP:
11122                case DRX_STANDARD_NTSC:
11123                case DRX_STANDARD_FM:
11124                        rc = power_down_atv(demod, ext_attr->standard, true);
11125                        if (rc != 0) {
11126                                pr_err("error %d\n", rc);
11127                                goto rw_error;
11128                        }
11129                        break;
11130                case DRX_STANDARD_UNKNOWN:
11131                        /* Do nothing */
11132                        break;
11133                case DRX_STANDARD_AUTO:
11134                default:
11135                        return -EIO;
11136                }
11137                ext_attr->standard = DRX_STANDARD_UNKNOWN;
11138        }
11139
11140        if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
11141                rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
11142                if (rc != 0) {
11143                        pr_err("error %d\n", rc);
11144                        goto rw_error;
11145                }
11146                rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11147                if (rc != 0) {
11148                        pr_err("error %d\n", rc);
11149                        goto rw_error;
11150                }
11151
11152                if ((*mode != DRX_POWER_UP)) {
11153                        /* Initialize HI, wakeup key especially before put IC to sleep */
11154                        rc = init_hi(demod);
11155                        if (rc != 0) {
11156                                pr_err("error %d\n", rc);
11157                                goto rw_error;
11158                        }
11159
11160                        ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
11161                        rc = hi_cfg_command(demod);
11162                        if (rc != 0) {
11163                                pr_err("error %d\n", rc);
11164                                goto rw_error;
11165                        }
11166                }
11167        }
11168
11169        common_attr->current_power_mode = *mode;
11170
11171        return 0;
11172rw_error:
11173        return rc;
11174}
11175
11176/*============================================================================*/
11177/*== CTRL Set/Get Config related functions ===================================*/
11178/*============================================================================*/
11179
11180/*
11181* \fn int ctrl_set_cfg_pre_saw()
11182* \brief Set Pre-saw reference.
11183* \param demod demod instance
11184* \param u16 *
11185* \return int.
11186*
11187* Check arguments
11188* Dispatch handling to standard specific function.
11189*
11190*/
11191static int
11192ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
11193{
11194        struct i2c_device_addr *dev_addr = NULL;
11195        struct drxj_data *ext_attr = NULL;
11196        int rc;
11197
11198        dev_addr = demod->my_i2c_dev_addr;
11199        ext_attr = (struct drxj_data *) demod->my_ext_attr;
11200
11201        /* check arguments */
11202        if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
11203            ) {
11204                return -EINVAL;
11205        }
11206
11207        /* Only if standard is currently active */
11208        if ((ext_attr->standard == pre_saw->standard) ||
11209            (DRXJ_ISQAMSTD(ext_attr->standard) &&
11210             DRXJ_ISQAMSTD(pre_saw->standard)) ||
11211            (DRXJ_ISATVSTD(ext_attr->standard) &&
11212             DRXJ_ISATVSTD(pre_saw->standard))) {
11213                rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
11214                if (rc != 0) {
11215                        pr_err("error %d\n", rc);
11216                        goto rw_error;
11217                }
11218        }
11219
11220        /* Store pre-saw settings */
11221        switch (pre_saw->standard) {
11222        case DRX_STANDARD_8VSB:
11223                ext_attr->vsb_pre_saw_cfg = *pre_saw;
11224                break;
11225#ifndef DRXJ_VSB_ONLY
11226        case DRX_STANDARD_ITU_A:
11227        case DRX_STANDARD_ITU_B:
11228        case DRX_STANDARD_ITU_C:
11229                ext_attr->qam_pre_saw_cfg = *pre_saw;
11230                break;
11231#endif
11232        default:
11233                return -EINVAL;
11234        }
11235
11236        return 0;
11237rw_error:
11238        return rc;
11239}
11240
11241/*============================================================================*/
11242
11243/*
11244* \fn int ctrl_set_cfg_afe_gain()
11245* \brief Set AFE Gain.
11246* \param demod demod instance
11247* \param u16 *
11248* \return int.
11249*
11250* Check arguments
11251* Dispatch handling to standard specific function.
11252*
11253*/
11254static int
11255ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
11256{
11257        struct i2c_device_addr *dev_addr = NULL;
11258        struct drxj_data *ext_attr = NULL;
11259        int rc;
11260        u8 gain = 0;
11261
11262        /* check arguments */
11263        if (afe_gain == NULL)
11264                return -EINVAL;
11265
11266        dev_addr = demod->my_i2c_dev_addr;
11267        ext_attr = (struct drxj_data *) demod->my_ext_attr;
11268
11269        switch (afe_gain->standard) {
11270        case DRX_STANDARD_8VSB: fallthrough;
11271#ifndef DRXJ_VSB_ONLY
11272        case DRX_STANDARD_ITU_A:
11273        case DRX_STANDARD_ITU_B:
11274        case DRX_STANDARD_ITU_C:
11275#endif
11276                /* Do nothing */
11277                break;
11278        default:
11279                return -EINVAL;
11280        }
11281
11282        /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
11283           So I (PJ) think interface requires choice between auto, user mode */
11284
11285        if (afe_gain->gain >= 329)
11286                gain = 15;
11287        else if (afe_gain->gain <= 147)
11288                gain = 0;
11289        else
11290                gain = (afe_gain->gain - 140 + 6) / 13;
11291
11292        /* Only if standard is currently active */
11293        if (ext_attr->standard == afe_gain->standard) {
11294                        rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
11295                        if (rc != 0) {
11296                                pr_err("error %d\n", rc);
11297                                goto rw_error;
11298                        }
11299                }
11300
11301        /* Store AFE Gain settings */
11302        switch (afe_gain->standard) {
11303        case DRX_STANDARD_8VSB:
11304                ext_attr->vsb_pga_cfg = gain * 13 + 140;
11305                break;
11306#ifndef DRXJ_VSB_ONLY
11307        case DRX_STANDARD_ITU_A:
11308        case DRX_STANDARD_ITU_B:
11309        case DRX_STANDARD_ITU_C:
11310                ext_attr->qam_pga_cfg = gain * 13 + 140;
11311                break;
11312#endif
11313        default:
11314                return -EIO;
11315        }
11316
11317        return 0;
11318rw_error:
11319        return rc;
11320}
11321
11322/*============================================================================*/
11323
11324
11325/*=============================================================================
11326===== EXPORTED FUNCTIONS ====================================================*/
11327
11328static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11329                       struct drxu_code_info *mc_info,
11330                       enum drxu_code_action action);
11331static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
11332
11333/*
11334* \fn drxj_open()
11335* \brief Open the demod instance, configure device, configure drxdriver
11336* \return Status_t Return status.
11337*
11338* drxj_open() can be called with a NULL ucode image => no ucode upload.
11339* This means that drxj_open() must NOT contain SCU commands or, in general,
11340* rely on SCU or AUD ucode to be present.
11341*
11342*/
11343
11344static int drxj_open(struct drx_demod_instance *demod)
11345{
11346        struct i2c_device_addr *dev_addr = NULL;
11347        struct drxj_data *ext_attr = NULL;
11348        struct drx_common_attr *common_attr = NULL;
11349        u32 driver_version = 0;
11350        struct drxu_code_info ucode_info;
11351        struct drx_cfg_mpeg_output cfg_mpeg_output;
11352        int rc;
11353        enum drx_power_mode power_mode = DRX_POWER_UP;
11354
11355        if ((demod == NULL) ||
11356            (demod->my_common_attr == NULL) ||
11357            (demod->my_ext_attr == NULL) ||
11358            (demod->my_i2c_dev_addr == NULL) ||
11359            (demod->my_common_attr->is_opened)) {
11360                return -EINVAL;
11361        }
11362
11363        /* Check arguments */
11364        if (demod->my_ext_attr == NULL)
11365                return -EINVAL;
11366
11367        dev_addr = demod->my_i2c_dev_addr;
11368        ext_attr = (struct drxj_data *) demod->my_ext_attr;
11369        common_attr = (struct drx_common_attr *) demod->my_common_attr;
11370
11371        rc = ctrl_power_mode(demod, &power_mode);
11372        if (rc != 0) {
11373                pr_err("error %d\n", rc);
11374                goto rw_error;
11375        }
11376        if (power_mode != DRX_POWER_UP) {
11377                rc = -EINVAL;
11378                pr_err("failed to powerup device\n");
11379                goto rw_error;
11380        }
11381
11382        /* has to be in front of setIqmAf and setOrxNsuAox */
11383        rc = get_device_capabilities(demod);
11384        if (rc != 0) {
11385                pr_err("error %d\n", rc);
11386                goto rw_error;
11387        }
11388
11389        /*
11390         * Soft reset of sys- and osc-clockdomain
11391         *
11392         * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
11393         * As we didn't load the firmware here yet, we should do the same.
11394         * Btw, this is coherent with DRX-K, where we send reset codes
11395         * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
11396         */
11397        rc = drxj_dap_write_reg16(dev_addr, SIO_CC_SOFT_RST__A, (0x04 | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
11398        if (rc != 0) {
11399                pr_err("error %d\n", rc);
11400                goto rw_error;
11401        }
11402        rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11403        if (rc != 0) {
11404                pr_err("error %d\n", rc);
11405                goto rw_error;
11406        }
11407        msleep(1);
11408
11409        /* TODO first make sure that everything keeps working before enabling this */
11410        /* PowerDownAnalogBlocks() */
11411        rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
11412        if (rc != 0) {
11413                pr_err("error %d\n", rc);
11414                goto rw_error;
11415        }
11416
11417        rc = set_iqm_af(demod, false);
11418        if (rc != 0) {
11419                pr_err("error %d\n", rc);
11420                goto rw_error;
11421        }
11422        rc = set_orx_nsu_aox(demod, false);
11423        if (rc != 0) {
11424                pr_err("error %d\n", rc);
11425                goto rw_error;
11426        }
11427
11428        rc = init_hi(demod);
11429        if (rc != 0) {
11430                pr_err("error %d\n", rc);
11431                goto rw_error;
11432        }
11433
11434        /* disable mpegoutput pins */
11435        memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
11436        cfg_mpeg_output.enable_mpeg_output = false;
11437
11438        rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
11439        if (rc != 0) {
11440                pr_err("error %d\n", rc);
11441                goto rw_error;
11442        }
11443        /* Stop AUD Inform SetAudio it will need to do all setting */
11444        rc = power_down_aud(demod);
11445        if (rc != 0) {
11446                pr_err("error %d\n", rc);
11447                goto rw_error;
11448        }
11449        /* Stop SCU */
11450        rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
11451        if (rc != 0) {
11452                pr_err("error %d\n", rc);
11453                goto rw_error;
11454        }
11455
11456        /* Upload microcode */
11457        if (common_attr->microcode_file != NULL) {
11458                /* Dirty trick to use common ucode upload & verify,
11459                   pretend device is already open */
11460                common_attr->is_opened = true;
11461                ucode_info.mc_file = common_attr->microcode_file;
11462
11463                if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
11464                        pr_err("Should powerup before loading the firmware.");
11465                        return -EINVAL;
11466                }
11467
11468                rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
11469                if (rc != 0) {
11470                        pr_err("error %d while uploading the firmware\n", rc);
11471                        goto rw_error;
11472                }
11473                if (common_attr->verify_microcode == true) {
11474                        rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);
11475                        if (rc != 0) {
11476                                pr_err("error %d while verifying the firmware\n",
11477                                       rc);
11478                                goto rw_error;
11479                        }
11480                }
11481                common_attr->is_opened = false;
11482        }
11483
11484        /* Run SCU for a little while to initialize microcode version numbers */
11485        rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
11486        if (rc != 0) {
11487                pr_err("error %d\n", rc);
11488                goto rw_error;
11489        }
11490
11491        /* Initialize scan timeout */
11492        common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
11493        common_attr->scan_desired_lock = DRX_LOCKED;
11494
11495        drxj_reset_mode(ext_attr);
11496        ext_attr->standard = DRX_STANDARD_UNKNOWN;
11497
11498        rc = smart_ant_init(demod);
11499        if (rc != 0) {
11500                pr_err("error %d\n", rc);
11501                goto rw_error;
11502        }
11503
11504        /* Stamp driver version number in SCU data RAM in BCD code
11505           Done to enable field application engineers to retrieve drxdriver version
11506           via I2C from SCU RAM
11507         */
11508        driver_version = (VERSION_MAJOR / 100) % 10;
11509        driver_version <<= 4;
11510        driver_version += (VERSION_MAJOR / 10) % 10;
11511        driver_version <<= 4;
11512        driver_version += (VERSION_MAJOR % 10);
11513        driver_version <<= 4;
11514        driver_version += (VERSION_MINOR % 10);
11515        driver_version <<= 4;
11516        driver_version += (VERSION_PATCH / 1000) % 10;
11517        driver_version <<= 4;
11518        driver_version += (VERSION_PATCH / 100) % 10;
11519        driver_version <<= 4;
11520        driver_version += (VERSION_PATCH / 10) % 10;
11521        driver_version <<= 4;
11522        driver_version += (VERSION_PATCH % 10);
11523        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
11524        if (rc != 0) {
11525                pr_err("error %d\n", rc);
11526                goto rw_error;
11527        }
11528        rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
11529        if (rc != 0) {
11530                pr_err("error %d\n", rc);
11531                goto rw_error;
11532        }
11533
11534        rc = ctrl_set_oob(demod, NULL);
11535        if (rc != 0) {
11536                pr_err("error %d\n", rc);
11537                goto rw_error;
11538        }
11539
11540        /* refresh the audio data structure with default */
11541        ext_attr->aud_data = drxj_default_aud_data_g;
11542
11543        demod->my_common_attr->is_opened = true;
11544        drxj_set_lna_state(demod, false);
11545        return 0;
11546rw_error:
11547        common_attr->is_opened = false;
11548        return rc;
11549}
11550
11551/*============================================================================*/
11552/*
11553* \fn drxj_close()
11554* \brief Close the demod instance, power down the device
11555* \return Status_t Return status.
11556*
11557*/
11558static int drxj_close(struct drx_demod_instance *demod)
11559{
11560        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11561        int rc;
11562        enum drx_power_mode power_mode = DRX_POWER_UP;
11563
11564        if ((demod->my_common_attr == NULL) ||
11565            (demod->my_ext_attr == NULL) ||
11566            (demod->my_i2c_dev_addr == NULL) ||
11567            (!demod->my_common_attr->is_opened)) {
11568                return -EINVAL;
11569        }
11570
11571        /* power up */
11572        rc = ctrl_power_mode(demod, &power_mode);
11573        if (rc != 0) {
11574                pr_err("error %d\n", rc);
11575                goto rw_error;
11576        }
11577
11578        rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
11579        if (rc != 0) {
11580                pr_err("error %d\n", rc);
11581                goto rw_error;
11582        }
11583        power_mode = DRX_POWER_DOWN;
11584        rc = ctrl_power_mode(demod, &power_mode);
11585        if (rc != 0) {
11586                pr_err("error %d\n", rc);
11587                goto rw_error;
11588        }
11589
11590        DRX_ATTR_ISOPENED(demod) = false;
11591
11592        return 0;
11593rw_error:
11594        DRX_ATTR_ISOPENED(demod) = false;
11595
11596        return rc;
11597}
11598
11599/*
11600 * Microcode related functions
11601 */
11602
11603/*
11604 * drx_u_code_compute_crc       - Compute CRC of block of microcode data.
11605 * @block_data: Pointer to microcode data.
11606 * @nr_words:   Size of microcode block (number of 16 bits words).
11607 *
11608 * returns The computed CRC residue.
11609 */
11610static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
11611{
11612        u16 i = 0;
11613        u16 j = 0;
11614        u32 crc_word = 0;
11615        u32 carry = 0;
11616
11617        while (i < nr_words) {
11618                crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
11619                for (j = 0; j < 16; j++) {
11620                        crc_word <<= 1;
11621                        if (carry != 0)
11622                                crc_word ^= 0x80050000UL;
11623                        carry = crc_word & 0x80000000UL;
11624                }
11625                i++;
11626                block_data += (sizeof(u16));
11627        }
11628        return (u16)(crc_word >> 16);
11629}
11630
11631/*
11632 * drx_check_firmware - checks if the loaded firmware is valid
11633 *
11634 * @demod:      demod structure
11635 * @mc_data:    pointer to the start of the firmware
11636 * @size:       firmware size
11637 */
11638static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
11639                          unsigned size)
11640{
11641        struct drxu_code_block_hdr block_hdr;
11642        int i;
11643        unsigned count = 2 * sizeof(u16);
11644        u32 mc_dev_type, mc_version, mc_base_version;
11645        u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
11646
11647        /*
11648         * Scan microcode blocks first for version info
11649         * and firmware check
11650         */
11651
11652        /* Clear version block */
11653        DRX_ATTR_MCRECORD(demod).aux_type = 0;
11654        DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
11655        DRX_ATTR_MCRECORD(demod).mc_version = 0;
11656        DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
11657
11658        for (i = 0; i < mc_nr_of_blks; i++) {
11659                if (count + 3 * sizeof(u16) + sizeof(u32) > size)
11660                        goto eof;
11661
11662                /* Process block header */
11663                block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
11664                count += sizeof(u32);
11665                block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
11666                count += sizeof(u16);
11667                block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
11668                count += sizeof(u16);
11669                block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
11670                count += sizeof(u16);
11671
11672                pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11673                        count, block_hdr.addr, block_hdr.size, block_hdr.flags,
11674                        block_hdr.CRC);
11675
11676                if (block_hdr.flags & 0x8) {
11677                        u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
11678                        u16 auxtype;
11679
11680                        if (block_hdr.addr + sizeof(u16) > size)
11681                                goto eof;
11682
11683                        auxtype = be16_to_cpu(*(__be16 *)(auxblk));
11684
11685                        /* Aux block. Check type */
11686                        if (DRX_ISMCVERTYPE(auxtype)) {
11687                                if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
11688                                        goto eof;
11689
11690                                auxblk += sizeof(u16);
11691                                mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
11692                                auxblk += sizeof(u32);
11693                                mc_version = be32_to_cpu(*(__be32 *)(auxblk));
11694                                auxblk += sizeof(u32);
11695                                mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
11696
11697                                DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
11698                                DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
11699                                DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
11700                                DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
11701
11702                                pr_info("Firmware dev %x, ver %x, base ver %x\n",
11703                                        mc_dev_type, mc_version, mc_base_version);
11704
11705                        }
11706                } else if (count + block_hdr.size * sizeof(u16) > size)
11707                        goto eof;
11708
11709                count += block_hdr.size * sizeof(u16);
11710        }
11711        return 0;
11712eof:
11713        pr_err("Firmware is truncated at pos %u/%u\n", count, size);
11714        return -EINVAL;
11715}
11716
11717/*
11718 * drx_ctrl_u_code - Handle microcode upload or verify.
11719 * @dev_addr: Address of device.
11720 * @mc_info:  Pointer to information about microcode data.
11721 * @action:  Either UCODE_UPLOAD or UCODE_VERIFY
11722 *
11723 * This function returns:
11724 *      0:
11725 *              - In case of UCODE_UPLOAD: code is successfully uploaded.
11726 *               - In case of UCODE_VERIFY: image on device is equal to
11727 *                image provided to this control function.
11728 *      -EIO:
11729 *              - In case of UCODE_UPLOAD: I2C error.
11730 *              - In case of UCODE_VERIFY: I2C error or image on device
11731 *                is not equal to image provided to this control function.
11732 *      -EINVAL:
11733 *              - Invalid arguments.
11734 *              - Provided image is corrupt
11735 */
11736static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11737                       struct drxu_code_info *mc_info,
11738                       enum drxu_code_action action)
11739{
11740        struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11741        int rc;
11742        u16 i = 0;
11743        u16 mc_nr_of_blks = 0;
11744        u16 mc_magic_word = 0;
11745        const u8 *mc_data_init = NULL;
11746        u8 *mc_data = NULL;
11747        unsigned size;
11748        char *mc_file;
11749
11750        /* Check arguments */
11751        if (!mc_info || !mc_info->mc_file)
11752                return -EINVAL;
11753
11754        mc_file = mc_info->mc_file;
11755
11756        if (!demod->firmware) {
11757                const struct firmware *fw = NULL;
11758
11759                rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
11760                if (rc < 0) {
11761                        pr_err("Couldn't read firmware %s\n", mc_file);
11762                        return rc;
11763                }
11764                demod->firmware = fw;
11765
11766                if (demod->firmware->size < 2 * sizeof(u16)) {
11767                        rc = -EINVAL;
11768                        pr_err("Firmware is too short!\n");
11769                        goto release;
11770                }
11771
11772                pr_info("Firmware %s, size %zu\n",
11773                        mc_file, demod->firmware->size);
11774        }
11775
11776        mc_data_init = demod->firmware->data;
11777        size = demod->firmware->size;
11778
11779        mc_data = (void *)mc_data_init;
11780        /* Check data */
11781        mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
11782        mc_data += sizeof(u16);
11783        mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
11784        mc_data += sizeof(u16);
11785
11786        if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
11787                rc = -EINVAL;
11788                pr_err("Firmware magic word doesn't match\n");
11789                goto release;
11790        }
11791
11792        if (action == UCODE_UPLOAD) {
11793                rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
11794                if (rc)
11795                        goto release;
11796                pr_info("Uploading firmware %s\n", mc_file);
11797        } else {
11798                pr_info("Verifying if firmware upload was ok.\n");
11799        }
11800
11801        /* Process microcode blocks */
11802        for (i = 0; i < mc_nr_of_blks; i++) {
11803                struct drxu_code_block_hdr block_hdr;
11804                u16 mc_block_nr_bytes = 0;
11805
11806                /* Process block header */
11807                block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
11808                mc_data += sizeof(u32);
11809                block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
11810                mc_data += sizeof(u16);
11811                block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
11812                mc_data += sizeof(u16);
11813                block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
11814                mc_data += sizeof(u16);
11815
11816                pr_debug("%zd: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11817                        (mc_data - mc_data_init), block_hdr.addr,
11818                         block_hdr.size, block_hdr.flags, block_hdr.CRC);
11819
11820                /* Check block header on:
11821                   - data larger than 64Kb
11822                   - if CRC enabled check CRC
11823                 */
11824                if ((block_hdr.size > 0x7FFF) ||
11825                    (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
11826                     (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
11827                    ) {
11828                        /* Wrong data ! */
11829                        rc = -EINVAL;
11830                        pr_err("firmware CRC is wrong\n");
11831                        goto release;
11832                }
11833
11834                if (!block_hdr.size)
11835                        continue;
11836
11837                mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
11838
11839                /* Perform the desired action */
11840                switch (action) {
11841                case UCODE_UPLOAD:      /* Upload microcode */
11842                        if (drxdap_fasi_write_block(dev_addr,
11843                                                        block_hdr.addr,
11844                                                        mc_block_nr_bytes,
11845                                                        mc_data, 0x0000)) {
11846                                rc = -EIO;
11847                                pr_err("error writing firmware at pos %zd\n",
11848                                       mc_data - mc_data_init);
11849                                goto release;
11850                        }
11851                        break;
11852                case UCODE_VERIFY: {    /* Verify uploaded microcode */
11853                        int result = 0;
11854                        u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
11855                        u32 bytes_to_comp = 0;
11856                        u32 bytes_left = mc_block_nr_bytes;
11857                        u32 curr_addr = block_hdr.addr;
11858                        u8 *curr_ptr = mc_data;
11859
11860                        while (bytes_left != 0) {
11861                                if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
11862                                        bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
11863                                else
11864                                        bytes_to_comp = bytes_left;
11865
11866                                if (drxdap_fasi_read_block(dev_addr,
11867                                                    curr_addr,
11868                                                    (u16)bytes_to_comp,
11869                                                    (u8 *)mc_data_buffer,
11870                                                    0x0000)) {
11871                                        pr_err("error reading firmware at pos %zd\n",
11872                                               mc_data - mc_data_init);
11873                                        return -EIO;
11874                                }
11875
11876                                result = memcmp(curr_ptr, mc_data_buffer,
11877                                                bytes_to_comp);
11878
11879                                if (result) {
11880                                        pr_err("error verifying firmware at pos %zd\n",
11881                                               mc_data - mc_data_init);
11882                                        return -EIO;
11883                                }
11884
11885                                curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
11886                                curr_ptr =&(curr_ptr[bytes_to_comp]);
11887                                bytes_left -=((u32) bytes_to_comp);
11888                        }
11889                        break;
11890                }
11891                default:
11892                        return -EINVAL;
11893
11894                }
11895                mc_data += mc_block_nr_bytes;
11896        }
11897
11898        return 0;
11899
11900release:
11901        release_firmware(demod->firmware);
11902        demod->firmware = NULL;
11903
11904        return rc;
11905}
11906
11907/* caller is expected to check if lna is supported before enabling */
11908static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
11909{
11910        struct drxuio_cfg uio_cfg;
11911        struct drxuio_data uio_data;
11912        int result;
11913
11914        uio_cfg.uio = DRX_UIO1;
11915        uio_cfg.mode = DRX_UIO_MODE_READWRITE;
11916        /* Configure user-I/O #3: enable read/write */
11917        result = ctrl_set_uio_cfg(demod, &uio_cfg);
11918        if (result) {
11919                pr_err("Failed to setup LNA GPIO!\n");
11920                return result;
11921        }
11922
11923        uio_data.uio = DRX_UIO1;
11924        uio_data.value = state;
11925        result = ctrl_uio_write(demod, &uio_data);
11926        if (result != 0) {
11927                pr_err("Failed to %sable LNA!\n",
11928                       state ? "en" : "dis");
11929                return result;
11930        }
11931        return 0;
11932}
11933
11934/*
11935 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
11936 *
11937 * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
11938 */
11939
11940static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
11941{
11942        struct drx39xxj_state *state = fe->demodulator_priv;
11943        struct drx_demod_instance *demod = state->demod;
11944        int result;
11945        enum drx_power_mode power_mode;
11946
11947        if (enable)
11948                power_mode = DRX_POWER_UP;
11949        else
11950                power_mode = DRX_POWER_DOWN;
11951
11952        result = ctrl_power_mode(demod, &power_mode);
11953        if (result != 0) {
11954                pr_err("Power state change failed\n");
11955                return 0;
11956        }
11957
11958        return 0;
11959}
11960
11961static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
11962{
11963        struct drx39xxj_state *state = fe->demodulator_priv;
11964        struct drx_demod_instance *demod = state->demod;
11965        int result;
11966        enum drx_lock_status lock_status;
11967
11968        *status = 0;
11969
11970        result = ctrl_lock_status(demod, &lock_status);
11971        if (result != 0) {
11972                pr_err("drx39xxj: could not get lock status!\n");
11973                *status = 0;
11974        }
11975
11976        switch (lock_status) {
11977        case DRX_NEVER_LOCK:
11978                *status = 0;
11979                pr_err("drx says NEVER_LOCK\n");
11980                break;
11981        case DRX_NOT_LOCKED:
11982                *status = 0;
11983                break;
11984        case DRX_LOCK_STATE_1:
11985        case DRX_LOCK_STATE_2:
11986        case DRX_LOCK_STATE_3:
11987        case DRX_LOCK_STATE_4:
11988        case DRX_LOCK_STATE_5:
11989        case DRX_LOCK_STATE_6:
11990        case DRX_LOCK_STATE_7:
11991        case DRX_LOCK_STATE_8:
11992        case DRX_LOCK_STATE_9:
11993                *status = FE_HAS_SIGNAL
11994                    | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
11995                break;
11996        case DRX_LOCKED:
11997                *status = FE_HAS_SIGNAL
11998                    | FE_HAS_CARRIER
11999                    | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
12000                break;
12001        default:
12002                pr_err("Lock state unknown %d\n", lock_status);
12003        }
12004        ctrl_sig_quality(demod, lock_status);
12005
12006        return 0;
12007}
12008
12009static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
12010{
12011        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12012
12013        if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12014                *ber = 0;
12015                return 0;
12016        }
12017
12018        if (!p->pre_bit_count.stat[0].uvalue) {
12019                if (!p->pre_bit_error.stat[0].uvalue)
12020                        *ber = 0;
12021                else
12022                        *ber = 1000000;
12023        } else {
12024                *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
12025                                     p->pre_bit_count.stat[0].uvalue);
12026        }
12027        return 0;
12028}
12029
12030static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
12031                                         u16 *strength)
12032{
12033        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12034
12035        if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12036                *strength = 0;
12037                return 0;
12038        }
12039
12040        *strength = p->strength.stat[0].uvalue;
12041        return 0;
12042}
12043
12044static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
12045{
12046        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12047        u64 tmp64;
12048
12049        if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12050                *snr = 0;
12051                return 0;
12052        }
12053
12054        tmp64 = p->cnr.stat[0].svalue;
12055        do_div(tmp64, 10);
12056        *snr = tmp64;
12057        return 0;
12058}
12059
12060static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
12061{
12062        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12063
12064        if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12065                *ucb = 0;
12066                return 0;
12067        }
12068
12069        *ucb = p->block_error.stat[0].uvalue;
12070        return 0;
12071}
12072
12073static int drx39xxj_set_frontend(struct dvb_frontend *fe)
12074{
12075#ifdef DJH_DEBUG
12076        int i;
12077#endif
12078        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12079        struct drx39xxj_state *state = fe->demodulator_priv;
12080        struct drx_demod_instance *demod = state->demod;
12081        enum drx_standard standard = DRX_STANDARD_8VSB;
12082        struct drx_channel channel;
12083        int result;
12084        static const struct drx_channel def_channel = {
12085                /* frequency      */ 0,
12086                /* bandwidth      */ DRX_BANDWIDTH_6MHZ,
12087                /* mirror         */ DRX_MIRROR_NO,
12088                /* constellation  */ DRX_CONSTELLATION_AUTO,
12089                /* hierarchy      */ DRX_HIERARCHY_UNKNOWN,
12090                /* priority       */ DRX_PRIORITY_UNKNOWN,
12091                /* coderate       */ DRX_CODERATE_UNKNOWN,
12092                /* guard          */ DRX_GUARD_UNKNOWN,
12093                /* fftmode        */ DRX_FFTMODE_UNKNOWN,
12094                /* classification */ DRX_CLASSIFICATION_AUTO,
12095                /* symbolrate     */ 5057000,
12096                /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
12097                /* ldpc           */ DRX_LDPC_UNKNOWN,
12098                /* carrier        */ DRX_CARRIER_UNKNOWN,
12099                /* frame mode     */ DRX_FRAMEMODE_UNKNOWN
12100        };
12101        u32 constellation = DRX_CONSTELLATION_AUTO;
12102
12103        /* Bring the demod out of sleep */
12104        drx39xxj_set_powerstate(fe, 1);
12105
12106        if (fe->ops.tuner_ops.set_params) {
12107                u32 int_freq;
12108
12109                if (fe->ops.i2c_gate_ctrl)
12110                        fe->ops.i2c_gate_ctrl(fe, 1);
12111
12112                /* Set tuner to desired frequency and standard */
12113                fe->ops.tuner_ops.set_params(fe);
12114
12115                /* Use the tuner's IF */
12116                if (fe->ops.tuner_ops.get_if_frequency) {
12117                        fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
12118                        demod->my_common_attr->intermediate_freq = int_freq / 1000;
12119                }
12120
12121                if (fe->ops.i2c_gate_ctrl)
12122                        fe->ops.i2c_gate_ctrl(fe, 0);
12123        }
12124
12125        switch (p->delivery_system) {
12126        case SYS_ATSC:
12127                standard = DRX_STANDARD_8VSB;
12128                break;
12129        case SYS_DVBC_ANNEX_B:
12130                standard = DRX_STANDARD_ITU_B;
12131
12132                switch (p->modulation) {
12133                case QAM_64:
12134                        constellation = DRX_CONSTELLATION_QAM64;
12135                        break;
12136                case QAM_256:
12137                        constellation = DRX_CONSTELLATION_QAM256;
12138                        break;
12139                default:
12140                        constellation = DRX_CONSTELLATION_AUTO;
12141                        break;
12142                }
12143                break;
12144        default:
12145                return -EINVAL;
12146        }
12147        /* Set the standard (will be powered up if necessary */
12148        result = ctrl_set_standard(demod, &standard);
12149        if (result != 0) {
12150                pr_err("Failed to set standard! result=%02x\n",
12151                        result);
12152                return -EINVAL;
12153        }
12154
12155        /* set channel parameters */
12156        channel = def_channel;
12157        channel.frequency = p->frequency / 1000;
12158        channel.bandwidth = DRX_BANDWIDTH_6MHZ;
12159        channel.constellation = constellation;
12160
12161        /* program channel */
12162        result = ctrl_set_channel(demod, &channel);
12163        if (result != 0) {
12164                pr_err("Failed to set channel!\n");
12165                return -EINVAL;
12166        }
12167        /* Just for giggles, let's shut off the LNA again.... */
12168        drxj_set_lna_state(demod, false);
12169
12170        /* After set_frontend, except for strength, stats aren't available */
12171        p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12172
12173        return 0;
12174}
12175
12176static int drx39xxj_sleep(struct dvb_frontend *fe)
12177{
12178        /* power-down the demodulator */
12179        return drx39xxj_set_powerstate(fe, 0);
12180}
12181
12182static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
12183{
12184        struct drx39xxj_state *state = fe->demodulator_priv;
12185        struct drx_demod_instance *demod = state->demod;
12186        bool i2c_gate_state;
12187        int result;
12188
12189#ifdef DJH_DEBUG
12190        pr_debug("i2c gate call: enable=%d state=%d\n", enable,
12191               state->i2c_gate_open);
12192#endif
12193
12194        if (enable)
12195                i2c_gate_state = true;
12196        else
12197                i2c_gate_state = false;
12198
12199        if (state->i2c_gate_open == enable) {
12200                /* We're already in the desired state */
12201                return 0;
12202        }
12203
12204        result = ctrl_i2c_bridge(demod, &i2c_gate_state);
12205        if (result != 0) {
12206                pr_err("drx39xxj: could not open i2c gate [%d]\n",
12207                       result);
12208                dump_stack();
12209        } else {
12210                state->i2c_gate_open = enable;
12211        }
12212        return 0;
12213}
12214
12215static int drx39xxj_init(struct dvb_frontend *fe)
12216{
12217        struct drx39xxj_state *state = fe->demodulator_priv;
12218        struct drx_demod_instance *demod = state->demod;
12219        int rc = 0;
12220
12221        if (fe->exit == DVB_FE_DEVICE_RESUME) {
12222                /* so drxj_open() does what it needs to do */
12223                demod->my_common_attr->is_opened = false;
12224                rc = drxj_open(demod);
12225                if (rc != 0)
12226                        pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
12227        } else
12228                drx39xxj_set_powerstate(fe, 1);
12229
12230        return rc;
12231}
12232
12233static int drx39xxj_set_lna(struct dvb_frontend *fe)
12234{
12235        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
12236        struct drx39xxj_state *state = fe->demodulator_priv;
12237        struct drx_demod_instance *demod = state->demod;
12238        struct drxj_data *ext_attr = demod->my_ext_attr;
12239
12240        if (c->lna) {
12241                if (!ext_attr->has_lna) {
12242                        pr_err("LNA is not supported on this device!\n");
12243                        return -EINVAL;
12244
12245                }
12246        }
12247
12248        return drxj_set_lna_state(demod, c->lna);
12249}
12250
12251static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
12252                                      struct dvb_frontend_tune_settings *tune)
12253{
12254        tune->min_delay_ms = 1000;
12255        return 0;
12256}
12257
12258static void drx39xxj_release(struct dvb_frontend *fe)
12259{
12260        struct drx39xxj_state *state = fe->demodulator_priv;
12261        struct drx_demod_instance *demod = state->demod;
12262
12263        /* if device is removed don't access it */
12264        if (fe->exit != DVB_FE_DEVICE_REMOVED)
12265                drxj_close(demod);
12266
12267        kfree(demod->my_ext_attr);
12268        kfree(demod->my_common_attr);
12269        kfree(demod->my_i2c_dev_addr);
12270        release_firmware(demod->firmware);
12271        kfree(demod);
12272        kfree(state);
12273}
12274
12275static const struct dvb_frontend_ops drx39xxj_ops;
12276
12277struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
12278{
12279        struct drx39xxj_state *state = NULL;
12280        struct i2c_device_addr *demod_addr = NULL;
12281        struct drx_common_attr *demod_comm_attr = NULL;
12282        struct drxj_data *demod_ext_attr = NULL;
12283        struct drx_demod_instance *demod = NULL;
12284        struct dtv_frontend_properties *p;
12285        int result;
12286
12287        /* allocate memory for the internal state */
12288        state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);
12289        if (state == NULL)
12290                goto error;
12291
12292        demod = kmemdup(&drxj_default_demod_g,
12293                        sizeof(struct drx_demod_instance), GFP_KERNEL);
12294        if (demod == NULL)
12295                goto error;
12296
12297        demod_addr = kmemdup(&drxj_default_addr_g,
12298                             sizeof(struct i2c_device_addr), GFP_KERNEL);
12299        if (demod_addr == NULL)
12300                goto error;
12301
12302        demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
12303                                  sizeof(struct drx_common_attr), GFP_KERNEL);
12304        if (demod_comm_attr == NULL)
12305                goto error;
12306
12307        demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
12308                                 GFP_KERNEL);
12309        if (demod_ext_attr == NULL)
12310                goto error;
12311
12312        /* setup the state */
12313        state->i2c = i2c;
12314        state->demod = demod;
12315
12316        /* setup the demod data */
12317        demod->my_i2c_dev_addr = demod_addr;
12318        demod->my_common_attr = demod_comm_attr;
12319        demod->my_i2c_dev_addr->user_data = state;
12320        demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
12321        demod->my_common_attr->verify_microcode = true;
12322        demod->my_common_attr->intermediate_freq = 5000;
12323        demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
12324        demod->my_ext_attr = demod_ext_attr;
12325        ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
12326        demod->i2c = i2c;
12327
12328        result = drxj_open(demod);
12329        if (result != 0) {
12330                pr_err("DRX open failed!  Aborting\n");
12331                goto error;
12332        }
12333
12334        /* create dvb_frontend */
12335        memcpy(&state->frontend.ops, &drx39xxj_ops,
12336               sizeof(struct dvb_frontend_ops));
12337
12338        state->frontend.demodulator_priv = state;
12339
12340        /* Initialize stats - needed for DVBv5 stats to work */
12341        p = &state->frontend.dtv_property_cache;
12342        p->strength.len = 1;
12343        p->pre_bit_count.len = 1;
12344        p->pre_bit_error.len = 1;
12345        p->post_bit_count.len = 1;
12346        p->post_bit_error.len = 1;
12347        p->block_count.len = 1;
12348        p->block_error.len = 1;
12349        p->cnr.len = 1;
12350
12351        p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12352        p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12353        p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12354        p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12355        p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12356        p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12357        p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12358        p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12359
12360        return &state->frontend;
12361
12362error:
12363        kfree(demod_ext_attr);
12364        kfree(demod_comm_attr);
12365        kfree(demod_addr);
12366        kfree(demod);
12367        kfree(state);
12368
12369        return NULL;
12370}
12371EXPORT_SYMBOL(drx39xxj_attach);
12372
12373static const struct dvb_frontend_ops drx39xxj_ops = {
12374        .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
12375        .info = {
12376                 .name = "Micronas DRX39xxj family Frontend",
12377                 .frequency_min_hz =  51 * MHz,
12378                 .frequency_max_hz = 858 * MHz,
12379                 .frequency_stepsize_hz = 62500,
12380                 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
12381        },
12382
12383        .init = drx39xxj_init,
12384        .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
12385        .sleep = drx39xxj_sleep,
12386        .set_frontend = drx39xxj_set_frontend,
12387        .get_tune_settings = drx39xxj_get_tune_settings,
12388        .read_status = drx39xxj_read_status,
12389        .read_ber = drx39xxj_read_ber,
12390        .read_signal_strength = drx39xxj_read_signal_strength,
12391        .read_snr = drx39xxj_read_snr,
12392        .read_ucblocks = drx39xxj_read_ucblocks,
12393        .release = drx39xxj_release,
12394        .set_lna = drx39xxj_set_lna,
12395};
12396
12397MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
12398MODULE_AUTHOR("Devin Heitmueller");
12399MODULE_LICENSE("GPL");
12400MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);
12401