cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tda18271c2dd.c (29140B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * tda18271c2dd: Driver for the TDA18271C2 tuner
      4 *
      5 * Copyright (C) 2010 Digital Devices GmbH
      6 */
      7
      8#include <linux/kernel.h>
      9#include <linux/module.h>
     10#include <linux/init.h>
     11#include <linux/delay.h>
     12#include <linux/firmware.h>
     13#include <linux/i2c.h>
     14#include <asm/div64.h>
     15
     16#include <media/dvb_frontend.h>
     17#include "tda18271c2dd.h"
     18
     19/* Max transfer size done by I2C transfer functions */
     20#define MAX_XFER_SIZE  64
     21
     22struct SStandardParam {
     23	s32   m_IFFrequency;
     24	u32   m_BandWidth;
     25	u8    m_EP3_4_0;
     26	u8    m_EB22;
     27};
     28
     29struct SMap {
     30	u32   m_Frequency;
     31	u8    m_Param;
     32};
     33
     34struct SMapI {
     35	u32   m_Frequency;
     36	s32    m_Param;
     37};
     38
     39struct SMap2 {
     40	u32   m_Frequency;
     41	u8    m_Param1;
     42	u8    m_Param2;
     43};
     44
     45struct SRFBandMap {
     46	u32   m_RF_max;
     47	u32   m_RF1_Default;
     48	u32   m_RF2_Default;
     49	u32   m_RF3_Default;
     50};
     51
     52enum ERegister {
     53	ID = 0,
     54	TM,
     55	PL,
     56	EP1, EP2, EP3, EP4, EP5,
     57	CPD, CD1, CD2, CD3,
     58	MPD, MD1, MD2, MD3,
     59	EB1, EB2, EB3, EB4, EB5, EB6, EB7, EB8, EB9, EB10,
     60	EB11, EB12, EB13, EB14, EB15, EB16, EB17, EB18, EB19, EB20,
     61	EB21, EB22, EB23,
     62	NUM_REGS
     63};
     64
     65struct tda_state {
     66	struct i2c_adapter *i2c;
     67	u8 adr;
     68
     69	u32   m_Frequency;
     70	u32   IF;
     71
     72	u8    m_IFLevelAnalog;
     73	u8    m_IFLevelDigital;
     74	u8    m_IFLevelDVBC;
     75	u8    m_IFLevelDVBT;
     76
     77	u8    m_EP4;
     78	u8    m_EP3_Standby;
     79
     80	bool  m_bMaster;
     81
     82	s32   m_SettlingTime;
     83
     84	u8    m_Regs[NUM_REGS];
     85
     86	/* Tracking filter settings for band 0..6 */
     87	u32   m_RF1[7];
     88	s32   m_RF_A1[7];
     89	s32   m_RF_B1[7];
     90	u32   m_RF2[7];
     91	s32   m_RF_A2[7];
     92	s32   m_RF_B2[7];
     93	u32   m_RF3[7];
     94
     95	u8    m_TMValue_RFCal;    /* Calibration temperature */
     96
     97	bool  m_bFMInput;         /* true to use Pin 8 for FM Radio */
     98
     99};
    100
    101static int PowerScan(struct tda_state *state,
    102		     u8 RFBand, u32 RF_in,
    103		     u32 *pRF_Out, bool *pbcal);
    104
    105static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len)
    106{
    107	struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
    108				   .buf  = data, .len   = len} };
    109	return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
    110}
    111
    112static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
    113{
    114	struct i2c_msg msg = {.addr = adr, .flags = 0,
    115			      .buf = data, .len = len};
    116
    117	if (i2c_transfer(adap, &msg, 1) != 1) {
    118		printk(KERN_ERR "tda18271c2dd: i2c write error at addr %i\n", adr);
    119		return -1;
    120	}
    121	return 0;
    122}
    123
    124static int WriteRegs(struct tda_state *state,
    125		     u8 SubAddr, u8 *Regs, u16 nRegs)
    126{
    127	u8 data[MAX_XFER_SIZE];
    128
    129	if (1 + nRegs > sizeof(data)) {
    130		printk(KERN_WARNING
    131		       "%s: i2c wr: len=%d is too big!\n",
    132		       KBUILD_MODNAME, nRegs);
    133		return -EINVAL;
    134	}
    135
    136	data[0] = SubAddr;
    137	memcpy(data + 1, Regs, nRegs);
    138	return i2c_write(state->i2c, state->adr, data, nRegs + 1);
    139}
    140
    141static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg)
    142{
    143	u8 msg[2] = {SubAddr, Reg};
    144
    145	return i2c_write(state->i2c, state->adr, msg, 2);
    146}
    147
    148static int Read(struct tda_state *state, u8 * Regs)
    149{
    150	return i2c_readn(state->i2c, state->adr, Regs, 16);
    151}
    152
    153static int ReadExtented(struct tda_state *state, u8 * Regs)
    154{
    155	return i2c_readn(state->i2c, state->adr, Regs, NUM_REGS);
    156}
    157
    158static int UpdateRegs(struct tda_state *state, u8 RegFrom, u8 RegTo)
    159{
    160	return WriteRegs(state, RegFrom,
    161			 &state->m_Regs[RegFrom], RegTo-RegFrom+1);
    162}
    163static int UpdateReg(struct tda_state *state, u8 Reg)
    164{
    165	return WriteReg(state, Reg, state->m_Regs[Reg]);
    166}
    167
    168#include "tda18271c2dd_maps.h"
    169
    170static void reset(struct tda_state *state)
    171{
    172	u32   ulIFLevelAnalog = 0;
    173	u32   ulIFLevelDigital = 2;
    174	u32   ulIFLevelDVBC = 7;
    175	u32   ulIFLevelDVBT = 6;
    176	u32   ulXTOut = 0;
    177	u32   ulStandbyMode = 0x06;    /* Send in stdb, but leave osc on */
    178	u32   ulSlave = 0;
    179	u32   ulFMInput = 0;
    180	u32   ulSettlingTime = 100;
    181
    182	state->m_Frequency         = 0;
    183	state->m_SettlingTime = 100;
    184	state->m_IFLevelAnalog = (ulIFLevelAnalog & 0x07) << 2;
    185	state->m_IFLevelDigital = (ulIFLevelDigital & 0x07) << 2;
    186	state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07) << 2;
    187	state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07) << 2;
    188
    189	state->m_EP4 = 0x20;
    190	if (ulXTOut != 0)
    191		state->m_EP4 |= 0x40;
    192
    193	state->m_EP3_Standby = ((ulStandbyMode & 0x07) << 5) | 0x0F;
    194	state->m_bMaster = (ulSlave == 0);
    195
    196	state->m_SettlingTime = ulSettlingTime;
    197
    198	state->m_bFMInput = (ulFMInput == 2);
    199}
    200
    201static bool SearchMap1(const struct SMap map[], u32 frequency, u8 *param)
    202{
    203	int i = 0;
    204
    205	while ((map[i].m_Frequency != 0) && (frequency > map[i].m_Frequency))
    206		i += 1;
    207	if (map[i].m_Frequency == 0)
    208		return false;
    209	*param = map[i].m_Param;
    210	return true;
    211}
    212
    213static bool SearchMap2(const struct SMapI map[], u32 frequency, s32 *param)
    214{
    215	int i = 0;
    216
    217	while ((map[i].m_Frequency != 0) &&
    218	       (frequency > map[i].m_Frequency))
    219		i += 1;
    220	if (map[i].m_Frequency == 0)
    221		return false;
    222	*param = map[i].m_Param;
    223	return true;
    224}
    225
    226static bool SearchMap3(const struct SMap2 map[], u32 frequency, u8 *param1,
    227		       u8 *param2)
    228{
    229	int i = 0;
    230
    231	while ((map[i].m_Frequency != 0) &&
    232	       (frequency > map[i].m_Frequency))
    233		i += 1;
    234	if (map[i].m_Frequency == 0)
    235		return false;
    236	*param1 = map[i].m_Param1;
    237	*param2 = map[i].m_Param2;
    238	return true;
    239}
    240
    241static bool SearchMap4(const struct SRFBandMap map[], u32 frequency, u8 *rfband)
    242{
    243	int i = 0;
    244
    245	while (i < 7 && (frequency > map[i].m_RF_max))
    246		i += 1;
    247	if (i == 7)
    248		return false;
    249	*rfband = i;
    250	return true;
    251}
    252
    253static int ThermometerRead(struct tda_state *state, u8 *pTM_Value)
    254{
    255	int status = 0;
    256
    257	do {
    258		u8 Regs[16];
    259		state->m_Regs[TM] |= 0x10;
    260		status = UpdateReg(state, TM);
    261		if (status < 0)
    262			break;
    263		status = Read(state, Regs);
    264		if (status < 0)
    265			break;
    266		if (((Regs[TM] & 0x0F) == 0 && (Regs[TM] & 0x20) == 0x20) ||
    267		    ((Regs[TM] & 0x0F) == 8 && (Regs[TM] & 0x20) == 0x00)) {
    268			state->m_Regs[TM] ^= 0x20;
    269			status = UpdateReg(state, TM);
    270			if (status < 0)
    271				break;
    272			msleep(10);
    273			status = Read(state, Regs);
    274			if (status < 0)
    275				break;
    276		}
    277		*pTM_Value = (Regs[TM] & 0x20)
    278				? m_Thermometer_Map_2[Regs[TM] & 0x0F]
    279				: m_Thermometer_Map_1[Regs[TM] & 0x0F] ;
    280		state->m_Regs[TM] &= ~0x10;        /* Thermometer off */
    281		status = UpdateReg(state, TM);
    282		if (status < 0)
    283			break;
    284		state->m_Regs[EP4] &= ~0x03;       /* CAL_mode = 0 ????????? */
    285		status = UpdateReg(state, EP4);
    286		if (status < 0)
    287			break;
    288	} while (0);
    289
    290	return status;
    291}
    292
    293static int StandBy(struct tda_state *state)
    294{
    295	int status = 0;
    296	do {
    297		state->m_Regs[EB12] &= ~0x20;  /* PD_AGC1_Det = 0 */
    298		status = UpdateReg(state, EB12);
    299		if (status < 0)
    300			break;
    301		state->m_Regs[EB18] &= ~0x83;  /* AGC1_loop_off = 0, AGC1_Gain = 6 dB */
    302		status = UpdateReg(state, EB18);
    303		if (status < 0)
    304			break;
    305		state->m_Regs[EB21] |= 0x03; /* AGC2_Gain = -6 dB */
    306		state->m_Regs[EP3] = state->m_EP3_Standby;
    307		status = UpdateReg(state, EP3);
    308		if (status < 0)
    309			break;
    310		state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LP_Fc[2] = 0 */
    311		status = UpdateRegs(state, EB21, EB23);
    312		if (status < 0)
    313			break;
    314	} while (0);
    315	return status;
    316}
    317
    318static int CalcMainPLL(struct tda_state *state, u32 freq)
    319{
    320
    321	u8  PostDiv;
    322	u8  Div;
    323	u64 OscFreq;
    324	u32 MainDiv;
    325
    326	if (!SearchMap3(m_Main_PLL_Map, freq, &PostDiv, &Div))
    327		return -EINVAL;
    328
    329	OscFreq = (u64) freq * (u64) Div;
    330	OscFreq *= (u64) 16384;
    331	do_div(OscFreq, (u64)16000000);
    332	MainDiv = OscFreq;
    333
    334	state->m_Regs[MPD] = PostDiv & 0x77;
    335	state->m_Regs[MD1] = ((MainDiv >> 16) & 0x7F);
    336	state->m_Regs[MD2] = ((MainDiv >>  8) & 0xFF);
    337	state->m_Regs[MD3] = (MainDiv & 0xFF);
    338
    339	return UpdateRegs(state, MPD, MD3);
    340}
    341
    342static int CalcCalPLL(struct tda_state *state, u32 freq)
    343{
    344	u8 PostDiv;
    345	u8 Div;
    346	u64 OscFreq;
    347	u32 CalDiv;
    348
    349	if (!SearchMap3(m_Cal_PLL_Map, freq, &PostDiv, &Div))
    350		return -EINVAL;
    351
    352	OscFreq = (u64)freq * (u64)Div;
    353	/* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
    354	OscFreq *= (u64)16384;
    355	do_div(OscFreq, (u64)16000000);
    356	CalDiv = OscFreq;
    357
    358	state->m_Regs[CPD] = PostDiv;
    359	state->m_Regs[CD1] = ((CalDiv >> 16) & 0xFF);
    360	state->m_Regs[CD2] = ((CalDiv >>  8) & 0xFF);
    361	state->m_Regs[CD3] = (CalDiv & 0xFF);
    362
    363	return UpdateRegs(state, CPD, CD3);
    364}
    365
    366static int CalibrateRF(struct tda_state *state,
    367		       u8 RFBand, u32 freq, s32 *pCprog)
    368{
    369	int status = 0;
    370	u8 Regs[NUM_REGS];
    371	do {
    372		u8 BP_Filter = 0;
    373		u8 GainTaper = 0;
    374		u8 RFC_K = 0;
    375		u8 RFC_M = 0;
    376
    377		state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 */
    378		status = UpdateReg(state, EP4);
    379		if (status < 0)
    380			break;
    381		state->m_Regs[EB18] |= 0x03;  /* AGC1_Gain = 3 */
    382		status = UpdateReg(state, EB18);
    383		if (status < 0)
    384			break;
    385
    386		/* Switching off LT (as datasheet says) causes calibration on C1 to fail */
    387		/* (Readout of Cprog is always 255) */
    388		if (state->m_Regs[ID] != 0x83)    /* C1: ID == 83, C2: ID == 84 */
    389			state->m_Regs[EP3] |= 0x40; /* SM_LT = 1 */
    390
    391		if (!(SearchMap1(m_BP_Filter_Map, freq, &BP_Filter) &&
    392			SearchMap1(m_GainTaper_Map, freq, &GainTaper) &&
    393			SearchMap3(m_KM_Map, freq, &RFC_K, &RFC_M)))
    394			return -EINVAL;
    395
    396		state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | BP_Filter;
    397		state->m_Regs[EP2] = (RFBand << 5) | GainTaper;
    398
    399		state->m_Regs[EB13] = (state->m_Regs[EB13] & ~0x7C) | (RFC_K << 4) | (RFC_M << 2);
    400
    401		status = UpdateRegs(state, EP1, EP3);
    402		if (status < 0)
    403			break;
    404		status = UpdateReg(state, EB13);
    405		if (status < 0)
    406			break;
    407
    408		state->m_Regs[EB4] |= 0x20;    /* LO_ForceSrce = 1 */
    409		status = UpdateReg(state, EB4);
    410		if (status < 0)
    411			break;
    412
    413		state->m_Regs[EB7] |= 0x20;    /* CAL_ForceSrce = 1 */
    414		status = UpdateReg(state, EB7);
    415		if (status < 0)
    416			break;
    417
    418		state->m_Regs[EB14] = 0; /* RFC_Cprog = 0 */
    419		status = UpdateReg(state, EB14);
    420		if (status < 0)
    421			break;
    422
    423		state->m_Regs[EB20] &= ~0x20;  /* ForceLock = 0; */
    424		status = UpdateReg(state, EB20);
    425		if (status < 0)
    426			break;
    427
    428		state->m_Regs[EP4] |= 0x03;  /* CAL_Mode = 3 */
    429		status = UpdateRegs(state, EP4, EP5);
    430		if (status < 0)
    431			break;
    432
    433		status = CalcCalPLL(state, freq);
    434		if (status < 0)
    435			break;
    436		status = CalcMainPLL(state, freq + 1000000);
    437		if (status < 0)
    438			break;
    439
    440		msleep(5);
    441		status = UpdateReg(state, EP2);
    442		if (status < 0)
    443			break;
    444		status = UpdateReg(state, EP1);
    445		if (status < 0)
    446			break;
    447		status = UpdateReg(state, EP2);
    448		if (status < 0)
    449			break;
    450		status = UpdateReg(state, EP1);
    451		if (status < 0)
    452			break;
    453
    454		state->m_Regs[EB4] &= ~0x20;    /* LO_ForceSrce = 0 */
    455		status = UpdateReg(state, EB4);
    456		if (status < 0)
    457			break;
    458
    459		state->m_Regs[EB7] &= ~0x20;    /* CAL_ForceSrce = 0 */
    460		status = UpdateReg(state, EB7);
    461		if (status < 0)
    462			break;
    463		msleep(10);
    464
    465		state->m_Regs[EB20] |= 0x20;  /* ForceLock = 1; */
    466		status = UpdateReg(state, EB20);
    467		if (status < 0)
    468			break;
    469		msleep(60);
    470
    471		state->m_Regs[EP4] &= ~0x03;  /* CAL_Mode = 0 */
    472		state->m_Regs[EP3] &= ~0x40; /* SM_LT = 0 */
    473		state->m_Regs[EB18] &= ~0x03;  /* AGC1_Gain = 0 */
    474		status = UpdateReg(state, EB18);
    475		if (status < 0)
    476			break;
    477		status = UpdateRegs(state, EP3, EP4);
    478		if (status < 0)
    479			break;
    480		status = UpdateReg(state, EP1);
    481		if (status < 0)
    482			break;
    483
    484		status = ReadExtented(state, Regs);
    485		if (status < 0)
    486			break;
    487
    488		*pCprog = Regs[EB14];
    489
    490	} while (0);
    491	return status;
    492}
    493
    494static int RFTrackingFiltersInit(struct tda_state *state,
    495				 u8 RFBand)
    496{
    497	int status = 0;
    498
    499	u32   RF1 = m_RF_Band_Map[RFBand].m_RF1_Default;
    500	u32   RF2 = m_RF_Band_Map[RFBand].m_RF2_Default;
    501	u32   RF3 = m_RF_Band_Map[RFBand].m_RF3_Default;
    502	bool    bcal = false;
    503
    504	s32    Cprog_cal1 = 0;
    505	s32    Cprog_table1 = 0;
    506	s32    Cprog_cal2 = 0;
    507	s32    Cprog_table2 = 0;
    508	s32    Cprog_cal3 = 0;
    509	s32    Cprog_table3 = 0;
    510
    511	state->m_RF_A1[RFBand] = 0;
    512	state->m_RF_B1[RFBand] = 0;
    513	state->m_RF_A2[RFBand] = 0;
    514	state->m_RF_B2[RFBand] = 0;
    515
    516	do {
    517		status = PowerScan(state, RFBand, RF1, &RF1, &bcal);
    518		if (status < 0)
    519			break;
    520		if (bcal) {
    521			status = CalibrateRF(state, RFBand, RF1, &Cprog_cal1);
    522			if (status < 0)
    523				break;
    524		}
    525		SearchMap2(m_RF_Cal_Map, RF1, &Cprog_table1);
    526		if (!bcal)
    527			Cprog_cal1 = Cprog_table1;
    528		state->m_RF_B1[RFBand] = Cprog_cal1 - Cprog_table1;
    529		/* state->m_RF_A1[RF_Band] = ???? */
    530
    531		if (RF2 == 0)
    532			break;
    533
    534		status = PowerScan(state, RFBand, RF2, &RF2, &bcal);
    535		if (status < 0)
    536			break;
    537		if (bcal) {
    538			status = CalibrateRF(state, RFBand, RF2, &Cprog_cal2);
    539			if (status < 0)
    540				break;
    541		}
    542		SearchMap2(m_RF_Cal_Map, RF2, &Cprog_table2);
    543		if (!bcal)
    544			Cprog_cal2 = Cprog_table2;
    545
    546		state->m_RF_A1[RFBand] =
    547			(Cprog_cal2 - Cprog_table2 - Cprog_cal1 + Cprog_table1) /
    548			((s32)(RF2) - (s32)(RF1));
    549
    550		if (RF3 == 0)
    551			break;
    552
    553		status = PowerScan(state, RFBand, RF3, &RF3, &bcal);
    554		if (status < 0)
    555			break;
    556		if (bcal) {
    557			status = CalibrateRF(state, RFBand, RF3, &Cprog_cal3);
    558			if (status < 0)
    559				break;
    560		}
    561		SearchMap2(m_RF_Cal_Map, RF3, &Cprog_table3);
    562		if (!bcal)
    563			Cprog_cal3 = Cprog_table3;
    564		state->m_RF_A2[RFBand] = (Cprog_cal3 - Cprog_table3 - Cprog_cal2 + Cprog_table2) / ((s32)(RF3) - (s32)(RF2));
    565		state->m_RF_B2[RFBand] = Cprog_cal2 - Cprog_table2;
    566
    567	} while (0);
    568
    569	state->m_RF1[RFBand] = RF1;
    570	state->m_RF2[RFBand] = RF2;
    571	state->m_RF3[RFBand] = RF3;
    572
    573#if 0
    574	printk(KERN_ERR "tda18271c2dd: %s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __func__,
    575	       RFBand, RF1, state->m_RF_A1[RFBand], state->m_RF_B1[RFBand], RF2,
    576	       state->m_RF_A2[RFBand], state->m_RF_B2[RFBand], RF3);
    577#endif
    578
    579	return status;
    580}
    581
    582static int PowerScan(struct tda_state *state,
    583		     u8 RFBand, u32 RF_in, u32 *pRF_Out, bool *pbcal)
    584{
    585	int status = 0;
    586	do {
    587		u8   Gain_Taper = 0;
    588		s32  RFC_Cprog = 0;
    589		u8   CID_Target = 0;
    590		u8   CountLimit = 0;
    591		u32  freq_MainPLL;
    592		u8   Regs[NUM_REGS];
    593		u8   CID_Gain;
    594		s32  Count = 0;
    595		int  sign  = 1;
    596		bool wait = false;
    597
    598		if (!(SearchMap2(m_RF_Cal_Map, RF_in, &RFC_Cprog) &&
    599		      SearchMap1(m_GainTaper_Map, RF_in, &Gain_Taper) &&
    600		      SearchMap3(m_CID_Target_Map, RF_in, &CID_Target, &CountLimit))) {
    601
    602			printk(KERN_ERR "tda18271c2dd: %s Search map failed\n", __func__);
    603			return -EINVAL;
    604		}
    605
    606		state->m_Regs[EP2] = (RFBand << 5) | Gain_Taper;
    607		state->m_Regs[EB14] = (RFC_Cprog);
    608		status = UpdateReg(state, EP2);
    609		if (status < 0)
    610			break;
    611		status = UpdateReg(state, EB14);
    612		if (status < 0)
    613			break;
    614
    615		freq_MainPLL = RF_in + 1000000;
    616		status = CalcMainPLL(state, freq_MainPLL);
    617		if (status < 0)
    618			break;
    619		msleep(5);
    620		state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x03) | 1;    /* CAL_mode = 1 */
    621		status = UpdateReg(state, EP4);
    622		if (status < 0)
    623			break;
    624		status = UpdateReg(state, EP2);  /* Launch power measurement */
    625		if (status < 0)
    626			break;
    627		status = ReadExtented(state, Regs);
    628		if (status < 0)
    629			break;
    630		CID_Gain = Regs[EB10] & 0x3F;
    631		state->m_Regs[ID] = Regs[ID];  /* Chip version, (needed for C1 workaround in CalibrateRF) */
    632
    633		*pRF_Out = RF_in;
    634
    635		while (CID_Gain < CID_Target) {
    636			freq_MainPLL = RF_in + sign * Count + 1000000;
    637			status = CalcMainPLL(state, freq_MainPLL);
    638			if (status < 0)
    639				break;
    640			msleep(wait ? 5 : 1);
    641			wait = false;
    642			status = UpdateReg(state, EP2);  /* Launch power measurement */
    643			if (status < 0)
    644				break;
    645			status = ReadExtented(state, Regs);
    646			if (status < 0)
    647				break;
    648			CID_Gain = Regs[EB10] & 0x3F;
    649			Count += 200000;
    650
    651			if (Count < CountLimit * 100000)
    652				continue;
    653			if (sign < 0)
    654				break;
    655
    656			sign = -sign;
    657			Count = 200000;
    658			wait = true;
    659		}
    660		if (status < 0)
    661			break;
    662		if (CID_Gain >= CID_Target) {
    663			*pbcal = true;
    664			*pRF_Out = freq_MainPLL - 1000000;
    665		} else
    666			*pbcal = false;
    667	} while (0);
    668
    669	return status;
    670}
    671
    672static int PowerScanInit(struct tda_state *state)
    673{
    674	int status = 0;
    675	do {
    676		state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | 0x12;
    677		state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x1F); /* If level = 0, Cal mode = 0 */
    678		status = UpdateRegs(state, EP3, EP4);
    679		if (status < 0)
    680			break;
    681		state->m_Regs[EB18] = (state->m_Regs[EB18] & ~0x03); /* AGC 1 Gain = 0 */
    682		status = UpdateReg(state, EB18);
    683		if (status < 0)
    684			break;
    685		state->m_Regs[EB21] = (state->m_Regs[EB21] & ~0x03); /* AGC 2 Gain = 0 (Datasheet = 3) */
    686		state->m_Regs[EB23] = (state->m_Regs[EB23] | 0x06); /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
    687		status = UpdateRegs(state, EB21, EB23);
    688		if (status < 0)
    689			break;
    690	} while (0);
    691	return status;
    692}
    693
    694static int CalcRFFilterCurve(struct tda_state *state)
    695{
    696	int status = 0;
    697	do {
    698		msleep(200);      /* Temperature stabilisation */
    699		status = PowerScanInit(state);
    700		if (status < 0)
    701			break;
    702		status = RFTrackingFiltersInit(state, 0);
    703		if (status < 0)
    704			break;
    705		status = RFTrackingFiltersInit(state, 1);
    706		if (status < 0)
    707			break;
    708		status = RFTrackingFiltersInit(state, 2);
    709		if (status < 0)
    710			break;
    711		status = RFTrackingFiltersInit(state, 3);
    712		if (status < 0)
    713			break;
    714		status = RFTrackingFiltersInit(state, 4);
    715		if (status < 0)
    716			break;
    717		status = RFTrackingFiltersInit(state, 5);
    718		if (status < 0)
    719			break;
    720		status = RFTrackingFiltersInit(state, 6);
    721		if (status < 0)
    722			break;
    723		status = ThermometerRead(state, &state->m_TMValue_RFCal); /* also switches off Cal mode !!! */
    724		if (status < 0)
    725			break;
    726	} while (0);
    727
    728	return status;
    729}
    730
    731static int FixedContentsI2CUpdate(struct tda_state *state)
    732{
    733	static u8 InitRegs[] = {
    734		0x08, 0x80, 0xC6,
    735		0xDF, 0x16, 0x60, 0x80,
    736		0x80, 0x00, 0x00, 0x00,
    737		0x00, 0x00, 0x00, 0x00,
    738		0xFC, 0x01, 0x84, 0x41,
    739		0x01, 0x84, 0x40, 0x07,
    740		0x00, 0x00, 0x96, 0x3F,
    741		0xC1, 0x00, 0x8F, 0x00,
    742		0x00, 0x8C, 0x00, 0x20,
    743		0xB3, 0x48, 0xB0,
    744	};
    745	int status = 0;
    746	memcpy(&state->m_Regs[TM], InitRegs, EB23 - TM + 1);
    747	do {
    748		status = UpdateRegs(state, TM, EB23);
    749		if (status < 0)
    750			break;
    751
    752		/* AGC1 gain setup */
    753		state->m_Regs[EB17] = 0x00;
    754		status = UpdateReg(state, EB17);
    755		if (status < 0)
    756			break;
    757		state->m_Regs[EB17] = 0x03;
    758		status = UpdateReg(state, EB17);
    759		if (status < 0)
    760			break;
    761		state->m_Regs[EB17] = 0x43;
    762		status = UpdateReg(state, EB17);
    763		if (status < 0)
    764			break;
    765		state->m_Regs[EB17] = 0x4C;
    766		status = UpdateReg(state, EB17);
    767		if (status < 0)
    768			break;
    769
    770		/* IRC Cal Low band */
    771		state->m_Regs[EP3] = 0x1F;
    772		state->m_Regs[EP4] = 0x66;
    773		state->m_Regs[EP5] = 0x81;
    774		state->m_Regs[CPD] = 0xCC;
    775		state->m_Regs[CD1] = 0x6C;
    776		state->m_Regs[CD2] = 0x00;
    777		state->m_Regs[CD3] = 0x00;
    778		state->m_Regs[MPD] = 0xC5;
    779		state->m_Regs[MD1] = 0x77;
    780		state->m_Regs[MD2] = 0x08;
    781		state->m_Regs[MD3] = 0x00;
    782		status = UpdateRegs(state, EP2, MD3); /* diff between sw and datasheet (ep3-md3) */
    783		if (status < 0)
    784			break;
    785
    786#if 0
    787		state->m_Regs[EB4] = 0x61;          /* missing in sw */
    788		status = UpdateReg(state, EB4);
    789		if (status < 0)
    790			break;
    791		msleep(1);
    792		state->m_Regs[EB4] = 0x41;
    793		status = UpdateReg(state, EB4);
    794		if (status < 0)
    795			break;
    796#endif
    797
    798		msleep(5);
    799		status = UpdateReg(state, EP1);
    800		if (status < 0)
    801			break;
    802		msleep(5);
    803
    804		state->m_Regs[EP5] = 0x85;
    805		state->m_Regs[CPD] = 0xCB;
    806		state->m_Regs[CD1] = 0x66;
    807		state->m_Regs[CD2] = 0x70;
    808		status = UpdateRegs(state, EP3, CD3);
    809		if (status < 0)
    810			break;
    811		msleep(5);
    812		status = UpdateReg(state, EP2);
    813		if (status < 0)
    814			break;
    815		msleep(30);
    816
    817		/* IRC Cal mid band */
    818		state->m_Regs[EP5] = 0x82;
    819		state->m_Regs[CPD] = 0xA8;
    820		state->m_Regs[CD2] = 0x00;
    821		state->m_Regs[MPD] = 0xA1; /* Datasheet = 0xA9 */
    822		state->m_Regs[MD1] = 0x73;
    823		state->m_Regs[MD2] = 0x1A;
    824		status = UpdateRegs(state, EP3, MD3);
    825		if (status < 0)
    826			break;
    827
    828		msleep(5);
    829		status = UpdateReg(state, EP1);
    830		if (status < 0)
    831			break;
    832		msleep(5);
    833
    834		state->m_Regs[EP5] = 0x86;
    835		state->m_Regs[CPD] = 0xA8;
    836		state->m_Regs[CD1] = 0x66;
    837		state->m_Regs[CD2] = 0xA0;
    838		status = UpdateRegs(state, EP3, CD3);
    839		if (status < 0)
    840			break;
    841		msleep(5);
    842		status = UpdateReg(state, EP2);
    843		if (status < 0)
    844			break;
    845		msleep(30);
    846
    847		/* IRC Cal high band */
    848		state->m_Regs[EP5] = 0x83;
    849		state->m_Regs[CPD] = 0x98;
    850		state->m_Regs[CD1] = 0x65;
    851		state->m_Regs[CD2] = 0x00;
    852		state->m_Regs[MPD] = 0x91;  /* Datasheet = 0x91 */
    853		state->m_Regs[MD1] = 0x71;
    854		state->m_Regs[MD2] = 0xCD;
    855		status = UpdateRegs(state, EP3, MD3);
    856		if (status < 0)
    857			break;
    858		msleep(5);
    859		status = UpdateReg(state, EP1);
    860		if (status < 0)
    861			break;
    862		msleep(5);
    863		state->m_Regs[EP5] = 0x87;
    864		state->m_Regs[CD1] = 0x65;
    865		state->m_Regs[CD2] = 0x50;
    866		status = UpdateRegs(state, EP3, CD3);
    867		if (status < 0)
    868			break;
    869		msleep(5);
    870		status = UpdateReg(state, EP2);
    871		if (status < 0)
    872			break;
    873		msleep(30);
    874
    875		/* Back to normal */
    876		state->m_Regs[EP4] = 0x64;
    877		status = UpdateReg(state, EP4);
    878		if (status < 0)
    879			break;
    880		status = UpdateReg(state, EP1);
    881		if (status < 0)
    882			break;
    883
    884	} while (0);
    885	return status;
    886}
    887
    888static int InitCal(struct tda_state *state)
    889{
    890	int status = 0;
    891
    892	do {
    893		status = FixedContentsI2CUpdate(state);
    894		if (status < 0)
    895			break;
    896		status = CalcRFFilterCurve(state);
    897		if (status < 0)
    898			break;
    899		status = StandBy(state);
    900		if (status < 0)
    901			break;
    902		/* m_bInitDone = true; */
    903	} while (0);
    904	return status;
    905};
    906
    907static int RFTrackingFiltersCorrection(struct tda_state *state,
    908				       u32 Frequency)
    909{
    910	int status = 0;
    911	s32 Cprog_table;
    912	u8 RFBand;
    913	u8 dCoverdT;
    914
    915	if (!SearchMap2(m_RF_Cal_Map, Frequency, &Cprog_table) ||
    916	    !SearchMap4(m_RF_Band_Map, Frequency, &RFBand) ||
    917	    !SearchMap1(m_RF_Cal_DC_Over_DT_Map, Frequency, &dCoverdT))
    918
    919		return -EINVAL;
    920
    921	do {
    922		u8 TMValue_Current;
    923		u32   RF1 = state->m_RF1[RFBand];
    924		u32   RF2 = state->m_RF1[RFBand];
    925		u32   RF3 = state->m_RF1[RFBand];
    926		s32    RF_A1 = state->m_RF_A1[RFBand];
    927		s32    RF_B1 = state->m_RF_B1[RFBand];
    928		s32    RF_A2 = state->m_RF_A2[RFBand];
    929		s32    RF_B2 = state->m_RF_B2[RFBand];
    930		s32 Capprox = 0;
    931		int TComp;
    932
    933		state->m_Regs[EP3] &= ~0xE0;  /* Power up */
    934		status = UpdateReg(state, EP3);
    935		if (status < 0)
    936			break;
    937
    938		status = ThermometerRead(state, &TMValue_Current);
    939		if (status < 0)
    940			break;
    941
    942		if (RF3 == 0 || Frequency < RF2)
    943			Capprox = RF_A1 * ((s32)(Frequency) - (s32)(RF1)) + RF_B1 + Cprog_table;
    944		else
    945			Capprox = RF_A2 * ((s32)(Frequency) - (s32)(RF2)) + RF_B2 + Cprog_table;
    946
    947		TComp = (int)(dCoverdT) * ((int)(TMValue_Current) - (int)(state->m_TMValue_RFCal))/1000;
    948
    949		Capprox += TComp;
    950
    951		if (Capprox < 0)
    952			Capprox = 0;
    953		else if (Capprox > 255)
    954			Capprox = 255;
    955
    956
    957		/* TODO Temperature compensation. There is defenitely a scale factor */
    958		/*      missing in the datasheet, so leave it out for now.           */
    959		state->m_Regs[EB14] = Capprox;
    960
    961		status = UpdateReg(state, EB14);
    962		if (status < 0)
    963			break;
    964
    965	} while (0);
    966	return status;
    967}
    968
    969static int ChannelConfiguration(struct tda_state *state,
    970				u32 Frequency, int Standard)
    971{
    972
    973	s32 IntermediateFrequency = m_StandardTable[Standard].m_IFFrequency;
    974	int status = 0;
    975
    976	u8 BP_Filter = 0;
    977	u8 RF_Band = 0;
    978	u8 GainTaper = 0;
    979	u8 IR_Meas = 0;
    980
    981	state->IF = IntermediateFrequency;
    982	/* printk("tda18271c2dd: %s Freq = %d Standard = %d IF = %d\n", __func__, Frequency, Standard, IntermediateFrequency); */
    983	/* get values from tables */
    984
    985	if (!(SearchMap1(m_BP_Filter_Map, Frequency, &BP_Filter) &&
    986	       SearchMap1(m_GainTaper_Map, Frequency, &GainTaper) &&
    987	       SearchMap1(m_IR_Meas_Map, Frequency, &IR_Meas) &&
    988	       SearchMap4(m_RF_Band_Map, Frequency, &RF_Band))) {
    989
    990		printk(KERN_ERR "tda18271c2dd: %s SearchMap failed\n", __func__);
    991		return -EINVAL;
    992	}
    993
    994	do {
    995		state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | m_StandardTable[Standard].m_EP3_4_0;
    996		state->m_Regs[EP3] &= ~0x04;   /* switch RFAGC to high speed mode */
    997
    998		/* m_EP4 default for XToutOn, CAL_Mode (0) */
    999		state->m_Regs[EP4] = state->m_EP4 | ((Standard > HF_AnalogMax) ? state->m_IFLevelDigital : state->m_IFLevelAnalog);
   1000		/* state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; */
   1001		if (Standard <= HF_AnalogMax)
   1002			state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelAnalog;
   1003		else if (Standard <= HF_ATSC)
   1004			state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBT;
   1005		else if (Standard <= HF_DVBC)
   1006			state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBC;
   1007		else
   1008			state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
   1009
   1010		if ((Standard == HF_FM_Radio) && state->m_bFMInput)
   1011			state->m_Regs[EP4] |= 0x80;
   1012
   1013		state->m_Regs[MPD] &= ~0x80;
   1014		if (Standard > HF_AnalogMax)
   1015			state->m_Regs[MPD] |= 0x80; /* Add IF_notch for digital */
   1016
   1017		state->m_Regs[EB22] = m_StandardTable[Standard].m_EB22;
   1018
   1019		/* Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM ) */
   1020		if (Standard == HF_FM_Radio)
   1021			state->m_Regs[EB23] |=  0x06; /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
   1022		else
   1023			state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LPFc[2] = 0 */
   1024
   1025		status = UpdateRegs(state, EB22, EB23);
   1026		if (status < 0)
   1027			break;
   1028
   1029		state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | 0x40 | BP_Filter;   /* Dis_Power_level = 1, Filter */
   1030		state->m_Regs[EP5] = (state->m_Regs[EP5] & ~0x07) | IR_Meas;
   1031		state->m_Regs[EP2] = (RF_Band << 5) | GainTaper;
   1032
   1033		state->m_Regs[EB1] = (state->m_Regs[EB1] & ~0x07) |
   1034			(state->m_bMaster ? 0x04 : 0x00); /* CALVCO_FortLOn = MS */
   1035		/* AGC1_always_master = 0 */
   1036		/* AGC_firstn = 0 */
   1037		status = UpdateReg(state, EB1);
   1038		if (status < 0)
   1039			break;
   1040
   1041		if (state->m_bMaster) {
   1042			status = CalcMainPLL(state, Frequency + IntermediateFrequency);
   1043			if (status < 0)
   1044				break;
   1045			status = UpdateRegs(state, TM, EP5);
   1046			if (status < 0)
   1047				break;
   1048			state->m_Regs[EB4] |= 0x20;    /* LO_forceSrce = 1 */
   1049			status = UpdateReg(state, EB4);
   1050			if (status < 0)
   1051				break;
   1052			msleep(1);
   1053			state->m_Regs[EB4] &= ~0x20;   /* LO_forceSrce = 0 */
   1054			status = UpdateReg(state, EB4);
   1055			if (status < 0)
   1056				break;
   1057		} else {
   1058			u8 PostDiv = 0;
   1059			u8 Div;
   1060			status = CalcCalPLL(state, Frequency + IntermediateFrequency);
   1061			if (status < 0)
   1062				break;
   1063
   1064			SearchMap3(m_Cal_PLL_Map, Frequency + IntermediateFrequency, &PostDiv, &Div);
   1065			state->m_Regs[MPD] = (state->m_Regs[MPD] & ~0x7F) | (PostDiv & 0x77);
   1066			status = UpdateReg(state, MPD);
   1067			if (status < 0)
   1068				break;
   1069			status = UpdateRegs(state, TM, EP5);
   1070			if (status < 0)
   1071				break;
   1072
   1073			state->m_Regs[EB7] |= 0x20;    /* CAL_forceSrce = 1 */
   1074			status = UpdateReg(state, EB7);
   1075			if (status < 0)
   1076				break;
   1077			msleep(1);
   1078			state->m_Regs[EB7] &= ~0x20;   /* CAL_forceSrce = 0 */
   1079			status = UpdateReg(state, EB7);
   1080			if (status < 0)
   1081				break;
   1082		}
   1083		msleep(20);
   1084		if (Standard != HF_FM_Radio)
   1085			state->m_Regs[EP3] |= 0x04;    /* RFAGC to normal mode */
   1086		status = UpdateReg(state, EP3);
   1087		if (status < 0)
   1088			break;
   1089
   1090	} while (0);
   1091	return status;
   1092}
   1093
   1094static int sleep(struct dvb_frontend *fe)
   1095{
   1096	struct tda_state *state = fe->tuner_priv;
   1097
   1098	StandBy(state);
   1099	return 0;
   1100}
   1101
   1102static int init(struct dvb_frontend *fe)
   1103{
   1104	return 0;
   1105}
   1106
   1107static void release(struct dvb_frontend *fe)
   1108{
   1109	kfree(fe->tuner_priv);
   1110	fe->tuner_priv = NULL;
   1111}
   1112
   1113
   1114static int set_params(struct dvb_frontend *fe)
   1115{
   1116	struct tda_state *state = fe->tuner_priv;
   1117	int status = 0;
   1118	int Standard;
   1119	u32 bw = fe->dtv_property_cache.bandwidth_hz;
   1120	u32 delsys  = fe->dtv_property_cache.delivery_system;
   1121
   1122	state->m_Frequency = fe->dtv_property_cache.frequency;
   1123
   1124	switch (delsys) {
   1125	case  SYS_DVBT:
   1126	case  SYS_DVBT2:
   1127		switch (bw) {
   1128		case 6000000:
   1129			Standard = HF_DVBT_6MHZ;
   1130			break;
   1131		case 7000000:
   1132			Standard = HF_DVBT_7MHZ;
   1133			break;
   1134		case 8000000:
   1135			Standard = HF_DVBT_8MHZ;
   1136			break;
   1137		default:
   1138			return -EINVAL;
   1139		}
   1140		break;
   1141	case SYS_DVBC_ANNEX_A:
   1142	case SYS_DVBC_ANNEX_C:
   1143		if (bw <= 6000000)
   1144			Standard = HF_DVBC_6MHZ;
   1145		else if (bw <= 7000000)
   1146			Standard = HF_DVBC_7MHZ;
   1147		else
   1148			Standard = HF_DVBC_8MHZ;
   1149		break;
   1150	default:
   1151		return -EINVAL;
   1152	}
   1153	do {
   1154		status = RFTrackingFiltersCorrection(state, state->m_Frequency);
   1155		if (status < 0)
   1156			break;
   1157		status = ChannelConfiguration(state, state->m_Frequency,
   1158					      Standard);
   1159		if (status < 0)
   1160			break;
   1161
   1162		msleep(state->m_SettlingTime);  /* Allow AGC's to settle down */
   1163	} while (0);
   1164	return status;
   1165}
   1166
   1167#if 0
   1168static int GetSignalStrength(s32 *pSignalStrength, u32 RFAgc, u32 IFAgc)
   1169{
   1170	if (IFAgc < 500) {
   1171		/* Scale this from 0 to 50000 */
   1172		*pSignalStrength = IFAgc * 100;
   1173	} else {
   1174		/* Scale range 500-1500 to 50000-80000 */
   1175		*pSignalStrength = 50000 + (IFAgc - 500) * 30;
   1176	}
   1177
   1178	return 0;
   1179}
   1180#endif
   1181
   1182static int get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
   1183{
   1184	struct tda_state *state = fe->tuner_priv;
   1185
   1186	*frequency = state->IF;
   1187	return 0;
   1188}
   1189
   1190static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
   1191{
   1192	/* struct tda_state *state = fe->tuner_priv; */
   1193	/* *bandwidth = priv->bandwidth; */
   1194	return 0;
   1195}
   1196
   1197
   1198static const struct dvb_tuner_ops tuner_ops = {
   1199	.info = {
   1200		.name = "NXP TDA18271C2D",
   1201		.frequency_min_hz  =  47125 * kHz,
   1202		.frequency_max_hz  =    865 * MHz,
   1203		.frequency_step_hz =  62500
   1204	},
   1205	.init              = init,
   1206	.sleep             = sleep,
   1207	.set_params        = set_params,
   1208	.release           = release,
   1209	.get_if_frequency  = get_if_frequency,
   1210	.get_bandwidth     = get_bandwidth,
   1211};
   1212
   1213struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
   1214					 struct i2c_adapter *i2c, u8 adr)
   1215{
   1216	struct tda_state *state;
   1217
   1218	state = kzalloc(sizeof(struct tda_state), GFP_KERNEL);
   1219	if (!state)
   1220		return NULL;
   1221
   1222	fe->tuner_priv = state;
   1223	state->adr = adr;
   1224	state->i2c = i2c;
   1225	memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops));
   1226	reset(state);
   1227	InitCal(state);
   1228
   1229	return fe;
   1230}
   1231EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
   1232
   1233MODULE_DESCRIPTION("TDA18271C2 driver");
   1234MODULE_AUTHOR("DD");
   1235MODULE_LICENSE("GPL");