^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");