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