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