blob: 7f526143ba406a463b40c84f9ae7fe2be8d1f25e [file] [log] [blame]
Ralph Metzlere8783952011-07-03 13:36:17 -03001/*
2 * tda18271c2dd: Driver for the TDA18271C2 tuner
3 *
4 * Copyright (C) 2010 Digital Devices GmbH
5 *
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 only, as published by the Free Software Foundation.
10 *
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA
22 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 */
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/firmware.h>
31#include <linux/i2c.h>
32#include <linux/version.h>
33#include <asm/div64.h>
34
35#include "dvb_frontend.h"
36
37struct SStandardParam {
38 s32 m_IFFrequency;
39 u32 m_BandWidth;
40 u8 m_EP3_4_0;
41 u8 m_EB22;
42};
43
44struct SMap {
45 u32 m_Frequency;
46 u8 m_Param;
47};
48
49struct SMapI {
50 u32 m_Frequency;
51 s32 m_Param;
52};
53
54struct SMap2 {
55 u32 m_Frequency;
56 u8 m_Param1;
57 u8 m_Param2;
58};
59
60struct SRFBandMap {
61 u32 m_RF_max;
62 u32 m_RF1_Default;
63 u32 m_RF2_Default;
64 u32 m_RF3_Default;
65};
66
Oliver Endriss0fe44622011-07-03 13:37:31 -030067enum ERegister {
Ralph Metzlere8783952011-07-03 13:36:17 -030068 ID = 0,
69 TM,
70 PL,
71 EP1, EP2, EP3, EP4, EP5,
72 CPD, CD1, CD2, CD3,
73 MPD, MD1, MD2, MD3,
74 EB1, EB2, EB3, EB4, EB5, EB6, EB7, EB8, EB9, EB10,
75 EB11, EB12, EB13, EB14, EB15, EB16, EB17, EB18, EB19, EB20,
76 EB21, EB22, EB23,
77 NUM_REGS
78};
79
80struct tda_state {
81 struct i2c_adapter *i2c;
82 u8 adr;
83
84 u32 m_Frequency;
85 u32 IF;
86
87 u8 m_IFLevelAnalog;
88 u8 m_IFLevelDigital;
89 u8 m_IFLevelDVBC;
90 u8 m_IFLevelDVBT;
91
92 u8 m_EP4;
93 u8 m_EP3_Standby;
94
95 bool m_bMaster;
96
97 s32 m_SettlingTime;
98
99 u8 m_Regs[NUM_REGS];
100
101 /* Tracking filter settings for band 0..6 */
102 u32 m_RF1[7];
103 s32 m_RF_A1[7];
104 s32 m_RF_B1[7];
105 u32 m_RF2[7];
106 s32 m_RF_A2[7];
107 s32 m_RF_B2[7];
108 u32 m_RF3[7];
109
110 u8 m_TMValue_RFCal; /* Calibration temperatur */
111
112 bool m_bFMInput; /* true to use Pin 8 for FM Radio */
113
114};
115
116static int PowerScan(struct tda_state *state,
Oliver Endriss0fe44622011-07-03 13:37:31 -0300117 u8 RFBand, u32 RF_in,
118 u32 *pRF_Out, bool *pbcal);
Ralph Metzlere8783952011-07-03 13:36:17 -0300119
120static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len)
121{
122 struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
Oliver Endriss0fe44622011-07-03 13:37:31 -0300123 .buf = data, .len = len} };
Ralph Metzlere8783952011-07-03 13:36:17 -0300124 return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
125}
126
127static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
128{
129 struct i2c_msg msg = {.addr = adr, .flags = 0,
130 .buf = data, .len = len};
131
132 if (i2c_transfer(adap, &msg, 1) != 1) {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300133 printk(KERN_ERR "i2c_write error\n");
Ralph Metzlere8783952011-07-03 13:36:17 -0300134 return -1;
135 }
136 return 0;
137}
138
139static int WriteRegs(struct tda_state *state,
140 u8 SubAddr, u8 *Regs, u16 nRegs)
141{
142 u8 data[nRegs+1];
143
144 data[0] = SubAddr;
145 memcpy(data + 1, Regs, nRegs);
146 return i2c_write(state->i2c, state->adr, data, nRegs+1);
147}
148
Oliver Endriss0fe44622011-07-03 13:37:31 -0300149static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg)
Ralph Metzlere8783952011-07-03 13:36:17 -0300150{
151 u8 msg[2] = {SubAddr, Reg};
152
153 return i2c_write(state->i2c, state->adr, msg, 2);
154}
155
156static int Read(struct tda_state *state, u8 * Regs)
157{
158 return i2c_readn(state->i2c, state->adr, Regs, 16);
159}
160
161static int ReadExtented(struct tda_state *state, u8 * Regs)
162{
163 return i2c_readn(state->i2c, state->adr, Regs, NUM_REGS);
164}
165
Oliver Endriss0fe44622011-07-03 13:37:31 -0300166static int UpdateRegs(struct tda_state *state, u8 RegFrom, u8 RegTo)
Ralph Metzlere8783952011-07-03 13:36:17 -0300167{
168 return WriteRegs(state, RegFrom,
169 &state->m_Regs[RegFrom], RegTo-RegFrom+1);
170}
171static int UpdateReg(struct tda_state *state, u8 Reg)
172{
Oliver Endriss0fe44622011-07-03 13:37:31 -0300173 return WriteReg(state, Reg, state->m_Regs[Reg]);
Ralph Metzlere8783952011-07-03 13:36:17 -0300174}
175
176#include "tda18271c2dd_maps.h"
177
178#undef CHK_ERROR
179#define CHK_ERROR(s) if ((status = s) < 0) break
180
181static void reset(struct tda_state *state)
182{
183 u32 ulIFLevelAnalog = 0;
184 u32 ulIFLevelDigital = 2;
185 u32 ulIFLevelDVBC = 7;
186 u32 ulIFLevelDVBT = 6;
187 u32 ulXTOut = 0;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300188 u32 ulStandbyMode = 0x06; /* Send in stdb, but leave osc on */
Ralph Metzlere8783952011-07-03 13:36:17 -0300189 u32 ulSlave = 0;
190 u32 ulFMInput = 0;
191 u32 ulSettlingTime = 100;
192
193 state->m_Frequency = 0;
194 state->m_SettlingTime = 100;
195 state->m_IFLevelAnalog = (ulIFLevelAnalog & 0x07) << 2;
196 state->m_IFLevelDigital = (ulIFLevelDigital & 0x07) << 2;
197 state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07) << 2;
198 state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07) << 2;
199
200 state->m_EP4 = 0x20;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300201 if (ulXTOut != 0)
202 state->m_EP4 |= 0x40;
Ralph Metzlere8783952011-07-03 13:36:17 -0300203
204 state->m_EP3_Standby = ((ulStandbyMode & 0x07) << 5) | 0x0F;
205 state->m_bMaster = (ulSlave == 0);
206
207 state->m_SettlingTime = ulSettlingTime;
208
209 state->m_bFMInput = (ulFMInput == 2);
210}
211
212static bool SearchMap1(struct SMap Map[],
213 u32 Frequency, u8 *pParam)
214{
215 int i = 0;
216
Oliver Endriss0fe44622011-07-03 13:37:31 -0300217 while ((Map[i].m_Frequency != 0) && (Frequency > Map[i].m_Frequency))
Ralph Metzlere8783952011-07-03 13:36:17 -0300218 i += 1;
219 if (Map[i].m_Frequency == 0)
220 return false;
221 *pParam = Map[i].m_Param;
222 return true;
223}
224
225static bool SearchMap2(struct SMapI Map[],
226 u32 Frequency, s32 *pParam)
227{
228 int i = 0;
229
230 while ((Map[i].m_Frequency != 0) &&
Oliver Endriss0fe44622011-07-03 13:37:31 -0300231 (Frequency > Map[i].m_Frequency))
Ralph Metzlere8783952011-07-03 13:36:17 -0300232 i += 1;
233 if (Map[i].m_Frequency == 0)
234 return false;
235 *pParam = Map[i].m_Param;
236 return true;
237}
238
Oliver Endriss0fe44622011-07-03 13:37:31 -0300239static bool SearchMap3(struct SMap2 Map[], u32 Frequency,
Ralph Metzlere8783952011-07-03 13:36:17 -0300240 u8 *pParam1, u8 *pParam2)
241{
242 int i = 0;
243
244 while ((Map[i].m_Frequency != 0) &&
Oliver Endriss0fe44622011-07-03 13:37:31 -0300245 (Frequency > Map[i].m_Frequency))
Ralph Metzlere8783952011-07-03 13:36:17 -0300246 i += 1;
247 if (Map[i].m_Frequency == 0)
248 return false;
249 *pParam1 = Map[i].m_Param1;
250 *pParam2 = Map[i].m_Param2;
251 return true;
252}
253
254static bool SearchMap4(struct SRFBandMap Map[],
255 u32 Frequency, u8 *pRFBand)
256{
257 int i = 0;
258
259 while (i < 7 && (Frequency > Map[i].m_RF_max))
260 i += 1;
261 if (i == 7)
262 return false;
263 *pRFBand = i;
264 return true;
265}
266
267static int ThermometerRead(struct tda_state *state, u8 *pTM_Value)
268{
269 int status = 0;
270
271 do {
272 u8 Regs[16];
273 state->m_Regs[TM] |= 0x10;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300274 CHK_ERROR(UpdateReg(state, TM));
275 CHK_ERROR(Read(state, Regs));
276 if (((Regs[TM] & 0x0F) == 0 && (Regs[TM] & 0x20) == 0x20) ||
277 ((Regs[TM] & 0x0F) == 8 && (Regs[TM] & 0x20) == 0x00)) {
Ralph Metzlere8783952011-07-03 13:36:17 -0300278 state->m_Regs[TM] ^= 0x20;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300279 CHK_ERROR(UpdateReg(state, TM));
Ralph Metzlere8783952011-07-03 13:36:17 -0300280 msleep(10);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300281 CHK_ERROR(Read(state, Regs));
Ralph Metzlere8783952011-07-03 13:36:17 -0300282 }
Oliver Endriss0fe44622011-07-03 13:37:31 -0300283 *pTM_Value = (Regs[TM] & 0x20)
284 ? m_Thermometer_Map_2[Regs[TM] & 0x0F]
285 : m_Thermometer_Map_1[Regs[TM] & 0x0F] ;
286 state->m_Regs[TM] &= ~0x10; /* Thermometer off */
287 CHK_ERROR(UpdateReg(state, TM));
288 state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 ????????? */
289 CHK_ERROR(UpdateReg(state, EP4));
290 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300291
292 return status;
293}
294
295static int StandBy(struct tda_state *state)
296{
297 int status = 0;
298 do {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300299 state->m_Regs[EB12] &= ~0x20; /* PD_AGC1_Det = 0 */
300 CHK_ERROR(UpdateReg(state, EB12));
301 state->m_Regs[EB18] &= ~0x83; /* AGC1_loop_off = 0, AGC1_Gain = 6 dB */
302 CHK_ERROR(UpdateReg(state, EB18));
303 state->m_Regs[EB21] |= 0x03; /* AGC2_Gain = -6 dB */
Ralph Metzlere8783952011-07-03 13:36:17 -0300304 state->m_Regs[EP3] = state->m_EP3_Standby;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300305 CHK_ERROR(UpdateReg(state, EP3));
306 state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LP_Fc[2] = 0 */
307 CHK_ERROR(UpdateRegs(state, EB21, EB23));
308 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300309 return status;
310}
311
312static int CalcMainPLL(struct tda_state *state, u32 freq)
313{
314
315 u8 PostDiv;
316 u8 Div;
317 u64 OscFreq;
318 u32 MainDiv;
319
Oliver Endriss0fe44622011-07-03 13:37:31 -0300320 if (!SearchMap3(m_Main_PLL_Map, freq, &PostDiv, &Div))
Ralph Metzlere8783952011-07-03 13:36:17 -0300321 return -EINVAL;
Ralph Metzlere8783952011-07-03 13:36:17 -0300322
323 OscFreq = (u64) freq * (u64) Div;
324 OscFreq *= (u64) 16384;
325 do_div(OscFreq, (u64)16000000);
326 MainDiv = OscFreq;
327
328 state->m_Regs[MPD] = PostDiv & 0x77;
329 state->m_Regs[MD1] = ((MainDiv >> 16) & 0x7F);
330 state->m_Regs[MD2] = ((MainDiv >> 8) & 0xFF);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300331 state->m_Regs[MD3] = (MainDiv & 0xFF);
Ralph Metzlere8783952011-07-03 13:36:17 -0300332
333 return UpdateRegs(state, MPD, MD3);
334}
335
336static int CalcCalPLL(struct tda_state *state, u32 freq)
337{
Ralph Metzlere8783952011-07-03 13:36:17 -0300338 u8 PostDiv;
339 u8 Div;
340 u64 OscFreq;
341 u32 CalDiv;
342
Oliver Endriss0fe44622011-07-03 13:37:31 -0300343 if (!SearchMap3(m_Cal_PLL_Map, freq, &PostDiv, &Div))
Ralph Metzlere8783952011-07-03 13:36:17 -0300344 return -EINVAL;
Ralph Metzlere8783952011-07-03 13:36:17 -0300345
346 OscFreq = (u64)freq * (u64)Div;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300347 /* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
348 OscFreq *= (u64)16384;
Ralph Metzlere8783952011-07-03 13:36:17 -0300349 do_div(OscFreq, (u64)16000000);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300350 CalDiv = OscFreq;
Ralph Metzlere8783952011-07-03 13:36:17 -0300351
352 state->m_Regs[CPD] = PostDiv;
353 state->m_Regs[CD1] = ((CalDiv >> 16) & 0xFF);
354 state->m_Regs[CD2] = ((CalDiv >> 8) & 0xFF);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300355 state->m_Regs[CD3] = (CalDiv & 0xFF);
Ralph Metzlere8783952011-07-03 13:36:17 -0300356
Oliver Endriss0fe44622011-07-03 13:37:31 -0300357 return UpdateRegs(state, CPD, CD3);
Ralph Metzlere8783952011-07-03 13:36:17 -0300358}
359
360static int CalibrateRF(struct tda_state *state,
Oliver Endriss0fe44622011-07-03 13:37:31 -0300361 u8 RFBand, u32 freq, s32 *pCprog)
Ralph Metzlere8783952011-07-03 13:36:17 -0300362{
Ralph Metzlere8783952011-07-03 13:36:17 -0300363 int status = 0;
364 u8 Regs[NUM_REGS];
365 do {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300366 u8 BP_Filter = 0;
367 u8 GainTaper = 0;
368 u8 RFC_K = 0;
369 u8 RFC_M = 0;
Ralph Metzlere8783952011-07-03 13:36:17 -0300370
Oliver Endriss0fe44622011-07-03 13:37:31 -0300371 state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 */
372 CHK_ERROR(UpdateReg(state, EP4));
373 state->m_Regs[EB18] |= 0x03; /* AGC1_Gain = 3 */
374 CHK_ERROR(UpdateReg(state, EB18));
Ralph Metzlere8783952011-07-03 13:36:17 -0300375
Oliver Endriss0fe44622011-07-03 13:37:31 -0300376 /* Switching off LT (as datasheet says) causes calibration on C1 to fail */
377 /* (Readout of Cprog is allways 255) */
378 if (state->m_Regs[ID] != 0x83) /* C1: ID == 83, C2: ID == 84 */
379 state->m_Regs[EP3] |= 0x40; /* SM_LT = 1 */
Ralph Metzlere8783952011-07-03 13:36:17 -0300380
Oliver Endriss0fe44622011-07-03 13:37:31 -0300381 if (!(SearchMap1(m_BP_Filter_Map, freq, &BP_Filter) &&
382 SearchMap1(m_GainTaper_Map, freq, &GainTaper) &&
383 SearchMap3(m_KM_Map, freq, &RFC_K, &RFC_M)))
Ralph Metzlere8783952011-07-03 13:36:17 -0300384 return -EINVAL;
Ralph Metzlere8783952011-07-03 13:36:17 -0300385
386 state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | BP_Filter;
387 state->m_Regs[EP2] = (RFBand << 5) | GainTaper;
388
389 state->m_Regs[EB13] = (state->m_Regs[EB13] & ~0x7C) | (RFC_K << 4) | (RFC_M << 2);
390
Oliver Endriss0fe44622011-07-03 13:37:31 -0300391 CHK_ERROR(UpdateRegs(state, EP1, EP3));
392 CHK_ERROR(UpdateReg(state, EB13));
Ralph Metzlere8783952011-07-03 13:36:17 -0300393
Oliver Endriss0fe44622011-07-03 13:37:31 -0300394 state->m_Regs[EB4] |= 0x20; /* LO_ForceSrce = 1 */
395 CHK_ERROR(UpdateReg(state, EB4));
Ralph Metzlere8783952011-07-03 13:36:17 -0300396
Oliver Endriss0fe44622011-07-03 13:37:31 -0300397 state->m_Regs[EB7] |= 0x20; /* CAL_ForceSrce = 1 */
398 CHK_ERROR(UpdateReg(state, EB7));
Ralph Metzlere8783952011-07-03 13:36:17 -0300399
Oliver Endriss0fe44622011-07-03 13:37:31 -0300400 state->m_Regs[EB14] = 0; /* RFC_Cprog = 0 */
401 CHK_ERROR(UpdateReg(state, EB14));
Ralph Metzlere8783952011-07-03 13:36:17 -0300402
Oliver Endriss0fe44622011-07-03 13:37:31 -0300403 state->m_Regs[EB20] &= ~0x20; /* ForceLock = 0; */
404 CHK_ERROR(UpdateReg(state, EB20));
Ralph Metzlere8783952011-07-03 13:36:17 -0300405
Oliver Endriss0fe44622011-07-03 13:37:31 -0300406 state->m_Regs[EP4] |= 0x03; /* CAL_Mode = 3 */
407 CHK_ERROR(UpdateRegs(state, EP4, EP5));
Ralph Metzlere8783952011-07-03 13:36:17 -0300408
Oliver Endriss0fe44622011-07-03 13:37:31 -0300409 CHK_ERROR(CalcCalPLL(state, freq));
410 CHK_ERROR(CalcMainPLL(state, freq + 1000000));
Ralph Metzlere8783952011-07-03 13:36:17 -0300411
412 msleep(5);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300413 CHK_ERROR(UpdateReg(state, EP2));
414 CHK_ERROR(UpdateReg(state, EP1));
415 CHK_ERROR(UpdateReg(state, EP2));
416 CHK_ERROR(UpdateReg(state, EP1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300417
Oliver Endriss0fe44622011-07-03 13:37:31 -0300418 state->m_Regs[EB4] &= ~0x20; /* LO_ForceSrce = 0 */
419 CHK_ERROR(UpdateReg(state, EB4));
Ralph Metzlere8783952011-07-03 13:36:17 -0300420
Oliver Endriss0fe44622011-07-03 13:37:31 -0300421 state->m_Regs[EB7] &= ~0x20; /* CAL_ForceSrce = 0 */
422 CHK_ERROR(UpdateReg(state, EB7));
Ralph Metzlere8783952011-07-03 13:36:17 -0300423 msleep(10);
424
Oliver Endriss0fe44622011-07-03 13:37:31 -0300425 state->m_Regs[EB20] |= 0x20; /* ForceLock = 1; */
426 CHK_ERROR(UpdateReg(state, EB20));
Ralph Metzlere8783952011-07-03 13:36:17 -0300427 msleep(60);
428
Oliver Endriss0fe44622011-07-03 13:37:31 -0300429 state->m_Regs[EP4] &= ~0x03; /* CAL_Mode = 0 */
430 state->m_Regs[EP3] &= ~0x40; /* SM_LT = 0 */
431 state->m_Regs[EB18] &= ~0x03; /* AGC1_Gain = 0 */
432 CHK_ERROR(UpdateReg(state, EB18));
433 CHK_ERROR(UpdateRegs(state, EP3, EP4));
434 CHK_ERROR(UpdateReg(state, EP1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300435
Oliver Endriss0fe44622011-07-03 13:37:31 -0300436 CHK_ERROR(ReadExtented(state, Regs));
Ralph Metzlere8783952011-07-03 13:36:17 -0300437
438 *pCprog = Regs[EB14];
Ralph Metzlere8783952011-07-03 13:36:17 -0300439
Oliver Endriss0fe44622011-07-03 13:37:31 -0300440 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300441 return status;
442}
443
444static int RFTrackingFiltersInit(struct tda_state *state,
445 u8 RFBand)
446{
Ralph Metzlere8783952011-07-03 13:36:17 -0300447 int status = 0;
448
449 u32 RF1 = m_RF_Band_Map[RFBand].m_RF1_Default;
450 u32 RF2 = m_RF_Band_Map[RFBand].m_RF2_Default;
451 u32 RF3 = m_RF_Band_Map[RFBand].m_RF3_Default;
452 bool bcal = false;
453
454 s32 Cprog_cal1 = 0;
455 s32 Cprog_table1 = 0;
456 s32 Cprog_cal2 = 0;
457 s32 Cprog_table2 = 0;
458 s32 Cprog_cal3 = 0;
459 s32 Cprog_table3 = 0;
460
461 state->m_RF_A1[RFBand] = 0;
462 state->m_RF_B1[RFBand] = 0;
463 state->m_RF_A2[RFBand] = 0;
464 state->m_RF_B2[RFBand] = 0;
465
466 do {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300467 CHK_ERROR(PowerScan(state, RFBand, RF1, &RF1, &bcal));
468 if (bcal) {
469 CHK_ERROR(CalibrateRF(state, RFBand, RF1, &Cprog_cal1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300470 }
Oliver Endriss0fe44622011-07-03 13:37:31 -0300471 SearchMap2(m_RF_Cal_Map, RF1, &Cprog_table1);
472 if (!bcal)
Ralph Metzlere8783952011-07-03 13:36:17 -0300473 Cprog_cal1 = Cprog_table1;
Ralph Metzlere8783952011-07-03 13:36:17 -0300474 state->m_RF_B1[RFBand] = Cprog_cal1 - Cprog_table1;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300475 /* state->m_RF_A1[RF_Band] = ???? */
Ralph Metzlere8783952011-07-03 13:36:17 -0300476
Oliver Endriss0fe44622011-07-03 13:37:31 -0300477 if (RF2 == 0)
478 break;
Ralph Metzlere8783952011-07-03 13:36:17 -0300479
Oliver Endriss0fe44622011-07-03 13:37:31 -0300480 CHK_ERROR(PowerScan(state, RFBand, RF2, &RF2, &bcal));
481 if (bcal) {
482 CHK_ERROR(CalibrateRF(state, RFBand, RF2, &Cprog_cal2));
Ralph Metzlere8783952011-07-03 13:36:17 -0300483 }
Oliver Endriss0fe44622011-07-03 13:37:31 -0300484 SearchMap2(m_RF_Cal_Map, RF2, &Cprog_table2);
485 if (!bcal)
Ralph Metzlere8783952011-07-03 13:36:17 -0300486 Cprog_cal2 = Cprog_table2;
Ralph Metzlere8783952011-07-03 13:36:17 -0300487
488 state->m_RF_A1[RFBand] =
489 (Cprog_cal2 - Cprog_table2 - Cprog_cal1 + Cprog_table1) /
Oliver Endriss0fe44622011-07-03 13:37:31 -0300490 ((s32)(RF2) - (s32)(RF1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300491
Oliver Endriss0fe44622011-07-03 13:37:31 -0300492 if (RF3 == 0)
493 break;
Ralph Metzlere8783952011-07-03 13:36:17 -0300494
Oliver Endriss0fe44622011-07-03 13:37:31 -0300495 CHK_ERROR(PowerScan(state, RFBand, RF3, &RF3, &bcal));
496 if (bcal) {
497 CHK_ERROR(CalibrateRF(state, RFBand, RF3, &Cprog_cal3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300498 }
Oliver Endriss0fe44622011-07-03 13:37:31 -0300499 SearchMap2(m_RF_Cal_Map, RF3, &Cprog_table3);
500 if (!bcal)
Ralph Metzlere8783952011-07-03 13:36:17 -0300501 Cprog_cal3 = Cprog_table3;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300502 state->m_RF_A2[RFBand] = (Cprog_cal3 - Cprog_table3 - Cprog_cal2 + Cprog_table2) / ((s32)(RF3) - (s32)(RF2));
Ralph Metzlere8783952011-07-03 13:36:17 -0300503 state->m_RF_B2[RFBand] = Cprog_cal2 - Cprog_table2;
504
Oliver Endriss0fe44622011-07-03 13:37:31 -0300505 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300506
507 state->m_RF1[RFBand] = RF1;
508 state->m_RF2[RFBand] = RF2;
509 state->m_RF3[RFBand] = RF3;
510
511#if 0
Oliver Endriss0fe44622011-07-03 13:37:31 -0300512 printk(KERN_ERR "%s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __func__,
513 RFBand, RF1, state->m_RF_A1[RFBand], state->m_RF_B1[RFBand], RF2,
514 state->m_RF_A2[RFBand], state->m_RF_B2[RFBand], RF3);
Ralph Metzlere8783952011-07-03 13:36:17 -0300515#endif
516
517 return status;
518}
519
520static int PowerScan(struct tda_state *state,
Oliver Endriss0fe44622011-07-03 13:37:31 -0300521 u8 RFBand, u32 RF_in, u32 *pRF_Out, bool *pbcal)
Ralph Metzlere8783952011-07-03 13:36:17 -0300522{
Oliver Endriss0fe44622011-07-03 13:37:31 -0300523 int status = 0;
524 do {
525 u8 Gain_Taper = 0;
526 s32 RFC_Cprog = 0;
527 u8 CID_Target = 0;
528 u8 CountLimit = 0;
529 u32 freq_MainPLL;
530 u8 Regs[NUM_REGS];
531 u8 CID_Gain;
532 s32 Count = 0;
533 int sign = 1;
534 bool wait = false;
Ralph Metzlere8783952011-07-03 13:36:17 -0300535
Oliver Endriss0fe44622011-07-03 13:37:31 -0300536 if (!(SearchMap2(m_RF_Cal_Map, RF_in, &RFC_Cprog) &&
537 SearchMap1(m_GainTaper_Map, RF_in, &Gain_Taper) &&
538 SearchMap3(m_CID_Target_Map, RF_in, &CID_Target, &CountLimit))) {
Ralph Metzlere8783952011-07-03 13:36:17 -0300539
Oliver Endriss0fe44622011-07-03 13:37:31 -0300540 printk(KERN_ERR "%s Search map failed\n", __func__);
541 return -EINVAL;
542 }
Ralph Metzlere8783952011-07-03 13:36:17 -0300543
Oliver Endriss0fe44622011-07-03 13:37:31 -0300544 state->m_Regs[EP2] = (RFBand << 5) | Gain_Taper;
545 state->m_Regs[EB14] = (RFC_Cprog);
546 CHK_ERROR(UpdateReg(state, EP2));
547 CHK_ERROR(UpdateReg(state, EB14));
Ralph Metzlere8783952011-07-03 13:36:17 -0300548
Oliver Endriss0fe44622011-07-03 13:37:31 -0300549 freq_MainPLL = RF_in + 1000000;
550 CHK_ERROR(CalcMainPLL(state, freq_MainPLL));
551 msleep(5);
552 state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x03) | 1; /* CAL_mode = 1 */
553 CHK_ERROR(UpdateReg(state, EP4));
554 CHK_ERROR(UpdateReg(state, EP2)); /* Launch power measurement */
555 CHK_ERROR(ReadExtented(state, Regs));
556 CID_Gain = Regs[EB10] & 0x3F;
557 state->m_Regs[ID] = Regs[ID]; /* Chip version, (needed for C1 workarround in CalibrateRF) */
Ralph Metzlere8783952011-07-03 13:36:17 -0300558
Oliver Endriss0fe44622011-07-03 13:37:31 -0300559 *pRF_Out = RF_in;
Ralph Metzlere8783952011-07-03 13:36:17 -0300560
Oliver Endriss0fe44622011-07-03 13:37:31 -0300561 while (CID_Gain < CID_Target) {
562 freq_MainPLL = RF_in + sign * Count + 1000000;
563 CHK_ERROR(CalcMainPLL(state, freq_MainPLL));
564 msleep(wait ? 5 : 1);
565 wait = false;
566 CHK_ERROR(UpdateReg(state, EP2)); /* Launch power measurement */
567 CHK_ERROR(ReadExtented(state, Regs));
568 CID_Gain = Regs[EB10] & 0x3F;
569 Count += 200000;
Ralph Metzlere8783952011-07-03 13:36:17 -0300570
Oliver Endriss0fe44622011-07-03 13:37:31 -0300571 if (Count < CountLimit * 100000)
572 continue;
573 if (sign < 0)
574 break;
575
576 sign = -sign;
577 Count = 200000;
578 wait = true;
579 }
580 CHK_ERROR(status);
581 if (CID_Gain >= CID_Target) {
582 *pbcal = true;
583 *pRF_Out = freq_MainPLL - 1000000;
584 } else
585 *pbcal = false;
586 } while (0);
587
588 return status;
Ralph Metzlere8783952011-07-03 13:36:17 -0300589}
590
591static int PowerScanInit(struct tda_state *state)
592{
Ralph Metzlere8783952011-07-03 13:36:17 -0300593 int status = 0;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300594 do {
Ralph Metzlere8783952011-07-03 13:36:17 -0300595 state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | 0x12;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300596 state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x1F); /* If level = 0, Cal mode = 0 */
597 CHK_ERROR(UpdateRegs(state, EP3, EP4));
598 state->m_Regs[EB18] = (state->m_Regs[EB18] & ~0x03); /* AGC 1 Gain = 0 */
599 CHK_ERROR(UpdateReg(state, EB18));
600 state->m_Regs[EB21] = (state->m_Regs[EB21] & ~0x03); /* AGC 2 Gain = 0 (Datasheet = 3) */
601 state->m_Regs[EB23] = (state->m_Regs[EB23] | 0x06); /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
602 CHK_ERROR(UpdateRegs(state, EB21, EB23));
603 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300604 return status;
605}
606
607static int CalcRFFilterCurve(struct tda_state *state)
608{
Ralph Metzlere8783952011-07-03 13:36:17 -0300609 int status = 0;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300610 do {
611 msleep(200); /* Temperature stabilisation */
Ralph Metzlere8783952011-07-03 13:36:17 -0300612 CHK_ERROR(PowerScanInit(state));
Oliver Endriss0fe44622011-07-03 13:37:31 -0300613 CHK_ERROR(RFTrackingFiltersInit(state, 0));
614 CHK_ERROR(RFTrackingFiltersInit(state, 1));
615 CHK_ERROR(RFTrackingFiltersInit(state, 2));
616 CHK_ERROR(RFTrackingFiltersInit(state, 3));
617 CHK_ERROR(RFTrackingFiltersInit(state, 4));
618 CHK_ERROR(RFTrackingFiltersInit(state, 5));
619 CHK_ERROR(RFTrackingFiltersInit(state, 6));
620 CHK_ERROR(ThermometerRead(state, &state->m_TMValue_RFCal)); /* also switches off Cal mode !!! */
621 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300622
623 return status;
624}
625
626static int FixedContentsI2CUpdate(struct tda_state *state)
627{
628 static u8 InitRegs[] = {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300629 0x08, 0x80, 0xC6,
630 0xDF, 0x16, 0x60, 0x80,
631 0x80, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00,
633 0xFC, 0x01, 0x84, 0x41,
634 0x01, 0x84, 0x40, 0x07,
635 0x00, 0x00, 0x96, 0x3F,
636 0xC1, 0x00, 0x8F, 0x00,
637 0x00, 0x8C, 0x00, 0x20,
638 0xB3, 0x48, 0xB0,
Ralph Metzlere8783952011-07-03 13:36:17 -0300639 };
640 int status = 0;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300641 memcpy(&state->m_Regs[TM], InitRegs, EB23 - TM + 1);
Ralph Metzlere8783952011-07-03 13:36:17 -0300642 do {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300643 CHK_ERROR(UpdateRegs(state, TM, EB23));
Ralph Metzlere8783952011-07-03 13:36:17 -0300644
Oliver Endriss0fe44622011-07-03 13:37:31 -0300645 /* AGC1 gain setup */
Ralph Metzlere8783952011-07-03 13:36:17 -0300646 state->m_Regs[EB17] = 0x00;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300647 CHK_ERROR(UpdateReg(state, EB17));
Ralph Metzlere8783952011-07-03 13:36:17 -0300648 state->m_Regs[EB17] = 0x03;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300649 CHK_ERROR(UpdateReg(state, EB17));
Ralph Metzlere8783952011-07-03 13:36:17 -0300650 state->m_Regs[EB17] = 0x43;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300651 CHK_ERROR(UpdateReg(state, EB17));
Ralph Metzlere8783952011-07-03 13:36:17 -0300652 state->m_Regs[EB17] = 0x4C;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300653 CHK_ERROR(UpdateReg(state, EB17));
Ralph Metzlere8783952011-07-03 13:36:17 -0300654
Oliver Endriss0fe44622011-07-03 13:37:31 -0300655 /* IRC Cal Low band */
Ralph Metzlere8783952011-07-03 13:36:17 -0300656 state->m_Regs[EP3] = 0x1F;
657 state->m_Regs[EP4] = 0x66;
658 state->m_Regs[EP5] = 0x81;
659 state->m_Regs[CPD] = 0xCC;
660 state->m_Regs[CD1] = 0x6C;
661 state->m_Regs[CD2] = 0x00;
662 state->m_Regs[CD3] = 0x00;
663 state->m_Regs[MPD] = 0xC5;
664 state->m_Regs[MD1] = 0x77;
665 state->m_Regs[MD2] = 0x08;
666 state->m_Regs[MD3] = 0x00;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300667 CHK_ERROR(UpdateRegs(state, EP2, MD3)); /* diff between sw and datasheet (ep3-md3) */
Ralph Metzlere8783952011-07-03 13:36:17 -0300668
Oliver Endriss0fe44622011-07-03 13:37:31 -0300669#if 0
670 state->m_Regs[EB4] = 0x61; /* missing in sw */
671 CHK_ERROR(UpdateReg(state, EB4));
672 msleep(1);
673 state->m_Regs[EB4] = 0x41;
674 CHK_ERROR(UpdateReg(state, EB4));
675#endif
Ralph Metzlere8783952011-07-03 13:36:17 -0300676
677 msleep(5);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300678 CHK_ERROR(UpdateReg(state, EP1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300679 msleep(5);
680
681 state->m_Regs[EP5] = 0x85;
682 state->m_Regs[CPD] = 0xCB;
683 state->m_Regs[CD1] = 0x66;
684 state->m_Regs[CD2] = 0x70;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300685 CHK_ERROR(UpdateRegs(state, EP3, CD3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300686 msleep(5);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300687 CHK_ERROR(UpdateReg(state, EP2));
Ralph Metzlere8783952011-07-03 13:36:17 -0300688 msleep(30);
689
Oliver Endriss0fe44622011-07-03 13:37:31 -0300690 /* IRC Cal mid band */
Ralph Metzlere8783952011-07-03 13:36:17 -0300691 state->m_Regs[EP5] = 0x82;
692 state->m_Regs[CPD] = 0xA8;
693 state->m_Regs[CD2] = 0x00;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300694 state->m_Regs[MPD] = 0xA1; /* Datasheet = 0xA9 */
Ralph Metzlere8783952011-07-03 13:36:17 -0300695 state->m_Regs[MD1] = 0x73;
696 state->m_Regs[MD2] = 0x1A;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300697 CHK_ERROR(UpdateRegs(state, EP3, MD3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300698
699 msleep(5);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300700 CHK_ERROR(UpdateReg(state, EP1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300701 msleep(5);
702
703 state->m_Regs[EP5] = 0x86;
704 state->m_Regs[CPD] = 0xA8;
705 state->m_Regs[CD1] = 0x66;
706 state->m_Regs[CD2] = 0xA0;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300707 CHK_ERROR(UpdateRegs(state, EP3, CD3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300708 msleep(5);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300709 CHK_ERROR(UpdateReg(state, EP2));
Ralph Metzlere8783952011-07-03 13:36:17 -0300710 msleep(30);
711
Oliver Endriss0fe44622011-07-03 13:37:31 -0300712 /* IRC Cal high band */
Ralph Metzlere8783952011-07-03 13:36:17 -0300713 state->m_Regs[EP5] = 0x83;
714 state->m_Regs[CPD] = 0x98;
715 state->m_Regs[CD1] = 0x65;
716 state->m_Regs[CD2] = 0x00;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300717 state->m_Regs[MPD] = 0x91; /* Datasheet = 0x91 */
Ralph Metzlere8783952011-07-03 13:36:17 -0300718 state->m_Regs[MD1] = 0x71;
719 state->m_Regs[MD2] = 0xCD;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300720 CHK_ERROR(UpdateRegs(state, EP3, MD3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300721 msleep(5);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300722 CHK_ERROR(UpdateReg(state, EP1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300723 msleep(5);
724 state->m_Regs[EP5] = 0x87;
725 state->m_Regs[CD1] = 0x65;
726 state->m_Regs[CD2] = 0x50;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300727 CHK_ERROR(UpdateRegs(state, EP3, CD3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300728 msleep(5);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300729 CHK_ERROR(UpdateReg(state, EP2));
Ralph Metzlere8783952011-07-03 13:36:17 -0300730 msleep(30);
731
Oliver Endriss0fe44622011-07-03 13:37:31 -0300732 /* Back to normal */
Ralph Metzlere8783952011-07-03 13:36:17 -0300733 state->m_Regs[EP4] = 0x64;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300734 CHK_ERROR(UpdateReg(state, EP4));
735 CHK_ERROR(UpdateReg(state, EP1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300736
Oliver Endriss0fe44622011-07-03 13:37:31 -0300737 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300738 return status;
739}
740
741static int InitCal(struct tda_state *state)
742{
743 int status = 0;
744
Oliver Endriss0fe44622011-07-03 13:37:31 -0300745 do {
Ralph Metzlere8783952011-07-03 13:36:17 -0300746 CHK_ERROR(FixedContentsI2CUpdate(state));
747 CHK_ERROR(CalcRFFilterCurve(state));
748 CHK_ERROR(StandBy(state));
Oliver Endriss0fe44622011-07-03 13:37:31 -0300749 /* m_bInitDone = true; */
750 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300751 return status;
752};
753
754static int RFTrackingFiltersCorrection(struct tda_state *state,
755 u32 Frequency)
756{
757 int status = 0;
758 s32 Cprog_table;
759 u8 RFBand;
760 u8 dCoverdT;
761
Oliver Endriss0fe44622011-07-03 13:37:31 -0300762 if (!SearchMap2(m_RF_Cal_Map, Frequency, &Cprog_table) ||
763 !SearchMap4(m_RF_Band_Map, Frequency, &RFBand) ||
764 !SearchMap1(m_RF_Cal_DC_Over_DT_Map, Frequency, &dCoverdT))
Ralph Metzlere8783952011-07-03 13:36:17 -0300765
Oliver Endriss0fe44622011-07-03 13:37:31 -0300766 return -EINVAL;
767
768 do {
Ralph Metzlere8783952011-07-03 13:36:17 -0300769 u8 TMValue_Current;
770 u32 RF1 = state->m_RF1[RFBand];
771 u32 RF2 = state->m_RF1[RFBand];
772 u32 RF3 = state->m_RF1[RFBand];
773 s32 RF_A1 = state->m_RF_A1[RFBand];
774 s32 RF_B1 = state->m_RF_B1[RFBand];
775 s32 RF_A2 = state->m_RF_A2[RFBand];
776 s32 RF_B2 = state->m_RF_B2[RFBand];
777 s32 Capprox = 0;
778 int TComp;
779
Oliver Endriss0fe44622011-07-03 13:37:31 -0300780 state->m_Regs[EP3] &= ~0xE0; /* Power up */
781 CHK_ERROR(UpdateReg(state, EP3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300782
Oliver Endriss0fe44622011-07-03 13:37:31 -0300783 CHK_ERROR(ThermometerRead(state, &TMValue_Current));
Ralph Metzlere8783952011-07-03 13:36:17 -0300784
Oliver Endriss0fe44622011-07-03 13:37:31 -0300785 if (RF3 == 0 || Frequency < RF2)
Ralph Metzlere8783952011-07-03 13:36:17 -0300786 Capprox = RF_A1 * ((s32)(Frequency) - (s32)(RF1)) + RF_B1 + Cprog_table;
Ralph Metzlere8783952011-07-03 13:36:17 -0300787 else
Ralph Metzlere8783952011-07-03 13:36:17 -0300788 Capprox = RF_A2 * ((s32)(Frequency) - (s32)(RF2)) + RF_B2 + Cprog_table;
Ralph Metzlere8783952011-07-03 13:36:17 -0300789
790 TComp = (int)(dCoverdT) * ((int)(TMValue_Current) - (int)(state->m_TMValue_RFCal))/1000;
791
792 Capprox += TComp;
793
Oliver Endriss0fe44622011-07-03 13:37:31 -0300794 if (Capprox < 0)
795 Capprox = 0;
796 else if (Capprox > 255)
797 Capprox = 255;
Ralph Metzlere8783952011-07-03 13:36:17 -0300798
799
Oliver Endriss0fe44622011-07-03 13:37:31 -0300800 /* TODO Temperature compensation. There is defenitely a scale factor */
801 /* missing in the datasheet, so leave it out for now. */
802 state->m_Regs[EB14] = Capprox;
Ralph Metzlere8783952011-07-03 13:36:17 -0300803
Oliver Endriss0fe44622011-07-03 13:37:31 -0300804 CHK_ERROR(UpdateReg(state, EB14));
Ralph Metzlere8783952011-07-03 13:36:17 -0300805
Oliver Endriss0fe44622011-07-03 13:37:31 -0300806 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300807 return status;
808}
809
810static int ChannelConfiguration(struct tda_state *state,
811 u32 Frequency, int Standard)
812{
813
814 s32 IntermediateFrequency = m_StandardTable[Standard].m_IFFrequency;
815 int status = 0;
816
817 u8 BP_Filter = 0;
818 u8 RF_Band = 0;
819 u8 GainTaper = 0;
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300820 u8 IR_Meas = 0;
Ralph Metzlere8783952011-07-03 13:36:17 -0300821
Oliver Endriss0fe44622011-07-03 13:37:31 -0300822 state->IF = IntermediateFrequency;
823 /* printk("%s Freq = %d Standard = %d IF = %d\n", __func__, Frequency, Standard, IntermediateFrequency); */
824 /* get values from tables */
Ralph Metzlere8783952011-07-03 13:36:17 -0300825
Oliver Endriss0fe44622011-07-03 13:37:31 -0300826 if (!(SearchMap1(m_BP_Filter_Map, Frequency, &BP_Filter) &&
827 SearchMap1(m_GainTaper_Map, Frequency, &GainTaper) &&
828 SearchMap1(m_IR_Meas_Map, Frequency, &IR_Meas) &&
829 SearchMap4(m_RF_Band_Map, Frequency, &RF_Band))) {
830
831 printk(KERN_ERR "%s SearchMap failed\n", __func__);
Ralph Metzlere8783952011-07-03 13:36:17 -0300832 return -EINVAL;
833 }
834
Oliver Endriss0fe44622011-07-03 13:37:31 -0300835 do {
Ralph Metzlere8783952011-07-03 13:36:17 -0300836 state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | m_StandardTable[Standard].m_EP3_4_0;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300837 state->m_Regs[EP3] &= ~0x04; /* switch RFAGC to high speed mode */
Ralph Metzlere8783952011-07-03 13:36:17 -0300838
Oliver Endriss0fe44622011-07-03 13:37:31 -0300839 /* m_EP4 default for XToutOn, CAL_Mode (0) */
840 state->m_Regs[EP4] = state->m_EP4 | ((Standard > HF_AnalogMax) ? state->m_IFLevelDigital : state->m_IFLevelAnalog);
841 /* state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; */
842 if (Standard <= HF_AnalogMax)
843 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelAnalog;
844 else if (Standard <= HF_ATSC)
845 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBT;
846 else if (Standard <= HF_DVBC)
847 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBC;
848 else
849 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
Ralph Metzlere8783952011-07-03 13:36:17 -0300850
Oliver Endriss0fe44622011-07-03 13:37:31 -0300851 if ((Standard == HF_FM_Radio) && state->m_bFMInput)
852 state->m_Regs[EP4] |= 80;
Ralph Metzlere8783952011-07-03 13:36:17 -0300853
854 state->m_Regs[MPD] &= ~0x80;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300855 if (Standard > HF_AnalogMax)
856 state->m_Regs[MPD] |= 0x80; /* Add IF_notch for digital */
Ralph Metzlere8783952011-07-03 13:36:17 -0300857
858 state->m_Regs[EB22] = m_StandardTable[Standard].m_EB22;
859
Oliver Endriss0fe44622011-07-03 13:37:31 -0300860 /* Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM ) */
861 if (Standard == HF_FM_Radio)
862 state->m_Regs[EB23] |= 0x06; /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
863 else
864 state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LPFc[2] = 0 */
Ralph Metzlere8783952011-07-03 13:36:17 -0300865
Oliver Endriss0fe44622011-07-03 13:37:31 -0300866 CHK_ERROR(UpdateRegs(state, EB22, EB23));
Ralph Metzlere8783952011-07-03 13:36:17 -0300867
Oliver Endriss0fe44622011-07-03 13:37:31 -0300868 state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | 0x40 | BP_Filter; /* Dis_Power_level = 1, Filter */
Ralph Metzlere8783952011-07-03 13:36:17 -0300869 state->m_Regs[EP5] = (state->m_Regs[EP5] & ~0x07) | IR_Meas;
870 state->m_Regs[EP2] = (RF_Band << 5) | GainTaper;
871
872 state->m_Regs[EB1] = (state->m_Regs[EB1] & ~0x07) |
Oliver Endriss0fe44622011-07-03 13:37:31 -0300873 (state->m_bMaster ? 0x04 : 0x00); /* CALVCO_FortLOn = MS */
874 /* AGC1_always_master = 0 */
875 /* AGC_firstn = 0 */
876 CHK_ERROR(UpdateReg(state, EB1));
Ralph Metzlere8783952011-07-03 13:36:17 -0300877
Oliver Endriss0fe44622011-07-03 13:37:31 -0300878 if (state->m_bMaster) {
879 CHK_ERROR(CalcMainPLL(state, Frequency + IntermediateFrequency));
880 CHK_ERROR(UpdateRegs(state, TM, EP5));
881 state->m_Regs[EB4] |= 0x20; /* LO_forceSrce = 1 */
882 CHK_ERROR(UpdateReg(state, EB4));
Ralph Metzlere8783952011-07-03 13:36:17 -0300883 msleep(1);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300884 state->m_Regs[EB4] &= ~0x20; /* LO_forceSrce = 0 */
885 CHK_ERROR(UpdateReg(state, EB4));
886 } else {
Mauro Carvalho Chehabea90f012011-07-03 18:06:07 -0300887 u8 PostDiv = 0;
Ralph Metzlere8783952011-07-03 13:36:17 -0300888 u8 Div;
Oliver Endriss0fe44622011-07-03 13:37:31 -0300889 CHK_ERROR(CalcCalPLL(state, Frequency + IntermediateFrequency));
Ralph Metzlere8783952011-07-03 13:36:17 -0300890
Oliver Endriss0fe44622011-07-03 13:37:31 -0300891 SearchMap3(m_Cal_PLL_Map, Frequency + IntermediateFrequency, &PostDiv, &Div);
Ralph Metzlere8783952011-07-03 13:36:17 -0300892 state->m_Regs[MPD] = (state->m_Regs[MPD] & ~0x7F) | (PostDiv & 0x77);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300893 CHK_ERROR(UpdateReg(state, MPD));
894 CHK_ERROR(UpdateRegs(state, TM, EP5));
Ralph Metzlere8783952011-07-03 13:36:17 -0300895
Oliver Endriss0fe44622011-07-03 13:37:31 -0300896 state->m_Regs[EB7] |= 0x20; /* CAL_forceSrce = 1 */
897 CHK_ERROR(UpdateReg(state, EB7));
Ralph Metzlere8783952011-07-03 13:36:17 -0300898 msleep(1);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300899 state->m_Regs[EB7] &= ~0x20; /* CAL_forceSrce = 0 */
900 CHK_ERROR(UpdateReg(state, EB7));
Ralph Metzlere8783952011-07-03 13:36:17 -0300901 }
902 msleep(20);
Oliver Endriss0fe44622011-07-03 13:37:31 -0300903 if (Standard != HF_FM_Radio)
904 state->m_Regs[EP3] |= 0x04; /* RFAGC to normal mode */
905 CHK_ERROR(UpdateReg(state, EP3));
Ralph Metzlere8783952011-07-03 13:36:17 -0300906
Oliver Endriss0fe44622011-07-03 13:37:31 -0300907 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300908 return status;
909}
910
Oliver Endriss0fe44622011-07-03 13:37:31 -0300911static int sleep(struct dvb_frontend *fe)
Ralph Metzlere8783952011-07-03 13:36:17 -0300912{
913 struct tda_state *state = fe->tuner_priv;
914
915 StandBy(state);
916 return 0;
917}
918
Oliver Endriss0fe44622011-07-03 13:37:31 -0300919static int init(struct dvb_frontend *fe)
Ralph Metzlere8783952011-07-03 13:36:17 -0300920{
Ralph Metzlere8783952011-07-03 13:36:17 -0300921 return 0;
922}
923
Oliver Endriss0fe44622011-07-03 13:37:31 -0300924static int release(struct dvb_frontend *fe)
Ralph Metzlere8783952011-07-03 13:36:17 -0300925{
926 kfree(fe->tuner_priv);
927 fe->tuner_priv = NULL;
928 return 0;
929}
930
931static int set_params(struct dvb_frontend *fe,
932 struct dvb_frontend_parameters *params)
933{
934 struct tda_state *state = fe->tuner_priv;
935 int status = 0;
936 int Standard;
937
938 state->m_Frequency = params->frequency;
939
940 if (fe->ops.info.type == FE_OFDM)
941 switch (params->u.ofdm.bandwidth) {
942 case BANDWIDTH_6_MHZ:
943 Standard = HF_DVBT_6MHZ;
944 break;
945 case BANDWIDTH_7_MHZ:
946 Standard = HF_DVBT_7MHZ;
947 break;
948 default:
949 case BANDWIDTH_8_MHZ:
950 Standard = HF_DVBT_8MHZ;
951 break;
952 }
953 else if (fe->ops.info.type == FE_QAM) {
954 Standard = HF_DVBC_8MHZ;
955 } else
956 return -EINVAL;
957 do {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300958 CHK_ERROR(RFTrackingFiltersCorrection(state, params->frequency));
959 CHK_ERROR(ChannelConfiguration(state, params->frequency, Standard));
Ralph Metzlere8783952011-07-03 13:36:17 -0300960
Oliver Endriss0fe44622011-07-03 13:37:31 -0300961 msleep(state->m_SettlingTime); /* Allow AGC's to settle down */
962 } while (0);
Ralph Metzlere8783952011-07-03 13:36:17 -0300963 return status;
964}
965
966#if 0
Oliver Endriss0fe44622011-07-03 13:37:31 -0300967static int GetSignalStrength(s32 *pSignalStrength, u32 RFAgc, u32 IFAgc)
Ralph Metzlere8783952011-07-03 13:36:17 -0300968{
Oliver Endriss0fe44622011-07-03 13:37:31 -0300969 if (IFAgc < 500) {
970 /* Scale this from 0 to 50000 */
Ralph Metzlere8783952011-07-03 13:36:17 -0300971 *pSignalStrength = IFAgc * 100;
972 } else {
Oliver Endriss0fe44622011-07-03 13:37:31 -0300973 /* Scale range 500-1500 to 50000-80000 */
Ralph Metzlere8783952011-07-03 13:36:17 -0300974 *pSignalStrength = 50000 + (IFAgc - 500) * 30;
975 }
976
977 return 0;
978}
979#endif
980
981static int get_frequency(struct dvb_frontend *fe, u32 *frequency)
982{
983 struct tda_state *state = fe->tuner_priv;
984
985 *frequency = state->IF;
986 return 0;
987}
988
989static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
990{
Oliver Endriss0fe44622011-07-03 13:37:31 -0300991 /* struct tda_state *state = fe->tuner_priv; */
992 /* *bandwidth = priv->bandwidth; */
Ralph Metzlere8783952011-07-03 13:36:17 -0300993 return 0;
994}
995
996
997static struct dvb_tuner_ops tuner_ops = {
998 .info = {
999 .name = "NXP TDA18271C2D",
1000 .frequency_min = 47125000,
1001 .frequency_max = 865000000,
1002 .frequency_step = 62500
1003 },
1004 .init = init,
1005 .sleep = sleep,
1006 .set_params = set_params,
1007 .release = release,
1008 .get_frequency = get_frequency,
1009 .get_bandwidth = get_bandwidth,
1010};
1011
1012struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
1013 struct i2c_adapter *i2c, u8 adr)
1014{
1015 struct tda_state *state;
1016
1017 state = kzalloc(sizeof(struct tda_state), GFP_KERNEL);
1018 if (!state)
1019 return NULL;
1020
1021 fe->tuner_priv = state;
1022 state->adr = adr;
1023 state->i2c = i2c;
1024 memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops));
1025 reset(state);
1026 InitCal(state);
1027
1028 return fe;
1029}
Ralph Metzlere8783952011-07-03 13:36:17 -03001030EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
Oliver Endriss0fe44622011-07-03 13:37:31 -03001031
Ralph Metzlere8783952011-07-03 13:36:17 -03001032MODULE_DESCRIPTION("TDA18271C2 driver");
1033MODULE_AUTHOR("DD");
1034MODULE_LICENSE("GPL");