Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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