linux/drivers/media/dvb-frontends/drx39xyj/drxj.c

/*
  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
	and/or other materials provided with the distribution.
  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
    nor the names of its contributors may be used to endorse or promote
	products derived from this software without specific prior written
	permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.

  DRXJ specific implementation of DRX driver
  authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen

  The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
  written by Devin Heitmueller <[email protected]>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*-----------------------------------------------------------------------------
INCLUDE FILES
----------------------------------------------------------------------------*/

#define pr_fmt(fmt)

#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <asm/div64.h>

#include <media/dvb_frontend.h>
#include "drx39xxj.h"

#include "drxj.h"
#include "drxj_map.h"

/*============================================================================*/
/*=== DEFINES ================================================================*/
/*============================================================================*/

#define DRX39XX_MAIN_FIRMWARE

/*
* \brief Maximum u32 value.
*/
#ifndef MAX_U32
#define MAX_U32
#endif

/* Customer configurable hardware settings, etc */
#ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
#define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
#endif

#ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
#define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
#endif

#ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
#define MPEG_OUTPUT_CLK_DRIVE_STRENGTH
#endif

#ifndef OOB_CRX_DRIVE_STRENGTH
#define OOB_CRX_DRIVE_STRENGTH
#endif

#ifndef OOB_DRX_DRIVE_STRENGTH
#define OOB_DRX_DRIVE_STRENGTH
#endif
/*** START DJCOMBO patches to DRXJ registermap constants *********************/
/*** registermap 200706071303 from drxj **************************************/
#define ATV_TOP_CR_AMP_TH_FM
#define ATV_TOP_CR_AMP_TH_L
#define ATV_TOP_CR_AMP_TH_LP
#define ATV_TOP_CR_AMP_TH_BG
#define ATV_TOP_CR_AMP_TH_DK
#define ATV_TOP_CR_AMP_TH_I
#define ATV_TOP_CR_CONT_CR_D_MN
#define ATV_TOP_CR_CONT_CR_D_FM
#define ATV_TOP_CR_CONT_CR_D_L
#define ATV_TOP_CR_CONT_CR_D_LP
#define ATV_TOP_CR_CONT_CR_D_BG
#define ATV_TOP_CR_CONT_CR_D_DK
#define ATV_TOP_CR_CONT_CR_D_I
#define ATV_TOP_CR_CONT_CR_I_MN
#define ATV_TOP_CR_CONT_CR_I_FM
#define ATV_TOP_CR_CONT_CR_I_L
#define ATV_TOP_CR_CONT_CR_I_LP
#define ATV_TOP_CR_CONT_CR_I_BG
#define ATV_TOP_CR_CONT_CR_I_DK
#define ATV_TOP_CR_CONT_CR_I_I
#define ATV_TOP_CR_CONT_CR_P_MN
#define ATV_TOP_CR_CONT_CR_P_FM
#define ATV_TOP_CR_CONT_CR_P_L
#define ATV_TOP_CR_CONT_CR_P_LP
#define ATV_TOP_CR_CONT_CR_P_BG
#define ATV_TOP_CR_CONT_CR_P_DK
#define ATV_TOP_CR_CONT_CR_P_I
#define ATV_TOP_CR_OVM_TH_MN
#define ATV_TOP_CR_OVM_TH_FM
#define ATV_TOP_CR_OVM_TH_L
#define ATV_TOP_CR_OVM_TH_LP
#define ATV_TOP_CR_OVM_TH_BG
#define ATV_TOP_CR_OVM_TH_DK
#define ATV_TOP_CR_OVM_TH_I
#define ATV_TOP_EQU0_EQU_C0_FM
#define ATV_TOP_EQU0_EQU_C0_L
#define ATV_TOP_EQU0_EQU_C0_LP
#define ATV_TOP_EQU0_EQU_C0_BG
#define ATV_TOP_EQU0_EQU_C0_DK
#define ATV_TOP_EQU0_EQU_C0_I
#define ATV_TOP_EQU1_EQU_C1_FM
#define ATV_TOP_EQU1_EQU_C1_L
#define ATV_TOP_EQU1_EQU_C1_LP
#define ATV_TOP_EQU1_EQU_C1_BG
#define ATV_TOP_EQU1_EQU_C1_DK
#define ATV_TOP_EQU1_EQU_C1_I
#define ATV_TOP_EQU2_EQU_C2_FM
#define ATV_TOP_EQU2_EQU_C2_L
#define ATV_TOP_EQU2_EQU_C2_LP
#define ATV_TOP_EQU2_EQU_C2_BG
#define ATV_TOP_EQU2_EQU_C2_DK
#define ATV_TOP_EQU2_EQU_C2_I
#define ATV_TOP_EQU3_EQU_C3_FM
#define ATV_TOP_EQU3_EQU_C3_L
#define ATV_TOP_EQU3_EQU_C3_LP
#define ATV_TOP_EQU3_EQU_C3_BG
#define ATV_TOP_EQU3_EQU_C3_DK
#define ATV_TOP_EQU3_EQU_C3_I
#define ATV_TOP_STD_MODE_MN
#define ATV_TOP_STD_MODE_FM
#define ATV_TOP_STD_MODE_L
#define ATV_TOP_STD_MODE_LP
#define ATV_TOP_STD_MODE_BG
#define ATV_TOP_STD_MODE_DK
#define ATV_TOP_STD_MODE_I
#define ATV_TOP_STD_VID_POL_MN
#define ATV_TOP_STD_VID_POL_FM
#define ATV_TOP_STD_VID_POL_L
#define ATV_TOP_STD_VID_POL_LP
#define ATV_TOP_STD_VID_POL_BG
#define ATV_TOP_STD_VID_POL_DK
#define ATV_TOP_STD_VID_POL_I
#define ATV_TOP_VID_AMP_MN
#define ATV_TOP_VID_AMP_FM
#define ATV_TOP_VID_AMP_L
#define ATV_TOP_VID_AMP_LP
#define ATV_TOP_VID_AMP_BG
#define ATV_TOP_VID_AMP_DK
#define ATV_TOP_VID_AMP_I
#define IQM_CF_OUT_ENA_OFDM__M
#define IQM_FS_ADJ_SEL_B_QAM
#define IQM_FS_ADJ_SEL_B_OFF
#define IQM_FS_ADJ_SEL_B_VSB
#define IQM_RC_ADJ_SEL_B_OFF
#define IQM_RC_ADJ_SEL_B_QAM
#define IQM_RC_ADJ_SEL_B_VSB
/*** END DJCOMBO patches to DRXJ registermap *********************************/

#include "drx_driver_version.h"

/* #define DRX_DEBUG */
#ifdef DRX_DEBUG
#include <stdio.h>
#endif

/*-----------------------------------------------------------------------------
ENUMS
----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
DEFINES
----------------------------------------------------------------------------*/
#ifndef DRXJ_WAKE_UP_KEY
#define DRXJ_WAKE_UP_KEY
#endif

/*
* \def DRXJ_DEF_I2C_ADDR
* \brief Default I2C address of a demodulator instance.
*/
#define DRXJ_DEF_I2C_ADDR

/*
* \def DRXJ_DEF_DEMOD_DEV_ID
* \brief Default device identifier of a demodultor instance.
*/
#define DRXJ_DEF_DEMOD_DEV_ID

/*
* \def DRXJ_SCAN_TIMEOUT
* \brief Timeout value for waiting on demod lock during channel scan (millisec).
*/
#define DRXJ_SCAN_TIMEOUT

/*
* \def HI_I2C_DELAY
* \brief HI timing delay for I2C timing (in nano seconds)
*
*  Used to compute HI_CFG_DIV
*/
#define HI_I2C_DELAY

/*
* \def HI_I2C_BRIDGE_DELAY
* \brief HI timing delay for I2C timing (in nano seconds)
*
*  Used to compute HI_CFG_BDL
*/
#define HI_I2C_BRIDGE_DELAY

/*
* \brief Time Window for MER and SER Measurement in Units of Segment duration.
*/
#define VSB_TOP_MEASUREMENT_PERIOD
#define SYMBOLS_PER_SEGMENT

/*
* \brief bit rate and segment rate constants used for SER and BER.
*/
/* values taken from the QAM microcode */
#define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN
#define DRXJ_QAM_SL_SIG_POWER_QPSK
#define DRXJ_QAM_SL_SIG_POWER_QAM8
#define DRXJ_QAM_SL_SIG_POWER_QAM16
#define DRXJ_QAM_SL_SIG_POWER_QAM32
#define DRXJ_QAM_SL_SIG_POWER_QAM64
#define DRXJ_QAM_SL_SIG_POWER_QAM128
#define DRXJ_QAM_SL_SIG_POWER_QAM256
/*
* \brief Min supported symbolrates.
*/
#ifndef DRXJ_QAM_SYMBOLRATE_MIN
#define DRXJ_QAM_SYMBOLRATE_MIN
#endif

/*
* \brief Max supported symbolrates.
*/
#ifndef DRXJ_QAM_SYMBOLRATE_MAX
#define DRXJ_QAM_SYMBOLRATE_MAX
#endif

/*
* \def DRXJ_QAM_MAX_WAITTIME
* \brief Maximal wait time for QAM auto constellation in ms
*/
#ifndef DRXJ_QAM_MAX_WAITTIME
#define DRXJ_QAM_MAX_WAITTIME
#endif

#ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
#define DRXJ_QAM_FEC_LOCK_WAITTIME
#endif

#ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
#endif

/*
* \def SCU status and results
* \brief SCU
*/
#define DRX_SCU_READY
#define DRXJ_MAX_WAITTIME
#define FEC_RS_MEASUREMENT_PERIOD
#define FEC_RS_MEASUREMENT_PRESCALE

/*
* \def DRX_AUD_MAX_DEVIATION
* \brief Needed for calculation of prescale feature in AUD
*/
#ifndef DRXJ_AUD_MAX_FM_DEVIATION
#define DRXJ_AUD_MAX_FM_DEVIATION
#endif

/*
* \brief Needed for calculation of NICAM prescale feature in AUD
*/
#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
#define DRXJ_AUD_MAX_NICAM_PRESCALE
#endif

/*
* \brief Needed for calculation of NICAM prescale feature in AUD
*/
#ifndef DRXJ_AUD_MAX_WAITTIME
#define DRXJ_AUD_MAX_WAITTIME
#endif

/* ATV config changed flags */
#define DRXJ_ATV_CHANGED_COEF
#define DRXJ_ATV_CHANGED_PEAK_FLT
#define DRXJ_ATV_CHANGED_NOISE_FLT
#define DRXJ_ATV_CHANGED_OUTPUT
#define DRXJ_ATV_CHANGED_SIF_ATT

/* UIO define */
#define DRX_UIO_MODE_FIRMWARE_SMA
#define DRX_UIO_MODE_FIRMWARE_SAW

/*
 * MICROCODE RELATED DEFINES
 */

/* Magic word for checking correct Endianness of microcode data */
#define DRX_UCODE_MAGIC_WORD

/* CRC flag in ucode header, flags field. */
#define DRX_UCODE_CRC_FLAG

/*
 * Maximum size of buffer used to verify the microcode.
 * Must be an even number
 */
#define DRX_UCODE_MAX_BUF_SIZE

#if DRX_UCODE_MAX_BUF_SIZE & 1
#error DRX_UCODE_MAX_BUF_SIZE must be an even number
#endif

/*
 * Power mode macros
 */

#define DRX_ISPOWERDOWNMODE(mode)

/* Pin safe mode macro */
#define DRXJ_PIN_SAFE_MODE
/*============================================================================*/
/*=== GLOBAL VARIABLEs =======================================================*/
/*============================================================================*/
/*
*/

/*
* \brief Temporary register definitions.
*        (register definitions that are not yet available in register master)
*/

/*****************************************************************************/
/* Audio block 0x103 is write only. To avoid shadowing in driver accessing   */
/* RAM addresses directly. This must be READ ONLY to avoid problems.         */
/* Writing to the interface addresses are more than only writing the RAM     */
/* locations                                                                 */
/*****************************************************************************/
/*
* \brief RAM location of MODUS registers
*/
#define AUD_DEM_RAM_MODUS_HI__A
#define AUD_DEM_RAM_MODUS_HI__M

#define AUD_DEM_RAM_MODUS_LO__A
#define AUD_DEM_RAM_MODUS_LO__M

/*
* \brief RAM location of I2S config registers
*/
#define AUD_DEM_RAM_I2S_CONFIG1__A
#define AUD_DEM_RAM_I2S_CONFIG2__A

/*
* \brief RAM location of DCO config registers
*/
#define AUD_DEM_RAM_DCO_B_HI__A
#define AUD_DEM_RAM_DCO_B_LO__A
#define AUD_DEM_RAM_DCO_A_HI__A
#define AUD_DEM_RAM_DCO_A_LO__A

/*
* \brief RAM location of Threshold registers
*/
#define AUD_DEM_RAM_NICAM_THRSHLD__A
#define AUD_DEM_RAM_A2_THRSHLD__A
#define AUD_DEM_RAM_BTSC_THRSHLD__A

/*
* \brief RAM location of Carrier Threshold registers
*/
#define AUD_DEM_RAM_CM_A_THRSHLD__A
#define AUD_DEM_RAM_CM_B_THRSHLD__A

/*
* \brief FM Matrix register fix
*/
#ifdef AUD_DEM_WR_FM_MATRIX__A
#undef  AUD_DEM_WR_FM_MATRIX__A
#endif
#define AUD_DEM_WR_FM_MATRIX__A

/*============================================================================*/
/*
* \brief Defines required for audio
*/
#define AUD_VOLUME_ZERO_DB
#define AUD_VOLUME_DB_MIN
#define AUD_VOLUME_DB_MAX
#define AUD_CARRIER_STRENGTH_QP_0DB
#define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100
#define AUD_MAX_AVC_REF_LEVEL
#define AUD_I2S_FREQUENCY_MAX
#define AUD_I2S_FREQUENCY_MIN
#define AUD_RDS_ARRAY_SIZE

/*
* \brief Needed for calculation of prescale feature in AUD
*/
#ifndef DRX_AUD_MAX_FM_DEVIATION
#define DRX_AUD_MAX_FM_DEVIATION
#endif

/*
* \brief Needed for calculation of NICAM prescale feature in AUD
*/
#ifndef DRX_AUD_MAX_NICAM_PRESCALE
#define DRX_AUD_MAX_NICAM_PRESCALE
#endif

/*============================================================================*/
/* Values for I2S Master/Slave pin configurations */
#define SIO_PDR_I2S_CL_CFG_MODE__MASTER
#define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER
#define SIO_PDR_I2S_CL_CFG_MODE__SLAVE
#define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE

#define SIO_PDR_I2S_DA_CFG_MODE__MASTER
#define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER
#define SIO_PDR_I2S_DA_CFG_MODE__SLAVE
#define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE

#define SIO_PDR_I2S_WS_CFG_MODE__MASTER
#define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER
#define SIO_PDR_I2S_WS_CFG_MODE__SLAVE
#define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE

/*============================================================================*/
/*=== REGISTER ACCESS MACROS =================================================*/
/*============================================================================*/

/*
* This macro is used to create byte arrays for block writes.
* Block writes speed up I2C traffic between host and demod.
* The macro takes care of the required byte order in a 16 bits word.
* x -> lowbyte(x), highbyte(x)
*/
#define DRXJ_16TO8(x)
/*
* This macro is used to convert byte array to 16 bit register value for block read.
* Block read speed up I2C traffic between host and demod.
* The macro takes care of the required byte order in a 16 bits word.
*/
#define DRXJ_8TO16(x)

/*============================================================================*/
/*=== MISC DEFINES ===========================================================*/
/*============================================================================*/

/*============================================================================*/
/*=== HI COMMAND RELATED DEFINES =============================================*/
/*============================================================================*/

/*
* \brief General maximum number of retries for ucode command interfaces
*/
#define DRXJ_MAX_RETRIES

/*============================================================================*/
/*=== STANDARD RELATED MACROS ================================================*/
/*============================================================================*/

#define DRXJ_ISATVSTD(std)

#define DRXJ_ISQAMSTD(std)

/*-----------------------------------------------------------------------------
GLOBAL VARIABLES
----------------------------------------------------------------------------*/
/*
 * DRXJ DAP structures
 */

static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
				      u32 addr,
				      u16 datasize,
				      u8 *data, u32 flags);


static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
						 u32 waddr,
						 u32 raddr,
						 u16 wdata, u16 *rdata);

static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
				      u32 addr,
				      u16 *data, u32 flags);

static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
				      u32 addr,
				      u32 *data, u32 flags);

static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
				       u32 addr,
				       u16 datasize,
				       u8 *data, u32 flags);

static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
				       u32 addr,
				       u16 data, u32 flags);

static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
				       u32 addr,
				       u32 data, u32 flags);

static struct drxj_data drxj_data_g =;

/*
* \var drxj_default_addr_g
* \brief Default I2C address and device identifier.
*/
static struct i2c_device_addr drxj_default_addr_g =;

/*
* \var drxj_default_comm_attr_g
* \brief Default common attributes of a drxj demodulator instance.
*/
static struct drx_common_attr drxj_default_comm_attr_g =;

/*
* \var drxj_default_demod_g
* \brief Default drxj demodulator instance.
*/
static struct drx_demod_instance drxj_default_demod_g =;

/*
* \brief Default audio data structure for DRK demodulator instance.
*
* This structure is DRXK specific.
*
*/
static struct drx_aud_data drxj_default_aud_data_g =;

/*-----------------------------------------------------------------------------
STRUCTURES
----------------------------------------------------------------------------*/
/* HI command */
struct drxj_hi_cmd {};

/*============================================================================*/
/*=== MICROCODE RELATED STRUCTURES ===========================================*/
/*============================================================================*/

/*
 * struct drxu_code_block_hdr - Structure of the microcode block headers
 *
 * @addr:	Destination address of the data in this block
 * @size:	Size of the block data following this header counted in
 *		16 bits words
 * @CRC:	CRC value of the data block, only valid if CRC flag is
 *		set.
 */
struct drxu_code_block_hdr {};

/*-----------------------------------------------------------------------------
FUNCTIONS
----------------------------------------------------------------------------*/
/* Some prototypes */
static int
hi_command(struct i2c_device_addr *dev_addr,
	   const struct drxj_hi_cmd *cmd, u16 *result);

static int
ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);

static int
ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);

static int power_down_aud(struct drx_demod_instance *demod);

static int
ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);

static int
ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);

/*============================================================================*/
/*============================================================================*/
/*==                          HELPER FUNCTIONS                              ==*/
/*============================================================================*/
/*============================================================================*/


/*============================================================================*/

/*
* \fn u32 frac28(u32 N, u32 D)
* \brief Compute: (1<<28)*N/D
* \param N 32 bits
* \param D 32 bits
* \return (1<<28)*N/D
* This function is used to avoid floating-point calculations as they may
* not be present on the target platform.

* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
* fraction used for setting the Frequency Shifter registers.
* N and D can hold numbers up to width: 28-bits.
* The 4 bits integer part and the 28 bits fractional part are calculated.

* Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999

* N: 0...(1<<28)-1 = 268435454
* D: 0...(1<<28)-1
* Q: 0...(1<<32)-1
*/
static u32 frac28(u32 N, u32 D)
{}

/*
* \fn u32 log1_times100( u32 x)
* \brief Compute: 100*log10(x)
* \param x 32 bits
* \return 100*log10(x)
*
* 100*log10(x)
* = 100*(log2(x)/log2(10)))
* = (100*(2^15)*log2(x))/((2^15)*log2(10))
* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
*
* where y = 2^k and 1<= (x/y) < 2
*/

static u32 log1_times100(u32 x)
{}

/*
* \fn u32 frac_times1e6( u16 N, u32 D)
* \brief Compute: (N/D) * 1000000.
* \param N nominator 16-bits.
* \param D denominator 32-bits.
* \return u32
* \retval ((N/D) * 1000000), 32 bits
*
* No check on D=0!
*/
static u32 frac_times1e6(u32 N, u32 D)
{}

/*============================================================================*/


/*
* \brief Values for NICAM prescaler gain. Computed from dB to integer
*        and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
*
*/
#if 0
/* Currently, unused as we lack support for analog TV */
static const u16 nicam_presc_table_val[43] = {
	1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
	5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
	18, 20, 23, 25, 28, 32, 36, 40, 45,
	51, 57, 64, 71, 80, 90, 101, 113, 127
};
#endif

/*============================================================================*/
/*==                        END HELPER FUNCTIONS                            ==*/
/*============================================================================*/

/*============================================================================*/
/*============================================================================*/
/*==                      DRXJ DAP FUNCTIONS                                ==*/
/*============================================================================*/
/*============================================================================*/

/*
   This layer takes care of some device specific register access protocols:
   -conversion to short address format
   -access to audio block
   This layer is placed between the drx_dap_fasi and the rest of the drxj
   specific implementation. This layer can use address map knowledge whereas
   dap_fasi may not use memory map knowledge.

   * For audio currently only 16 bits read and write register access is
     supported. More is not needed. RMW and 32 or 8 bit access on audio
     registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
     single/multi master) will be ignored.

   TODO: check ignoring single/multimaster is ok for AUD access ?
*/

#define DRXJ_ISAUDWRITE(addr)
#define DRXJ_DAP_AUDTRIF_TIMEOUT
/*============================================================================*/

/*
* \fn bool is_handled_by_aud_tr_if( u32 addr )
* \brief Check if this address is handled by the audio token ring interface.
* \param addr
* \return bool
* \retval true  Yes, handled by audio token ring interface
* \retval false No, not handled by audio token ring interface
*
*/
static
bool is_handled_by_aud_tr_if(u32 addr)
{}

/*============================================================================*/

int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
				 u16 w_count,
				 u8 *wData,
				 struct i2c_device_addr *r_dev_addr,
				 u16 r_count, u8 *r_data)
{}

/*============================================================================*/

/*****************************
*
* int drxdap_fasi_read_block (
*      struct i2c_device_addr *dev_addr,      -- address of I2C device
*      u32 addr,         -- address of chip register/memory
*      u16            datasize,     -- number of bytes to read
*      u8 *data,         -- data to receive
*      u32 flags)        -- special device flags
*
* Read block data from chip address. Because the chip is word oriented,
* the number of bytes to read must be even.
*
* Make sure that the buffer to receive the data is large enough.
*
* Although this function expects an even number of bytes, it is still byte
* oriented, and the data read back is NOT translated to the endianness of
* the target platform.
*
* Output:
* - 0     if reading was successful
*                  in that case: data read is in *data.
* - -EIO  if anything went wrong
*
******************************/

static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
					 u32 addr,
					 u16 datasize,
					 u8 *data, u32 flags)
{}


/*****************************
*
* int drxdap_fasi_read_reg16 (
*     struct i2c_device_addr *dev_addr, -- address of I2C device
*     u32 addr,    -- address of chip register/memory
*     u16 *data,    -- data to receive
*     u32 flags)   -- special device flags
*
* Read one 16-bit register or memory location. The data received back is
* converted back to the target platform's endianness.
*
* Output:
* - 0     if reading was successful
*                  in that case: read data is at *data
* - -EIO  if anything went wrong
*
******************************/

static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
					 u32 addr,
					 u16 *data, u32 flags)
{}

/*****************************
*
* int drxdap_fasi_read_reg32 (
*     struct i2c_device_addr *dev_addr, -- address of I2C device
*     u32 addr,    -- address of chip register/memory
*     u32 *data,    -- data to receive
*     u32 flags)   -- special device flags
*
* Read one 32-bit register or memory location. The data received back is
* converted back to the target platform's endianness.
*
* Output:
* - 0     if reading was successful
*                  in that case: read data is at *data
* - -EIO  if anything went wrong
*
******************************/

static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
					 u32 addr,
					 u32 *data, u32 flags)
{}

/*****************************
*
* int drxdap_fasi_write_block (
*      struct i2c_device_addr *dev_addr,    -- address of I2C device
*      u32 addr,       -- address of chip register/memory
*      u16            datasize,   -- number of bytes to read
*      u8 *data,       -- data to receive
*      u32 flags)      -- special device flags
*
* Write block data to chip address. Because the chip is word oriented,
* the number of bytes to write must be even.
*
* Although this function expects an even number of bytes, it is still byte
* oriented, and the data being written is NOT translated from the endianness of
* the target platform.
*
* Output:
* - 0     if writing was successful
* - -EIO  if anything went wrong
*
******************************/

static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
					  u32 addr,
					  u16 datasize,
					  u8 *data, u32 flags)
{}

/*****************************
*
* int drxdap_fasi_write_reg16 (
*     struct i2c_device_addr *dev_addr, -- address of I2C device
*     u32 addr,    -- address of chip register/memory
*     u16            data,    -- data to send
*     u32 flags)   -- special device flags
*
* Write one 16-bit register or memory location. The data being written is
* converted from the target platform's endianness to little endian.
*
* Output:
* - 0     if writing was successful
* - -EIO  if anything went wrong
*
******************************/

static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
					  u32 addr,
					  u16 data, u32 flags)
{}

/*****************************
*
* int drxdap_fasi_read_modify_write_reg16 (
*      struct i2c_device_addr *dev_addr,   -- address of I2C device
*      u32 waddr,     -- address of chip register/memory
*      u32 raddr,     -- chip address to read back from
*      u16            wdata,     -- data to send
*      u16 *rdata)     -- data to receive back
*
* Write 16-bit data, then read back the original contents of that location.
* Requires long addressing format to be allowed.
*
* Before sending data, the data is converted to little endian. The
* data received back is converted back to the target platform's endianness.
*
* WARNING: This function is only guaranteed to work if there is one
* master on the I2C bus.
*
* Output:
* - 0     if reading was successful
*                  in that case: read back data is at *rdata
* - -EIO  if anything went wrong
*
******************************/

static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
						    u32 waddr,
						    u32 raddr,
						    u16 wdata, u16 *rdata)
{}

/*****************************
*
* int drxdap_fasi_write_reg32 (
*     struct i2c_device_addr *dev_addr, -- address of I2C device
*     u32 addr,    -- address of chip register/memory
*     u32            data,    -- data to send
*     u32 flags)   -- special device flags
*
* Write one 32-bit register or memory location. The data being written is
* converted from the target platform's endianness to little endian.
*
* Output:
* - 0     if writing was successful
* - -EIO  if anything went wrong
*
******************************/

static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
					  u32 addr,
					  u32 data, u32 flags)
{}

/*============================================================================*/

/*
* \fn int drxj_dap_rm_write_reg16short
* \brief Read modify write 16 bits audio register using short format only.
* \param dev_addr
* \param waddr    Address to write to
* \param raddr    Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
* \param wdata    Data to write
* \param rdata    Buffer for data to read
* \return int
* \retval 0 Success
* \retval -EIO Timeout, I2C error, illegal bank
*
* 16 bits register read modify write access using short addressing format only.
* Requires knowledge of the registermap, thus device dependent.
* Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
*
*/

/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
   See comments drxj_dap_read_modify_write_reg16 */
#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
					      u32 waddr,
					      u32 raddr,
					      u16 wdata, u16 *rdata)
{
	int rc;

	if (rdata == NULL)
		return -EINVAL;

	/* Set RMW flag */
	rc = drxdap_fasi_write_reg16(dev_addr,
					      SIO_HI_RA_RAM_S0_FLG_ACC__A,
					      SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
					      0x0000);
	if (rc == 0) {
		/* Write new data: triggers RMW */
		rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
						      0x0000);
	}
	if (rc == 0) {
		/* Read old data */
		rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
						     0x0000);
	}
	if (rc == 0) {
		/* Reset RMW flag */
		rc = drxdap_fasi_write_reg16(dev_addr,
						      SIO_HI_RA_RAM_S0_FLG_ACC__A,
						      0, 0x0000);
	}

	return rc;
}
#endif

/*============================================================================*/

static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
						 u32 waddr,
						 u32 raddr,
						 u16 wdata, u16 *rdata)
{}


/*============================================================================*/

/*
* \fn int drxj_dap_read_aud_reg16
* \brief Read 16 bits audio register
* \param dev_addr
* \param addr
* \param data
* \return int
* \retval 0 Success
* \retval -EIO Timeout, I2C error, illegal bank
*
* 16 bits register read access via audio token ring interface.
*
*/
static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
					 u32 addr, u16 *data)
{}

/*============================================================================*/

static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
				      u32 addr,
				      u16 *data, u32 flags)
{}
/*============================================================================*/

/*
* \fn int drxj_dap_write_aud_reg16
* \brief Write 16 bits audio register
* \param dev_addr
* \param addr
* \param data
* \return int
* \retval 0 Success
* \retval -EIO Timeout, I2C error, illegal bank
*
* 16 bits register write access via audio token ring interface.
*
*/
static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
					  u32 addr, u16 data)
{}

/*============================================================================*/

static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
				       u32 addr,
				       u16 data, u32 flags)
{}

/*============================================================================*/

/* Free data ram in SIO HI */
#define SIO_HI_RA_RAM_USR_BEGIN__A
#define SIO_HI_RA_RAM_USR_END__A

#define DRXJ_HI_ATOMIC_BUF_START
#define DRXJ_HI_ATOMIC_BUF_END
#define DRXJ_HI_ATOMIC_READ
#define DRXJ_HI_ATOMIC_WRITE

/*
* \fn int drxj_dap_atomic_read_write_block()
* \brief Basic access routine for atomic read or write access
* \param dev_addr  pointer to i2c dev address
* \param addr     destination/source address
* \param datasize size of data buffer in bytes
* \param data     pointer to data buffer
* \return int
* \retval 0 Success
* \retval -EIO Timeout, I2C error, illegal bank
*
*/
static
int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
					  u32 addr,
					  u16 datasize,
					  u8 *data, bool read_flag)
{}

/*============================================================================*/

/*
* \fn int drxj_dap_atomic_read_reg32()
* \brief Atomic read of 32 bits words
*/
static
int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
				     u32 addr,
				     u32 *data, u32 flags)
{}

/*============================================================================*/

/*============================================================================*/
/*==                        END DRXJ DAP FUNCTIONS                          ==*/
/*============================================================================*/

/*============================================================================*/
/*============================================================================*/
/*==                      HOST INTERFACE FUNCTIONS                          ==*/
/*============================================================================*/
/*============================================================================*/

/*
* \fn int hi_cfg_command()
* \brief Configure HI with settings stored in the demod structure.
* \param demod Demodulator.
* \return int.
*
* This routine was created because to much orthogonal settings have
* been put into one HI API function (configure). Especially the I2C bridge
* enable/disable should not need re-configuration of the HI.
*
*/
static int hi_cfg_command(const struct drx_demod_instance *demod)
{}

/*
* \fn int hi_command()
* \brief Configure HI with settings stored in the demod structure.
* \param dev_addr I2C address.
* \param cmd HI command.
* \param result HI command result.
* \return int.
*
* Sends command to HI
*
*/
static int
hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
{}

/*
* \fn int init_hi( const struct drx_demod_instance *demod )
* \brief Initialise and configurate HI.
* \param demod pointer to demod data.
* \return int Return status.
* \retval 0 Success.
* \retval -EIO Failure.
*
* Needs to know Psys (System Clock period) and Posc (Osc Clock period)
* Need to store configuration in driver because of the way I2C
* bridging is controlled.
*
*/
static int init_hi(const struct drx_demod_instance *demod)
{}

/*============================================================================*/
/*==                   END HOST INTERFACE FUNCTIONS                         ==*/
/*============================================================================*/

/*============================================================================*/
/*============================================================================*/
/*==                        AUXILIARY FUNCTIONS                             ==*/
/*============================================================================*/
/*============================================================================*/

/*
* \fn int get_device_capabilities()
* \brief Get and store device capabilities.
* \param demod  Pointer to demodulator instance.
* \return int.
* \return 0    Success
* \retval -EIO Failure
*
* Depending on pulldowns on MDx pins the following internals are set:
*  * common_attr->osc_clock_freq
*  * ext_attr->has_lna
*  * ext_attr->has_ntsc
*  * ext_attr->has_btsc
*  * ext_attr->has_oob
*
*/
static int get_device_capabilities(struct drx_demod_instance *demod)
{}

/*
* \fn int power_up_device()
* \brief Power up device.
* \param demod  Pointer to demodulator instance.
* \return int.
* \return 0    Success
* \retval -EIO Failure, I2C or max retries reached
*
*/

#ifndef DRXJ_MAX_RETRIES_POWERUP
#define DRXJ_MAX_RETRIES_POWERUP
#endif

static int power_up_device(struct drx_demod_instance *demod)
{}

/*----------------------------------------------------------------------------*/
/* MPEG Output Configuration Functions - begin                                */
/*----------------------------------------------------------------------------*/
/*
* \fn int ctrl_set_cfg_mpeg_output()
* \brief Set MPEG output configuration of the device.
* \param devmod  Pointer to demodulator instance.
* \param cfg_data Pointer to mpeg output configuaration.
* \return int.
*
*  Configure MPEG output parameters.
*
*/
static int
ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
{}

/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* MPEG Output Configuration Functions - end                                  */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* miscellaneous configurations - begin                           */
/*----------------------------------------------------------------------------*/

/*
* \fn int set_mpegtei_handling()
* \brief Activate MPEG TEI handling settings.
* \param devmod  Pointer to demodulator instance.
* \return int.
*
* This routine should be called during a set channel of QAM/VSB
*
*/
static int set_mpegtei_handling(struct drx_demod_instance *demod)
{}

/*----------------------------------------------------------------------------*/
/*
* \fn int bit_reverse_mpeg_output()
* \brief Set MPEG output bit-endian settings.
* \param devmod  Pointer to demodulator instance.
* \return int.
*
* This routine should be called during a set channel of QAM/VSB
*
*/
static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
{}

/*----------------------------------------------------------------------------*/
/*
* \fn int set_mpeg_start_width()
* \brief Set MPEG start width.
* \param devmod  Pointer to demodulator instance.
* \return int.
*
* This routine should be called during a set channel of QAM/VSB
*
*/
static int set_mpeg_start_width(struct drx_demod_instance *demod)
{}

/*----------------------------------------------------------------------------*/
/* miscellaneous configurations - end                             */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* UIO Configuration Functions - begin                                        */
/*----------------------------------------------------------------------------*/
/*
* \fn int ctrl_set_uio_cfg()
* \brief Configure modus oprandi UIO.
* \param demod Pointer to demodulator instance.
* \param uio_cfg Pointer to a configuration setting for a certain UIO.
* \return int.
*/
static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
{}

/*
* \fn int ctrl_uio_write()
* \brief Write to a UIO.
* \param demod Pointer to demodulator instance.
* \param uio_data Pointer to data container for a certain UIO.
* \return int.
*/
static int
ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
{}

/*---------------------------------------------------------------------------*/
/* UIO Configuration Functions - end                                         */
/*---------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* I2C Bridge Functions - begin                                               */
/*----------------------------------------------------------------------------*/
/*
* \fn int ctrl_i2c_bridge()
* \brief Open or close the I2C switch to tuner.
* \param demod Pointer to demodulator instance.
* \param bridge_closed Pointer to bool indication if bridge is closed not.
* \return int.

*/
static int
ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
{}

/*----------------------------------------------------------------------------*/
/* I2C Bridge Functions - end                                                 */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* Smart antenna Functions - begin                                            */
/*----------------------------------------------------------------------------*/
/*
* \fn int smart_ant_init()
* \brief Initialize Smart Antenna.
* \param pointer to struct drx_demod_instance.
* \return int.
*
*/
static int smart_ant_init(struct drx_demod_instance *demod)
{}

static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
{}

/*
* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
* \brief Basic access routine for SCU atomic read or write access
* \param dev_addr  pointer to i2c dev address
* \param addr     destination/source address
* \param datasize size of data buffer in bytes
* \param data     pointer to data buffer
* \return int
* \retval 0 Success
* \retval -EIO Timeout, I2C error, illegal bank
*
*/
#define ADDR_AT_SCU_SPACE(x)
static
int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 addr, u16 datasize,	/* max 30 bytes because the limit of SCU parameter */
					      u8 *data, bool read_flag)
{}

/*============================================================================*/

/*
* \fn int DRXJ_DAP_AtomicReadReg16()
* \brief Atomic read of 16 bits words
*/
static
int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
					 u32 addr,
					 u16 *data, u32 flags)
{}

/*============================================================================*/
/*
* \fn int drxj_dap_scu_atomic_write_reg16()
* \brief Atomic read of 16 bits words
*/
static
int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
					  u32 addr,
					  u16 data, u32 flags)
{}

/* -------------------------------------------------------------------------- */
/*
* \brief Measure result of ADC synchronisation
* \param demod demod instance
* \param count (returned) count
* \return int.
* \retval 0    Success
* \retval -EIO Failure: I2C error
*
*/
static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
{}

/*
* \brief Synchronize analog and digital clock domains
* \param demod demod instance
* \return int.
* \retval 0    Success
* \retval -EIO Failure: I2C error or failure to synchronize
*
* An IQM reset will also reset the results of this synchronization.
* After an IQM reset this routine needs to be called again.
*
*/

static int adc_synchronization(struct drx_demod_instance *demod)
{}

/*============================================================================*/
/*==                      END AUXILIARY FUNCTIONS                           ==*/
/*============================================================================*/

/*============================================================================*/
/*============================================================================*/
/*==                8VSB & QAM COMMON DATAPATH FUNCTIONS                    ==*/
/*============================================================================*/
/*============================================================================*/
/*
* \fn int init_agc ()
* \brief Initialize AGC for all standards.
* \param demod instance of demodulator.
* \param channel pointer to channel data.
* \return int.
*/
static int init_agc(struct drx_demod_instance *demod)
{}

/*
* \fn int set_frequency ()
* \brief Set frequency shift.
* \param demod instance of demodulator.
* \param channel pointer to channel data.
* \param tuner_freq_offset residual frequency from tuner.
* \return int.
*/
static int
set_frequency(struct drx_demod_instance *demod,
	      struct drx_channel *channel, s32 tuner_freq_offset)
{}

/*
* \fn int get_acc_pkt_err()
* \brief Retrieve signal strength for VSB and QAM.
* \param demod Pointer to demod instance
* \param packet_err Pointer to packet error
* \return int.
* \retval 0 sig_strength contains valid data.
* \retval -EINVAL sig_strength is NULL.
* \retval -EIO Erroneous data, sig_strength contains invalid data.
*/
#ifdef DRXJ_SIGNAL_ACCUM_ERR
static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
{
	int rc;
	static u16 pkt_err;
	static u16 last_pkt_err;
	u16 data = 0;
	struct drxj_data *ext_attr = NULL;
	struct i2c_device_addr *dev_addr = NULL;

	ext_attr = (struct drxj_data *) demod->my_ext_attr;
	dev_addr = demod->my_i2c_dev_addr;

	rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
	if (rc != 0) {
		pr_err("error %d\n", rc);
		goto rw_error;
	}
	if (ext_attr->reset_pkt_err_acc) {
		last_pkt_err = data;
		pkt_err = 0;
		ext_attr->reset_pkt_err_acc = false;
	}

	if (data < last_pkt_err) {
		pkt_err += 0xffff - last_pkt_err;
		pkt_err += data;
	} else {
		pkt_err += (data - last_pkt_err);
	}
	*packet_err = pkt_err;
	last_pkt_err = data;

	return 0;
rw_error:
	return rc;
}
#endif


/*============================================================================*/

/*
* \fn int set_agc_rf ()
* \brief Configure RF AGC
* \param demod instance of demodulator.
* \param agc_settings AGC configuration structure
* \return int.
*/
static int
set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
{}

/*
* \fn int set_agc_if ()
* \brief Configure If AGC
* \param demod instance of demodulator.
* \param agc_settings AGC configuration structure
* \return int.
*/
static int
set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
{}

/*
* \fn int set_iqm_af ()
* \brief Configure IQM AF registers
* \param demod instance of demodulator.
* \param active
* \return int.
*/
static int set_iqm_af(struct drx_demod_instance *demod, bool active)
{}

/*============================================================================*/
/*==              END 8VSB & QAM COMMON DATAPATH FUNCTIONS                  ==*/
/*============================================================================*/

/*============================================================================*/
/*============================================================================*/
/*==                       8VSB DATAPATH FUNCTIONS                          ==*/
/*============================================================================*/
/*============================================================================*/

/*
* \fn int power_down_vsb ()
* \brief Powr down QAM related blocks.
* \param demod instance of demodulator.
* \param channel pointer to channel data.
* \return int.
*/
static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
{}

/*
* \fn int set_vsb_leak_n_gain ()
* \brief Set ATSC demod.
* \param demod instance of demodulator.
* \return int.
*/
static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
{}

/*
* \fn int set_vsb()
* \brief Set 8VSB demod.
* \param demod instance of demodulator.
* \return int.
*
*/
static int set_vsb(struct drx_demod_instance *demod)
{}

/*
* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
* \brief Get the values of packet error in 8VSB mode
* \return Error code
*/
static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
				   u32 *pck_errs, u32 *pck_count)
{}

/*
* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
* \brief Get the values of ber in VSB mode
* \return Error code
*/
static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
				    u32 *ber, u32 *cnt)
{}

/*
* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
* \brief Get the values of ber in VSB mode
* \return Error code
*/
static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
				   u32 *ber, u32 *cnt)
{}

/*
* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
* \brief Get the values of MER
* \return Error code
*/
static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
{}


/*============================================================================*/
/*==                     END 8VSB DATAPATH FUNCTIONS                        ==*/
/*============================================================================*/

/*============================================================================*/
/*============================================================================*/
/*==                       QAM DATAPATH FUNCTIONS                           ==*/
/*============================================================================*/
/*============================================================================*/

/*
* \fn int power_down_qam ()
* \brief Powr down QAM related blocks.
* \param demod instance of demodulator.
* \param channel pointer to channel data.
* \return int.
*/
static int power_down_qam(struct drx_demod_instance *demod, bool primary)
{}

/*============================================================================*/

/*
* \fn int set_qam_measurement ()
* \brief Setup of the QAM Measuremnt intervals for signal quality
* \param demod instance of demod.
* \param constellation current constellation.
* \return int.
*
*  NOTE:
*  Take into account that for certain settings the errorcounters can overflow.
*  The implementation does not check this.
*
*  TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
*  constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
*  field ?
*
*/
#ifndef DRXJ_VSB_ONLY
static int
set_qam_measurement(struct drx_demod_instance *demod,
		    enum drx_modulation constellation, u32 symbol_rate)
{}

/*============================================================================*/

/*
* \fn int set_qam16 ()
* \brief QAM16 specific setup
* \param demod instance of demod.
* \return int.
*/
static int set_qam16(struct drx_demod_instance *demod)
{}

/*============================================================================*/

/*
* \fn int set_qam32 ()
* \brief QAM32 specific setup
* \param demod instance of demod.
* \return int.
*/
static int set_qam32(struct drx_demod_instance *demod)
{}

/*============================================================================*/

/*
* \fn int set_qam64 ()
* \brief QAM64 specific setup
* \param demod instance of demod.
* \return int.
*/
static int set_qam64(struct drx_demod_instance *demod)
{}

/*============================================================================*/

/*
* \fn int set_qam128 ()
* \brief QAM128 specific setup
* \param demod: instance of demod.
* \return int.
*/
static int set_qam128(struct drx_demod_instance *demod)
{}

/*============================================================================*/

/*
* \fn int set_qam256 ()
* \brief QAM256 specific setup
* \param demod: instance of demod.
* \return int.
*/
static int set_qam256(struct drx_demod_instance *demod)
{}

/*============================================================================*/
#define QAM_SET_OP_ALL
#define QAM_SET_OP_CONSTELLATION
#define QAM_SET_OP_SPECTRUM

/*
* \fn int set_qam ()
* \brief Set QAM demod.
* \param demod:   instance of demod.
* \param channel: pointer to channel data.
* \return int.
*/
static int
set_qam(struct drx_demod_instance *demod,
	struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
{}

/*============================================================================*/
static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);

static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
{}

#define NO_LOCK
#define DEMOD_LOCKED
#define SYNC_FLIPPED
#define SPEC_MIRRORED
/*
* \fn int qam64auto ()
* \brief auto do sync pattern switching and mirroring.
* \param demod:   instance of demod.
* \param channel: pointer to channel data.
* \param tuner_freq_offset: tuner frequency offset.
* \param lock_status: pointer to lock status.
* \return int.
*/
static int
qam64auto(struct drx_demod_instance *demod,
	  struct drx_channel *channel,
	  s32 tuner_freq_offset, enum drx_lock_status *lock_status)
{}

/*
* \fn int qam256auto ()
* \brief auto do sync pattern switching and mirroring.
* \param demod:   instance of demod.
* \param channel: pointer to channel data.
* \param tuner_freq_offset: tuner frequency offset.
* \param lock_status: pointer to lock status.
* \return int.
*/
static int
qam256auto(struct drx_demod_instance *demod,
	   struct drx_channel *channel,
	   s32 tuner_freq_offset, enum drx_lock_status *lock_status)
{}

/*
* \fn int set_qam_channel ()
* \brief Set QAM channel according to the requested constellation.
* \param demod:   instance of demod.
* \param channel: pointer to channel data.
* \return int.
*/
static int
set_qam_channel(struct drx_demod_instance *demod,
	       struct drx_channel *channel, s32 tuner_freq_offset)
{}

/*============================================================================*/

/*
* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
* \brief Get RS error count in QAM mode (used for post RS BER calculation)
* \return Error code
*
* precondition: measurement period & measurement prescale must be set
*
*/
static int
get_qamrs_err_count(struct i2c_device_addr *dev_addr,
		    struct drxjrs_errors *rs_errors)
{}

/*============================================================================*/

/*
 * \fn int get_sig_strength()
 * \brief Retrieve signal strength for VSB and QAM.
 * \param demod Pointer to demod instance
 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
 * \return int.
 * \retval 0 sig_strength contains valid data.
 * \retval -EINVAL sig_strength is NULL.
 * \retval -EIO Erroneous data, sig_strength contains invalid data.
 */
#define DRXJ_AGC_TOP
#define DRXJ_AGC_SNS
#define DRXJ_RFAGC_MAX
#define DRXJ_RFAGC_MIN

static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
{}

/*
* \fn int ctrl_get_qam_sig_quality()
* \brief Retrieve QAM signal quality from device.
* \param devmod Pointer to demodulator instance.
* \param sig_quality Pointer to signal quality data.
* \return int.
* \retval 0 sig_quality contains valid data.
* \retval -EINVAL sig_quality is NULL.
* \retval -EIO Erroneous data, sig_quality contains invalid data.

*  Pre-condition: Device must be started and in lock.
*/
static int
ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
{}

#endif /* #ifndef DRXJ_VSB_ONLY */

/*============================================================================*/
/*==                     END QAM DATAPATH FUNCTIONS                         ==*/
/*============================================================================*/

/*============================================================================*/
/*============================================================================*/
/*==                       ATV DATAPATH FUNCTIONS                           ==*/
/*============================================================================*/
/*============================================================================*/

/*
   Implementation notes.

   NTSC/FM AGCs

      Four AGCs are used for NTSC:
      (1) RF (used to attenuate the input signal in case of to much power)
      (2) IF (used to attenuate the input signal in case of to much power)
      (3) Video AGC (used to amplify the output signal in case input to low)
      (4) SIF AGC (used to amplify the output signal in case input to low)

      Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
      that the coupling between Video AGC and the RF and IF AGCs also works in
      favor of the SIF AGC.

      Three AGCs are used for FM:
      (1) RF (used to attenuate the input signal in case of to much power)
      (2) IF (used to attenuate the input signal in case of to much power)
      (3) SIF AGC (used to amplify the output signal in case input to low)

      The SIF AGC is now coupled to the RF/IF AGCs.
      The SIF AGC is needed for both SIF output and the internal SIF signal to
      the AUD block.

      RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
      the ATV block. The AGC control algorithms are all implemented in
      microcode.

   ATV SETTINGS

      (Shadow settings will not be used for now, they will be implemented
       later on because of the schedule)

      Several HW/SCU "settings" can be used for ATV. The standard selection
      will reset most of these settings. To avoid that the end user application
      has to perform these settings each time the ATV or FM standards is
      selected the driver will shadow these settings. This enables the end user
      to perform the settings only once after a drx_open(). The driver must
      write the shadow settings to HW/SCU in case:
	 ( setstandard FM/ATV) ||
	 ( settings have changed && FM/ATV standard is active)
      The shadow settings will be stored in the device specific data container.
      A set of flags will be defined to flag changes in shadow settings.
      A routine will be implemented to write all changed shadow settings to
      HW/SCU.

      The "settings" will consist of: AGC settings, filter settings etc.

      Disadvantage of use of shadow settings:
      Direct changes in HW/SCU registers will not be reflected in the
      shadow settings and these changes will be overwritten during a next
      update. This can happen during evaluation. This will not be a problem
      for normal customer usage.
*/
/* -------------------------------------------------------------------------- */

/*
* \fn int power_down_atv ()
* \brief Power down ATV.
* \param demod instance of demodulator
* \param standard either NTSC or FM (sub strandard for ATV )
* \return int.
*
*  Stops and thus resets ATV and IQM block
*  SIF and CVBS ADC are powered down
*  Calls audio power down
*/
static int
power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
{}

/*============================================================================*/

/*
* \brief Power up AUD.
* \param demod instance of demodulator
* \return int.
*
*/
static int power_down_aud(struct drx_demod_instance *demod)
{}

/*
* \fn int set_orx_nsu_aox()
* \brief Configure OrxNsuAox for OOB
* \param demod instance of demodulator.
* \param active
* \return int.
*/
static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
{}

/*
* \fn int ctrl_set_oob()
* \brief Set OOB channel to be used.
* \param demod instance of demodulator
* \param oob_param OOB parameters for channel setting.
* \frequency should be in KHz
* \return int.
*
* Accepts  only. Returns error otherwise.
* Demapper value is written after scu_command START
* because START command causes COMM_EXEC transition
* from 0 to 1 which causes all registers to be
* overwritten with initial value
*
*/

/* Nyquist filter impulse response */
#define IMPULSE_COSINE_ALPHA_0_3
#define IMPULSE_COSINE_ALPHA_0_5
#define IMPULSE_COSINE_ALPHA_RO_0_5

/* Coefficients for the nyquist filter (total: 27 taps) */
#define NYQFILTERLEN

static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
{}

/*============================================================================*/
/*==                     END OOB DATAPATH FUNCTIONS                         ==*/
/*============================================================================*/

/*=============================================================================
  ===== MC command related functions ==========================================
  ===========================================================================*/

/*=============================================================================
  ===== ctrl_set_channel() ==========================================================
  ===========================================================================*/
/*
* \fn int ctrl_set_channel()
* \brief Select a new transmission channel.
* \param demod instance of demod.
* \param channel Pointer to channel data.
* \return int.
*
* In case the tuner module is not used and in case of NTSC/FM the pogrammer
* must tune the tuner to the centre frequency of the NTSC/FM channel.
*
*/
static int
ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
{}

/*=============================================================================
  ===== SigQuality() ==========================================================
  ===========================================================================*/

/*
* \fn int ctrl_sig_quality()
* \brief Retrieve signal quality form device.
* \param devmod Pointer to demodulator instance.
* \param sig_quality Pointer to signal quality data.
* \return int.
* \retval 0 sig_quality contains valid data.
* \retval -EINVAL sig_quality is NULL.
* \retval -EIO Erroneous data, sig_quality contains invalid data.

*/
static int
ctrl_sig_quality(struct drx_demod_instance *demod,
		 enum drx_lock_status lock_status)
{}

/*============================================================================*/

/*
* \fn int ctrl_lock_status()
* \brief Retrieve lock status .
* \param dev_addr Pointer to demodulator device address.
* \param lock_stat Pointer to lock status structure.
* \return int.
*
*/
static int
ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
{}

/*============================================================================*/

/*
* \fn int ctrl_set_standard()
* \brief Set modulation standard to be used.
* \param standard Modulation standard.
* \return int.
*
* Setup stuff for the desired demodulation standard.
* Disable and power down the previous selected demodulation standard
*
*/
static int
ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
{}

/*============================================================================*/

static void drxj_reset_mode(struct drxj_data *ext_attr)
{}

/*
* \fn int ctrl_power_mode()
* \brief Set the power mode of the device to the specified power mode
* \param demod Pointer to demodulator instance.
* \param mode  Pointer to new power mode.
* \return int.
* \retval 0          Success
* \retval -EIO       I2C error or other failure
* \retval -EINVAL Invalid mode argument.
*
*
*/
static int
ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
{}

/*============================================================================*/
/*== CTRL Set/Get Config related functions ===================================*/
/*============================================================================*/

/*
* \fn int ctrl_set_cfg_pre_saw()
* \brief Set Pre-saw reference.
* \param demod demod instance
* \param u16 *
* \return int.
*
* Check arguments
* Dispatch handling to standard specific function.
*
*/
static int
ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
{}

/*============================================================================*/

/*
* \fn int ctrl_set_cfg_afe_gain()
* \brief Set AFE Gain.
* \param demod demod instance
* \param u16 *
* \return int.
*
* Check arguments
* Dispatch handling to standard specific function.
*
*/
static int
ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
{}

/*============================================================================*/


/*=============================================================================
===== EXPORTED FUNCTIONS ====================================================*/

static int drx_ctrl_u_code(struct drx_demod_instance *demod,
		       struct drxu_code_info *mc_info,
		       enum drxu_code_action action);
static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);

/*
* \fn drxj_open()
* \brief Open the demod instance, configure device, configure drxdriver
* \return Status_t Return status.
*
* drxj_open() can be called with a NULL ucode image => no ucode upload.
* This means that drxj_open() must NOT contain SCU commands or, in general,
* rely on SCU or AUD ucode to be present.
*
*/

static int drxj_open(struct drx_demod_instance *demod)
{}

/*============================================================================*/
/*
* \fn drxj_close()
* \brief Close the demod instance, power down the device
* \return Status_t Return status.
*
*/
static int drxj_close(struct drx_demod_instance *demod)
{}

/*
 * Microcode related functions
 */

/*
 * drx_u_code_compute_crc	- Compute CRC of block of microcode data.
 * @block_data: Pointer to microcode data.
 * @nr_words:   Size of microcode block (number of 16 bits words).
 *
 * returns The computed CRC residue.
 */
static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
{}

/*
 * drx_check_firmware - checks if the loaded firmware is valid
 *
 * @demod:	demod structure
 * @mc_data:	pointer to the start of the firmware
 * @size:	firmware size
 */
static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
			  unsigned size)
{}

/*
 * drx_ctrl_u_code - Handle microcode upload or verify.
 * @dev_addr: Address of device.
 * @mc_info:  Pointer to information about microcode data.
 * @action:  Either UCODE_UPLOAD or UCODE_VERIFY
 *
 * This function returns:
 *	0:
 *		- In case of UCODE_UPLOAD: code is successfully uploaded.
 *               - In case of UCODE_VERIFY: image on device is equal to
 *		  image provided to this control function.
 *	-EIO:
 *		- In case of UCODE_UPLOAD: I2C error.
 *		- In case of UCODE_VERIFY: I2C error or image on device
 *		  is not equal to image provided to this control function.
 *	-EINVAL:
 *		- Invalid arguments.
 *		- Provided image is corrupt
 */
static int drx_ctrl_u_code(struct drx_demod_instance *demod,
		       struct drxu_code_info *mc_info,
		       enum drxu_code_action action)
{}

/* caller is expected to check if lna is supported before enabling */
static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
{}

/*
 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
 *
 * Written by Devin Heitmueller <[email protected]>
 */

static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
{}

static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
{}

static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
{}

static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
					 u16 *strength)
{}

static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
{}

static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
{}

static int drx39xxj_set_frontend(struct dvb_frontend *fe)
{}

static int drx39xxj_sleep(struct dvb_frontend *fe)
{}

static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{}

static int drx39xxj_init(struct dvb_frontend *fe)
{}

static int drx39xxj_set_lna(struct dvb_frontend *fe)
{}

static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
				      struct dvb_frontend_tune_settings *tune)
{}

static void drx39xxj_release(struct dvb_frontend *fe)
{}

static const struct dvb_frontend_ops drx39xxj_ops;

struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
{}
EXPORT_SYMBOL_GPL();

static const struct dvb_frontend_ops drx39xxj_ops =;

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_FIRMWARE();