linux/drivers/media/tuners/mt2063.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for mt2063 Micronas tuner
 *
 * Copyright (c) 2011 Mauro Carvalho Chehab
 *
 * This driver came from a driver originally written by:
 *		Henry Wang <[email protected]>
 * Made publicly available by Terratec, at:
 *	http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/videodev2.h>
#include <linux/gcd.h>

#include "mt2063.h"

static unsigned int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC();

#define dprintk(level, fmt, arg...)


/* positive error codes used internally */

/*  Info: Unavoidable LO-related spur may be present in the output  */
#define MT2063_SPUR_PRESENT_ERR

/*  Info: Mask of bits used for # of LO-related spurs that were avoided during tuning  */
#define MT2063_SPUR_CNT_MASK
#define MT2063_SPUR_SHIFT

/*  Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
#define MT2063_UPC_RANGE

/*  Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
#define MT2063_DNC_RANGE

/*
 *  Constant defining the version of the following structure
 *  and therefore the API for this code.
 *
 *  When compiling the tuner driver, the preprocessor will
 *  check against this version number to make sure that
 *  it matches the version that the tuner driver knows about.
 */

/* DECT Frequency Avoidance */
#define MT2063_DECT_AVOID_US_FREQS

#define MT2063_DECT_AVOID_EURO_FREQS

#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s)

#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s)

enum MT2063_DECT_Avoid_Type {};

#define MT2063_MAX_ZONES

struct MT2063_ExclZone_t {};

/*
 *  Structure of data needed for Spur Avoidance
 */
struct MT2063_AvoidSpursData_t {};

/*
 * Parameter for function MT2063_SetPowerMask that specifies the power down
 * of various sections of the MT2063.
 */
enum MT2063_Mask_Bits {};

/*
 *  Possible values for MT2063_DNC_OUTPUT
 */
enum MT2063_DNC_Output_Enable {};

/*
 *  Two-wire serial bus subaddresses of the tuner registers.
 *  Also known as the tuner's register addresses.
 */
enum MT2063_Register_Offsets {};

struct mt2063_state {};

/*
 * mt2063_write - Write data into the I2C bus
 */
static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
{}

/*
 * mt2063_write - Write register data into the I2C bus, caching the value
 */
static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
{}

/*
 * mt2063_read - Read data from the I2C bus
 */
static int mt2063_read(struct mt2063_state *state,
			   u8 subAddress, u8 *pData, u32 cnt)
{}

/*
 * FIXME: Is this really needed?
 */
static int MT2063_Sleep(struct dvb_frontend *fe)
{}

/*
 * Microtune spur avoidance
 */

/*  Implement ceiling, floor functions.  */
#define ceil(n, d)
#define floor(n, d)

struct MT2063_FIFZone_t {};

static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
					    *pAS_Info,
					    struct MT2063_ExclZone_t *pPrevNode)
{}

static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
					    *pAS_Info,
					    struct MT2063_ExclZone_t *pPrevNode,
					    struct MT2063_ExclZone_t
					    *pNodeToRemove)
{}

/*
 * MT_AddExclZone()
 *
 * Add (and merge) an exclusion zone into the list.
 * If the range (f_min, f_max) is totally outside the
 * 1st IF BW, ignore the entry.
 * If the range (f_min, f_max) is negative, ignore the entry.
 */
static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
			       u32 f_min, u32 f_max)
{}

/*
 *  Reset all exclusion zones.
 *  Add zones to protect the PLL FracN regions near zero
 */
static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
{}

/*
 * MT_ChooseFirstIF - Choose the best available 1st IF
 *                    If f_Desired is not excluded, choose that first.
 *                    Otherwise, return the value closest to f_Center that is
 *                    not excluded
 */
static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
{}

/**
 * IsSpurInBand() - Checks to see if a spur will be present within the IF's
 *                  bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
 *
 *                    ma   mb                                     mc   md
 *                  <--+-+-+-------------------+-------------------+-+-+-->
 *                     |   ^                   0                   ^   |
 *                     ^   b=-fIFOut+fIFBW/2      -b=+fIFOut-fIFBW/2   ^
 *                     a=-fIFOut-fIFBW/2              -a=+fIFOut+fIFBW/2
 *
 *                  Note that some equations are doubled to prevent round-off
 *                  problems when calculating fIFBW/2
 *
 * @pAS_Info:	Avoid Spurs information block
 * @fm:		If spur, amount f_IF1 has to move negative
 * @fp:		If spur, amount f_IF1 has to move positive
 *
 *  Returns 1 if an LO spur would be present, otherwise 0.
 */
static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
			u32 *fm, u32 * fp)
{}

/*
 * MT_AvoidSpurs() - Main entry point to avoid spurs.
 *                   Checks for existing spurs in present LO1, LO2 freqs
 *                   and if present, chooses spur-free LO1, LO2 combination
 *                   that tunes the same input/output frequencies.
 */
static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
{}

/*
 * Constants used by the tuning algorithm
 */
#define MT2063_REF_FREQ
#define MT2063_IF1_BW
#define MT2063_TUNE_STEP_SIZE
#define MT2063_SPUR_STEP_HZ
#define MT2063_ZIF_BW
#define MT2063_MAX_HARMONICS_1
#define MT2063_MAX_HARMONICS_2
#define MT2063_MIN_LO_SEP
#define MT2063_LO1_FRACN_AVOID
#define MT2063_LO2_FRACN_AVOID
#define MT2063_MIN_FIN_FREQ
#define MT2063_MAX_FIN_FREQ
#define MT2063_MIN_FOUT_FREQ
#define MT2063_MAX_FOUT_FREQ
#define MT2063_MIN_DNC_FREQ
#define MT2063_MAX_DNC_FREQ
#define MT2063_MIN_UPC_FREQ
#define MT2063_MAX_UPC_FREQ

/*
 *  Define the supported Part/Rev codes for the MT2063
 */
#define MT2063_B0
#define MT2063_B1
#define MT2063_B2
#define MT2063_B3

/**
 * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
 *
 * @state:	struct mt2063_state pointer
 *
 * This function returns 0, if no lock, 1 if locked and a value < 1 if error
 */
static int mt2063_lockStatus(struct mt2063_state *state)
{}

/*
 *  Constants for setting receiver modes.
 *  (6 modes defined at this time, enumerated by mt2063_delivery_sys)
 *  (DNC1GC & DNC2GC are the values, which are used, when the specific
 *   DNC Output is selected, the other is always off)
 *
 *                enum mt2063_delivery_sys
 * -------------+----------------------------------------------
 * Mode 0 :     | MT2063_CABLE_QAM
 * Mode 1 :     | MT2063_CABLE_ANALOG
 * Mode 2 :     | MT2063_OFFAIR_COFDM
 * Mode 3 :     | MT2063_OFFAIR_COFDM_SAWLESS
 * Mode 4 :     | MT2063_OFFAIR_ANALOG
 * Mode 5 :     | MT2063_OFFAIR_8VSB
 * --------------+----------------------------------------------
 *
 *                |<----------   Mode  -------------->|
 *    Reg Field   |  0  |  1  |  2  |  3  |  4  |  5  |
 *    ------------+-----+-----+-----+-----+-----+-----+
 *    RFAGCen     | OFF | OFF | OFF | OFF | OFF | OFF
 *    LNARin      |   0 |   0 |   3 |   3 |  3  |  3
 *    FIFFQen     |   1 |   1 |   1 |   1 |  1  |  1
 *    FIFFq       |   0 |   0 |   0 |   0 |  0  |  0
 *    DNC1gc      |   0 |   0 |   0 |   0 |  0  |  0
 *    DNC2gc      |   0 |   0 |   0 |   0 |  0  |  0
 *    GCU Auto    |   1 |   1 |   1 |   1 |  1  |  1
 *    LNA max Atn |  31 |  31 |  31 |  31 | 31  | 31
 *    LNA Target  |  44 |  43 |  43 |  43 | 43  | 43
 *    ign  RF Ovl |   0 |   0 |   0 |   0 |  0  |  0
 *    RF  max Atn |  31 |  31 |  31 |  31 | 31  | 31
 *    PD1 Target  |  36 |  36 |  38 |  38 | 36  | 38
 *    ign FIF Ovl |   0 |   0 |   0 |   0 |  0  |  0
 *    FIF max Atn |   5 |   5 |   5 |   5 |  5  |  5
 *    PD2 Target  |  40 |  33 |  42 |  42 | 33  | 42
 */

enum mt2063_delivery_sys {};

static const char *mt2063_mode_name[] =;

static const u8 RFAGCEN[]	=;
static const u8 LNARIN[]	=;
static const u8 FIFFQEN[]	=;
static const u8 FIFFQ[]		=;
static const u8 DNC1GC[]	=;
static const u8 DNC2GC[]	=;
static const u8 ACLNAMAX[]	=;
static const u8 LNATGT[]	=;
static const u8 RFOVDIS[]	=;
static const u8 ACRFMAX[]	=;
static const u8 PD1TGT[]	=;
static const u8 FIFOVDIS[]	=;
static const u8 ACFIFMAX[]	=;
static const u8 PD2TGT[]	=;

/*
 * mt2063_set_dnc_output_enable()
 */
static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
					enum MT2063_DNC_Output_Enable *pValue)
{}

/*
 * mt2063_set_dnc_output_enable()
 */
static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
					enum MT2063_DNC_Output_Enable nValue)
{}

/*
 * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
 *			      the selected enum mt2063_delivery_sys type.
 *
 *  (DNC1GC & DNC2GC are the values, which are used, when the specific
 *   DNC Output is selected, the other is always off)
 *
 * @state:	ptr to mt2063_state structure
 * @Mode:	desired receiver delivery system
 *
 * Note: Register cache must be valid for it to work
 */

static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
				  enum mt2063_delivery_sys Mode)
{}

/*
 * MT2063_ClearPowerMaskBits () - Clears the power-down mask bits for various
 *				  sections of the MT2063
 *
 * @Bits:		Mask bits to be cleared.
 *
 * See definition of MT2063_Mask_Bits type for description
 * of each of the power bits.
 */
static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
				     enum MT2063_Mask_Bits Bits)
{}

/*
 * MT2063_SoftwareShutdown() - Enables or disables software shutdown function.
 *			       When Shutdown is 1, any section whose power
 *			       mask is set will be shutdown.
 */
static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
{}

static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
{}

/**
 * MT2063_fLO_FractionalTerm - Calculates the portion contributed by FracN / denom.
 *                        This function preserves maximum precision without
 *                        risk of overflow.  It accurately calculates
 *                        f_ref * num / denom to within 1 HZ with fixed math.
 *
 * @f_ref:	SRO frequency.
 * @num:	Fractional portion of the multiplier
 * @denom:	denominator portion of the ratio
 *
 * This calculation handles f_ref as two separate 14-bit fields.
 * Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
 * This is the genesis of the magic number "14" and the magic mask value of
 * 0x03FFF.
 *
 * This routine successfully handles denom values up to and including 2^18.
 *  Returns:        f_ref * num / denom
 */
static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
{}

/*
 * MT2063_CalcLO1Mult - Calculates Integer divider value and the numerator
 *                value for a FracN PLL.
 *
 *                This function assumes that the f_LO and f_Ref are
 *                evenly divisible by f_LO_Step.
 *
 * @Div:	OUTPUT: Whole number portion of the multiplier
 * @FracN:	OUTPUT: Fractional portion of the multiplier
 * @f_LO:	desired LO frequency.
 * @f_LO_Step:	Minimum step size for the LO (in Hz).
 * @f_Ref:	SRO frequency.
 * @f_Avoid:	Range of PLL frequencies to avoid near integer multiples
 *		of f_Ref (in Hz).
 *
 * Returns:        Recalculated LO frequency.
 */
static u32 MT2063_CalcLO1Mult(u32 *Div,
			      u32 *FracN,
			      u32 f_LO,
			      u32 f_LO_Step, u32 f_Ref)
{}

/**
 * MT2063_CalcLO2Mult - Calculates Integer divider value and the numerator
 *                 value for a FracN PLL.
 *
 *                  This function assumes that the f_LO and f_Ref are
 *                  evenly divisible by f_LO_Step.
 *
 * @Div:	OUTPUT: Whole number portion of the multiplier
 * @FracN:	OUTPUT: Fractional portion of the multiplier
 * @f_LO:	desired LO frequency.
 * @f_LO_Step:	Minimum step size for the LO (in Hz).
 * @f_Ref:	SRO frequency.
 *
 * Returns: Recalculated LO frequency.
 */
static u32 MT2063_CalcLO2Mult(u32 *Div,
			      u32 *FracN,
			      u32 f_LO,
			      u32 f_LO_Step, u32 f_Ref)
{}

/*
 * FindClearTuneFilter() - Calculate the corrrect ClearTune filter to be
 *			   used for a given input frequency.
 *
 * @state:	ptr to tuner data structure
 * @f_in:	RF input center frequency (in Hz).
 *
 * Returns: ClearTune filter number (0-31)
 */
static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
{}

/*
 * MT2063_Tune() - Change the tuner's tuned frequency to RFin.
 */
static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
{}

static const u8 MT2063B0_defaults[] =;

/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
static const u8 MT2063B1_defaults[] =;

/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
static const u8 MT2063B3_defaults[] =;

static int mt2063_init(struct dvb_frontend *fe)
{}

static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
{}

static void mt2063_release(struct dvb_frontend *fe)
{}

static int mt2063_set_analog_params(struct dvb_frontend *fe,
				    struct analog_parameters *params)
{}

/*
 * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
 * So, the amount of the needed bandwidth is given by:
 *	Bw = Symbol_rate * (1 + 0.15)
 * As such, the maximum symbol rate supported by 6 MHz is given by:
 *	max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
 */
#define MAX_SYMBOL_RATE_6MHz

static int mt2063_set_params(struct dvb_frontend *fe)
{}

static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
{}

static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
{}

static const struct dvb_tuner_ops mt2063_ops =;

struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
				   struct mt2063_config *config,
				   struct i2c_adapter *i2c)
{}
EXPORT_SYMBOL_GPL();

#if 0
/*
 * Ancillary routines visible outside mt2063
 * FIXME: Remove them in favor of using standard tuner callbacks
 */
static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
{
	struct mt2063_state *state = fe->tuner_priv;
	int err = 0;

	dprintk(2, "\n");

	err = MT2063_SoftwareShutdown(state, 1);
	if (err < 0)
		printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);

	return err;
}

static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
{
	struct mt2063_state *state = fe->tuner_priv;
	int err = 0;

	dprintk(2, "\n");

	err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
	if (err < 0)
		printk(KERN_ERR "%s: Invalid parameter\n", __func__);

	return err;
}
#endif

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