1 // SPDX-License-Identifier: GPL-2.0-only
3 * tda18271c2dd: Driver for the TDA18271C2 tuner
5 * Copyright (C) 2010 Digital Devices GmbH
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
{
56 EP1
, EP2
, EP3
, EP4
, EP5
,
59 EB1
, EB2
, EB3
, EB4
, EB5
, EB6
, EB7
, EB8
, EB9
, EB10
,
60 EB11
, EB12
, EB13
, EB14
, EB15
, EB16
, EB17
, EB18
, EB19
, EB20
,
66 struct i2c_adapter
*i2c
;
86 /* Tracking filter settings for band 0..6 */
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
);
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
)) {
131 "%s: i2c wr: len=%d is too big!\n",
132 KBUILD_MODNAME
, nRegs
);
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;
177 u32 ulStandbyMode
= 0x06; /* Send in stdb, but leave osc on */
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;
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(struct SMap Map
[],
202 u32 Frequency
, u8
*pParam
)
206 while ((Map
[i
].m_Frequency
!= 0) && (Frequency
> Map
[i
].m_Frequency
))
208 if (Map
[i
].m_Frequency
== 0)
210 *pParam
= Map
[i
].m_Param
;
214 static bool SearchMap2(struct SMapI Map
[],
215 u32 Frequency
, s32
*pParam
)
219 while ((Map
[i
].m_Frequency
!= 0) &&
220 (Frequency
> Map
[i
].m_Frequency
))
222 if (Map
[i
].m_Frequency
== 0)
224 *pParam
= Map
[i
].m_Param
;
228 static bool SearchMap3(struct SMap2 Map
[], u32 Frequency
,
229 u8
*pParam1
, u8
*pParam2
)
233 while ((Map
[i
].m_Frequency
!= 0) &&
234 (Frequency
> Map
[i
].m_Frequency
))
236 if (Map
[i
].m_Frequency
== 0)
238 *pParam1
= Map
[i
].m_Param1
;
239 *pParam2
= Map
[i
].m_Param2
;
243 static bool SearchMap4(struct SRFBandMap Map
[],
244 u32 Frequency
, u8
*pRFBand
)
248 while (i
< 7 && (Frequency
> Map
[i
].m_RF_max
))
256 static int ThermometerRead(struct tda_state
*state
, u8
*pTM_Value
)
262 state
->m_Regs
[TM
] |= 0x10;
263 status
= UpdateReg(state
, TM
);
266 status
= Read(state
, Regs
);
269 if (((Regs
[TM
] & 0x0F) == 0 && (Regs
[TM
] & 0x20) == 0x20) ||
270 ((Regs
[TM
] & 0x0F) == 8 && (Regs
[TM
] & 0x20) == 0x00)) {
271 state
->m_Regs
[TM
] ^= 0x20;
272 status
= UpdateReg(state
, TM
);
276 status
= Read(state
, Regs
);
280 *pTM_Value
= (Regs
[TM
] & 0x20)
281 ? m_Thermometer_Map_2
[Regs
[TM
] & 0x0F]
282 : m_Thermometer_Map_1
[Regs
[TM
] & 0x0F] ;
283 state
->m_Regs
[TM
] &= ~0x10; /* Thermometer off */
284 status
= UpdateReg(state
, TM
);
287 state
->m_Regs
[EP4
] &= ~0x03; /* CAL_mode = 0 ????????? */
288 status
= UpdateReg(state
, EP4
);
296 static int StandBy(struct tda_state
*state
)
300 state
->m_Regs
[EB12
] &= ~0x20; /* PD_AGC1_Det = 0 */
301 status
= UpdateReg(state
, EB12
);
304 state
->m_Regs
[EB18
] &= ~0x83; /* AGC1_loop_off = 0, AGC1_Gain = 6 dB */
305 status
= UpdateReg(state
, EB18
);
308 state
->m_Regs
[EB21
] |= 0x03; /* AGC2_Gain = -6 dB */
309 state
->m_Regs
[EP3
] = state
->m_EP3_Standby
;
310 status
= UpdateReg(state
, EP3
);
313 state
->m_Regs
[EB23
] &= ~0x06; /* ForceLP_Fc2_En = 0, LP_Fc[2] = 0 */
314 status
= UpdateRegs(state
, EB21
, EB23
);
321 static int CalcMainPLL(struct tda_state
*state
, u32 freq
)
329 if (!SearchMap3(m_Main_PLL_Map
, freq
, &PostDiv
, &Div
))
332 OscFreq
= (u64
) freq
* (u64
) Div
;
333 OscFreq
*= (u64
) 16384;
334 do_div(OscFreq
, (u64
)16000000);
337 state
->m_Regs
[MPD
] = PostDiv
& 0x77;
338 state
->m_Regs
[MD1
] = ((MainDiv
>> 16) & 0x7F);
339 state
->m_Regs
[MD2
] = ((MainDiv
>> 8) & 0xFF);
340 state
->m_Regs
[MD3
] = (MainDiv
& 0xFF);
342 return UpdateRegs(state
, MPD
, MD3
);
345 static int CalcCalPLL(struct tda_state
*state
, u32 freq
)
352 if (!SearchMap3(m_Cal_PLL_Map
, freq
, &PostDiv
, &Div
))
355 OscFreq
= (u64
)freq
* (u64
)Div
;
356 /* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
357 OscFreq
*= (u64
)16384;
358 do_div(OscFreq
, (u64
)16000000);
361 state
->m_Regs
[CPD
] = PostDiv
;
362 state
->m_Regs
[CD1
] = ((CalDiv
>> 16) & 0xFF);
363 state
->m_Regs
[CD2
] = ((CalDiv
>> 8) & 0xFF);
364 state
->m_Regs
[CD3
] = (CalDiv
& 0xFF);
366 return UpdateRegs(state
, CPD
, CD3
);
369 static int CalibrateRF(struct tda_state
*state
,
370 u8 RFBand
, u32 freq
, s32
*pCprog
)
380 state
->m_Regs
[EP4
] &= ~0x03; /* CAL_mode = 0 */
381 status
= UpdateReg(state
, EP4
);
384 state
->m_Regs
[EB18
] |= 0x03; /* AGC1_Gain = 3 */
385 status
= UpdateReg(state
, EB18
);
389 /* Switching off LT (as datasheet says) causes calibration on C1 to fail */
390 /* (Readout of Cprog is always 255) */
391 if (state
->m_Regs
[ID
] != 0x83) /* C1: ID == 83, C2: ID == 84 */
392 state
->m_Regs
[EP3
] |= 0x40; /* SM_LT = 1 */
394 if (!(SearchMap1(m_BP_Filter_Map
, freq
, &BP_Filter
) &&
395 SearchMap1(m_GainTaper_Map
, freq
, &GainTaper
) &&
396 SearchMap3(m_KM_Map
, freq
, &RFC_K
, &RFC_M
)))
399 state
->m_Regs
[EP1
] = (state
->m_Regs
[EP1
] & ~0x07) | BP_Filter
;
400 state
->m_Regs
[EP2
] = (RFBand
<< 5) | GainTaper
;
402 state
->m_Regs
[EB13
] = (state
->m_Regs
[EB13
] & ~0x7C) | (RFC_K
<< 4) | (RFC_M
<< 2);
404 status
= UpdateRegs(state
, EP1
, EP3
);
407 status
= UpdateReg(state
, EB13
);
411 state
->m_Regs
[EB4
] |= 0x20; /* LO_ForceSrce = 1 */
412 status
= UpdateReg(state
, EB4
);
416 state
->m_Regs
[EB7
] |= 0x20; /* CAL_ForceSrce = 1 */
417 status
= UpdateReg(state
, EB7
);
421 state
->m_Regs
[EB14
] = 0; /* RFC_Cprog = 0 */
422 status
= UpdateReg(state
, EB14
);
426 state
->m_Regs
[EB20
] &= ~0x20; /* ForceLock = 0; */
427 status
= UpdateReg(state
, EB20
);
431 state
->m_Regs
[EP4
] |= 0x03; /* CAL_Mode = 3 */
432 status
= UpdateRegs(state
, EP4
, EP5
);
436 status
= CalcCalPLL(state
, freq
);
439 status
= CalcMainPLL(state
, freq
+ 1000000);
444 status
= UpdateReg(state
, EP2
);
447 status
= UpdateReg(state
, EP1
);
450 status
= UpdateReg(state
, EP2
);
453 status
= UpdateReg(state
, EP1
);
457 state
->m_Regs
[EB4
] &= ~0x20; /* LO_ForceSrce = 0 */
458 status
= UpdateReg(state
, EB4
);
462 state
->m_Regs
[EB7
] &= ~0x20; /* CAL_ForceSrce = 0 */
463 status
= UpdateReg(state
, EB7
);
468 state
->m_Regs
[EB20
] |= 0x20; /* ForceLock = 1; */
469 status
= UpdateReg(state
, EB20
);
474 state
->m_Regs
[EP4
] &= ~0x03; /* CAL_Mode = 0 */
475 state
->m_Regs
[EP3
] &= ~0x40; /* SM_LT = 0 */
476 state
->m_Regs
[EB18
] &= ~0x03; /* AGC1_Gain = 0 */
477 status
= UpdateReg(state
, EB18
);
480 status
= UpdateRegs(state
, EP3
, EP4
);
483 status
= UpdateReg(state
, EP1
);
487 status
= ReadExtented(state
, Regs
);
491 *pCprog
= Regs
[EB14
];
497 static int RFTrackingFiltersInit(struct tda_state
*state
,
502 u32 RF1
= m_RF_Band_Map
[RFBand
].m_RF1_Default
;
503 u32 RF2
= m_RF_Band_Map
[RFBand
].m_RF2_Default
;
504 u32 RF3
= m_RF_Band_Map
[RFBand
].m_RF3_Default
;
508 s32 Cprog_table1
= 0;
510 s32 Cprog_table2
= 0;
512 s32 Cprog_table3
= 0;
514 state
->m_RF_A1
[RFBand
] = 0;
515 state
->m_RF_B1
[RFBand
] = 0;
516 state
->m_RF_A2
[RFBand
] = 0;
517 state
->m_RF_B2
[RFBand
] = 0;
520 status
= PowerScan(state
, RFBand
, RF1
, &RF1
, &bcal
);
524 status
= CalibrateRF(state
, RFBand
, RF1
, &Cprog_cal1
);
528 SearchMap2(m_RF_Cal_Map
, RF1
, &Cprog_table1
);
530 Cprog_cal1
= Cprog_table1
;
531 state
->m_RF_B1
[RFBand
] = Cprog_cal1
- Cprog_table1
;
532 /* state->m_RF_A1[RF_Band] = ???? */
537 status
= PowerScan(state
, RFBand
, RF2
, &RF2
, &bcal
);
541 status
= CalibrateRF(state
, RFBand
, RF2
, &Cprog_cal2
);
545 SearchMap2(m_RF_Cal_Map
, RF2
, &Cprog_table2
);
547 Cprog_cal2
= Cprog_table2
;
549 state
->m_RF_A1
[RFBand
] =
550 (Cprog_cal2
- Cprog_table2
- Cprog_cal1
+ Cprog_table1
) /
551 ((s32
)(RF2
) - (s32
)(RF1
));
556 status
= PowerScan(state
, RFBand
, RF3
, &RF3
, &bcal
);
560 status
= CalibrateRF(state
, RFBand
, RF3
, &Cprog_cal3
);
564 SearchMap2(m_RF_Cal_Map
, RF3
, &Cprog_table3
);
566 Cprog_cal3
= Cprog_table3
;
567 state
->m_RF_A2
[RFBand
] = (Cprog_cal3
- Cprog_table3
- Cprog_cal2
+ Cprog_table2
) / ((s32
)(RF3
) - (s32
)(RF2
));
568 state
->m_RF_B2
[RFBand
] = Cprog_cal2
- Cprog_table2
;
572 state
->m_RF1
[RFBand
] = RF1
;
573 state
->m_RF2
[RFBand
] = RF2
;
574 state
->m_RF3
[RFBand
] = RF3
;
577 printk(KERN_ERR
"tda18271c2dd: %s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __func__
,
578 RFBand
, RF1
, state
->m_RF_A1
[RFBand
], state
->m_RF_B1
[RFBand
], RF2
,
579 state
->m_RF_A2
[RFBand
], state
->m_RF_B2
[RFBand
], RF3
);
585 static int PowerScan(struct tda_state
*state
,
586 u8 RFBand
, u32 RF_in
, u32
*pRF_Out
, bool *pbcal
)
601 if (!(SearchMap2(m_RF_Cal_Map
, RF_in
, &RFC_Cprog
) &&
602 SearchMap1(m_GainTaper_Map
, RF_in
, &Gain_Taper
) &&
603 SearchMap3(m_CID_Target_Map
, RF_in
, &CID_Target
, &CountLimit
))) {
605 printk(KERN_ERR
"tda18271c2dd: %s Search map failed\n", __func__
);
609 state
->m_Regs
[EP2
] = (RFBand
<< 5) | Gain_Taper
;
610 state
->m_Regs
[EB14
] = (RFC_Cprog
);
611 status
= UpdateReg(state
, EP2
);
614 status
= UpdateReg(state
, EB14
);
618 freq_MainPLL
= RF_in
+ 1000000;
619 status
= CalcMainPLL(state
, freq_MainPLL
);
623 state
->m_Regs
[EP4
] = (state
->m_Regs
[EP4
] & ~0x03) | 1; /* CAL_mode = 1 */
624 status
= UpdateReg(state
, EP4
);
627 status
= UpdateReg(state
, EP2
); /* Launch power measurement */
630 status
= ReadExtented(state
, Regs
);
633 CID_Gain
= Regs
[EB10
] & 0x3F;
634 state
->m_Regs
[ID
] = Regs
[ID
]; /* Chip version, (needed for C1 workaround in CalibrateRF) */
638 while (CID_Gain
< CID_Target
) {
639 freq_MainPLL
= RF_in
+ sign
* Count
+ 1000000;
640 status
= CalcMainPLL(state
, freq_MainPLL
);
643 msleep(wait
? 5 : 1);
645 status
= UpdateReg(state
, EP2
); /* Launch power measurement */
648 status
= ReadExtented(state
, Regs
);
651 CID_Gain
= Regs
[EB10
] & 0x3F;
654 if (Count
< CountLimit
* 100000)
665 if (CID_Gain
>= CID_Target
) {
667 *pRF_Out
= freq_MainPLL
- 1000000;
675 static int PowerScanInit(struct tda_state
*state
)
679 state
->m_Regs
[EP3
] = (state
->m_Regs
[EP3
] & ~0x1F) | 0x12;
680 state
->m_Regs
[EP4
] = (state
->m_Regs
[EP4
] & ~0x1F); /* If level = 0, Cal mode = 0 */
681 status
= UpdateRegs(state
, EP3
, EP4
);
684 state
->m_Regs
[EB18
] = (state
->m_Regs
[EB18
] & ~0x03); /* AGC 1 Gain = 0 */
685 status
= UpdateReg(state
, EB18
);
688 state
->m_Regs
[EB21
] = (state
->m_Regs
[EB21
] & ~0x03); /* AGC 2 Gain = 0 (Datasheet = 3) */
689 state
->m_Regs
[EB23
] = (state
->m_Regs
[EB23
] | 0x06); /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
690 status
= UpdateRegs(state
, EB21
, EB23
);
697 static int CalcRFFilterCurve(struct tda_state
*state
)
701 msleep(200); /* Temperature stabilisation */
702 status
= PowerScanInit(state
);
705 status
= RFTrackingFiltersInit(state
, 0);
708 status
= RFTrackingFiltersInit(state
, 1);
711 status
= RFTrackingFiltersInit(state
, 2);
714 status
= RFTrackingFiltersInit(state
, 3);
717 status
= RFTrackingFiltersInit(state
, 4);
720 status
= RFTrackingFiltersInit(state
, 5);
723 status
= RFTrackingFiltersInit(state
, 6);
726 status
= ThermometerRead(state
, &state
->m_TMValue_RFCal
); /* also switches off Cal mode !!! */
734 static int FixedContentsI2CUpdate(struct tda_state
*state
)
736 static u8 InitRegs
[] = {
738 0xDF, 0x16, 0x60, 0x80,
739 0x80, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00,
741 0xFC, 0x01, 0x84, 0x41,
742 0x01, 0x84, 0x40, 0x07,
743 0x00, 0x00, 0x96, 0x3F,
744 0xC1, 0x00, 0x8F, 0x00,
745 0x00, 0x8C, 0x00, 0x20,
749 memcpy(&state
->m_Regs
[TM
], InitRegs
, EB23
- TM
+ 1);
751 status
= UpdateRegs(state
, TM
, EB23
);
755 /* AGC1 gain setup */
756 state
->m_Regs
[EB17
] = 0x00;
757 status
= UpdateReg(state
, EB17
);
760 state
->m_Regs
[EB17
] = 0x03;
761 status
= UpdateReg(state
, EB17
);
764 state
->m_Regs
[EB17
] = 0x43;
765 status
= UpdateReg(state
, EB17
);
768 state
->m_Regs
[EB17
] = 0x4C;
769 status
= UpdateReg(state
, EB17
);
773 /* IRC Cal Low band */
774 state
->m_Regs
[EP3
] = 0x1F;
775 state
->m_Regs
[EP4
] = 0x66;
776 state
->m_Regs
[EP5
] = 0x81;
777 state
->m_Regs
[CPD
] = 0xCC;
778 state
->m_Regs
[CD1
] = 0x6C;
779 state
->m_Regs
[CD2
] = 0x00;
780 state
->m_Regs
[CD3
] = 0x00;
781 state
->m_Regs
[MPD
] = 0xC5;
782 state
->m_Regs
[MD1
] = 0x77;
783 state
->m_Regs
[MD2
] = 0x08;
784 state
->m_Regs
[MD3
] = 0x00;
785 status
= UpdateRegs(state
, EP2
, MD3
); /* diff between sw and datasheet (ep3-md3) */
790 state
->m_Regs
[EB4
] = 0x61; /* missing in sw */
791 status
= UpdateReg(state
, EB4
);
795 state
->m_Regs
[EB4
] = 0x41;
796 status
= UpdateReg(state
, EB4
);
802 status
= UpdateReg(state
, EP1
);
807 state
->m_Regs
[EP5
] = 0x85;
808 state
->m_Regs
[CPD
] = 0xCB;
809 state
->m_Regs
[CD1
] = 0x66;
810 state
->m_Regs
[CD2
] = 0x70;
811 status
= UpdateRegs(state
, EP3
, CD3
);
815 status
= UpdateReg(state
, EP2
);
820 /* IRC Cal mid band */
821 state
->m_Regs
[EP5
] = 0x82;
822 state
->m_Regs
[CPD
] = 0xA8;
823 state
->m_Regs
[CD2
] = 0x00;
824 state
->m_Regs
[MPD
] = 0xA1; /* Datasheet = 0xA9 */
825 state
->m_Regs
[MD1
] = 0x73;
826 state
->m_Regs
[MD2
] = 0x1A;
827 status
= UpdateRegs(state
, EP3
, MD3
);
832 status
= UpdateReg(state
, EP1
);
837 state
->m_Regs
[EP5
] = 0x86;
838 state
->m_Regs
[CPD
] = 0xA8;
839 state
->m_Regs
[CD1
] = 0x66;
840 state
->m_Regs
[CD2
] = 0xA0;
841 status
= UpdateRegs(state
, EP3
, CD3
);
845 status
= UpdateReg(state
, EP2
);
850 /* IRC Cal high band */
851 state
->m_Regs
[EP5
] = 0x83;
852 state
->m_Regs
[CPD
] = 0x98;
853 state
->m_Regs
[CD1
] = 0x65;
854 state
->m_Regs
[CD2
] = 0x00;
855 state
->m_Regs
[MPD
] = 0x91; /* Datasheet = 0x91 */
856 state
->m_Regs
[MD1
] = 0x71;
857 state
->m_Regs
[MD2
] = 0xCD;
858 status
= UpdateRegs(state
, EP3
, MD3
);
862 status
= UpdateReg(state
, EP1
);
866 state
->m_Regs
[EP5
] = 0x87;
867 state
->m_Regs
[CD1
] = 0x65;
868 state
->m_Regs
[CD2
] = 0x50;
869 status
= UpdateRegs(state
, EP3
, CD3
);
873 status
= UpdateReg(state
, EP2
);
879 state
->m_Regs
[EP4
] = 0x64;
880 status
= UpdateReg(state
, EP4
);
883 status
= UpdateReg(state
, EP1
);
891 static int InitCal(struct tda_state
*state
)
896 status
= FixedContentsI2CUpdate(state
);
899 status
= CalcRFFilterCurve(state
);
902 status
= StandBy(state
);
905 /* m_bInitDone = true; */
910 static int RFTrackingFiltersCorrection(struct tda_state
*state
,
918 if (!SearchMap2(m_RF_Cal_Map
, Frequency
, &Cprog_table
) ||
919 !SearchMap4(m_RF_Band_Map
, Frequency
, &RFBand
) ||
920 !SearchMap1(m_RF_Cal_DC_Over_DT_Map
, Frequency
, &dCoverdT
))
926 u32 RF1
= state
->m_RF1
[RFBand
];
927 u32 RF2
= state
->m_RF1
[RFBand
];
928 u32 RF3
= state
->m_RF1
[RFBand
];
929 s32 RF_A1
= state
->m_RF_A1
[RFBand
];
930 s32 RF_B1
= state
->m_RF_B1
[RFBand
];
931 s32 RF_A2
= state
->m_RF_A2
[RFBand
];
932 s32 RF_B2
= state
->m_RF_B2
[RFBand
];
936 state
->m_Regs
[EP3
] &= ~0xE0; /* Power up */
937 status
= UpdateReg(state
, EP3
);
941 status
= ThermometerRead(state
, &TMValue_Current
);
945 if (RF3
== 0 || Frequency
< RF2
)
946 Capprox
= RF_A1
* ((s32
)(Frequency
) - (s32
)(RF1
)) + RF_B1
+ Cprog_table
;
948 Capprox
= RF_A2
* ((s32
)(Frequency
) - (s32
)(RF2
)) + RF_B2
+ Cprog_table
;
950 TComp
= (int)(dCoverdT
) * ((int)(TMValue_Current
) - (int)(state
->m_TMValue_RFCal
))/1000;
956 else if (Capprox
> 255)
960 /* TODO Temperature compensation. There is defenitely a scale factor */
961 /* missing in the datasheet, so leave it out for now. */
962 state
->m_Regs
[EB14
] = Capprox
;
964 status
= UpdateReg(state
, EB14
);
972 static int ChannelConfiguration(struct tda_state
*state
,
973 u32 Frequency
, int Standard
)
976 s32 IntermediateFrequency
= m_StandardTable
[Standard
].m_IFFrequency
;
984 state
->IF
= IntermediateFrequency
;
985 /* printk("tda18271c2dd: %s Freq = %d Standard = %d IF = %d\n", __func__, Frequency, Standard, IntermediateFrequency); */
986 /* get values from tables */
988 if (!(SearchMap1(m_BP_Filter_Map
, Frequency
, &BP_Filter
) &&
989 SearchMap1(m_GainTaper_Map
, Frequency
, &GainTaper
) &&
990 SearchMap1(m_IR_Meas_Map
, Frequency
, &IR_Meas
) &&
991 SearchMap4(m_RF_Band_Map
, Frequency
, &RF_Band
))) {
993 printk(KERN_ERR
"tda18271c2dd: %s SearchMap failed\n", __func__
);
998 state
->m_Regs
[EP3
] = (state
->m_Regs
[EP3
] & ~0x1F) | m_StandardTable
[Standard
].m_EP3_4_0
;
999 state
->m_Regs
[EP3
] &= ~0x04; /* switch RFAGC to high speed mode */
1001 /* m_EP4 default for XToutOn, CAL_Mode (0) */
1002 state
->m_Regs
[EP4
] = state
->m_EP4
| ((Standard
> HF_AnalogMax
) ? state
->m_IFLevelDigital
: state
->m_IFLevelAnalog
);
1003 /* state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; */
1004 if (Standard
<= HF_AnalogMax
)
1005 state
->m_Regs
[EP4
] = state
->m_EP4
| state
->m_IFLevelAnalog
;
1006 else if (Standard
<= HF_ATSC
)
1007 state
->m_Regs
[EP4
] = state
->m_EP4
| state
->m_IFLevelDVBT
;
1008 else if (Standard
<= HF_DVBC
)
1009 state
->m_Regs
[EP4
] = state
->m_EP4
| state
->m_IFLevelDVBC
;
1011 state
->m_Regs
[EP4
] = state
->m_EP4
| state
->m_IFLevelDigital
;
1013 if ((Standard
== HF_FM_Radio
) && state
->m_bFMInput
)
1014 state
->m_Regs
[EP4
] |= 0x80;
1016 state
->m_Regs
[MPD
] &= ~0x80;
1017 if (Standard
> HF_AnalogMax
)
1018 state
->m_Regs
[MPD
] |= 0x80; /* Add IF_notch for digital */
1020 state
->m_Regs
[EB22
] = m_StandardTable
[Standard
].m_EB22
;
1022 /* Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM ) */
1023 if (Standard
== HF_FM_Radio
)
1024 state
->m_Regs
[EB23
] |= 0x06; /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
1026 state
->m_Regs
[EB23
] &= ~0x06; /* ForceLP_Fc2_En = 0, LPFc[2] = 0 */
1028 status
= UpdateRegs(state
, EB22
, EB23
);
1032 state
->m_Regs
[EP1
] = (state
->m_Regs
[EP1
] & ~0x07) | 0x40 | BP_Filter
; /* Dis_Power_level = 1, Filter */
1033 state
->m_Regs
[EP5
] = (state
->m_Regs
[EP5
] & ~0x07) | IR_Meas
;
1034 state
->m_Regs
[EP2
] = (RF_Band
<< 5) | GainTaper
;
1036 state
->m_Regs
[EB1
] = (state
->m_Regs
[EB1
] & ~0x07) |
1037 (state
->m_bMaster
? 0x04 : 0x00); /* CALVCO_FortLOn = MS */
1038 /* AGC1_always_master = 0 */
1039 /* AGC_firstn = 0 */
1040 status
= UpdateReg(state
, EB1
);
1044 if (state
->m_bMaster
) {
1045 status
= CalcMainPLL(state
, Frequency
+ IntermediateFrequency
);
1048 status
= UpdateRegs(state
, TM
, EP5
);
1051 state
->m_Regs
[EB4
] |= 0x20; /* LO_forceSrce = 1 */
1052 status
= UpdateReg(state
, EB4
);
1056 state
->m_Regs
[EB4
] &= ~0x20; /* LO_forceSrce = 0 */
1057 status
= UpdateReg(state
, EB4
);
1063 status
= CalcCalPLL(state
, Frequency
+ IntermediateFrequency
);
1067 SearchMap3(m_Cal_PLL_Map
, Frequency
+ IntermediateFrequency
, &PostDiv
, &Div
);
1068 state
->m_Regs
[MPD
] = (state
->m_Regs
[MPD
] & ~0x7F) | (PostDiv
& 0x77);
1069 status
= UpdateReg(state
, MPD
);
1072 status
= UpdateRegs(state
, TM
, EP5
);
1076 state
->m_Regs
[EB7
] |= 0x20; /* CAL_forceSrce = 1 */
1077 status
= UpdateReg(state
, EB7
);
1081 state
->m_Regs
[EB7
] &= ~0x20; /* CAL_forceSrce = 0 */
1082 status
= UpdateReg(state
, EB7
);
1087 if (Standard
!= HF_FM_Radio
)
1088 state
->m_Regs
[EP3
] |= 0x04; /* RFAGC to normal mode */
1089 status
= UpdateReg(state
, EP3
);
1097 static int sleep(struct dvb_frontend
*fe
)
1099 struct tda_state
*state
= fe
->tuner_priv
;
1105 static int init(struct dvb_frontend
*fe
)
1110 static void release(struct dvb_frontend
*fe
)
1112 kfree(fe
->tuner_priv
);
1113 fe
->tuner_priv
= NULL
;
1117 static int set_params(struct dvb_frontend
*fe
)
1119 struct tda_state
*state
= fe
->tuner_priv
;
1122 u32 bw
= fe
->dtv_property_cache
.bandwidth_hz
;
1123 u32 delsys
= fe
->dtv_property_cache
.delivery_system
;
1125 state
->m_Frequency
= fe
->dtv_property_cache
.frequency
;
1132 Standard
= HF_DVBT_6MHZ
;
1135 Standard
= HF_DVBT_7MHZ
;
1138 Standard
= HF_DVBT_8MHZ
;
1144 case SYS_DVBC_ANNEX_A
:
1145 case SYS_DVBC_ANNEX_C
:
1147 Standard
= HF_DVBC_6MHZ
;
1148 else if (bw
<= 7000000)
1149 Standard
= HF_DVBC_7MHZ
;
1151 Standard
= HF_DVBC_8MHZ
;
1157 status
= RFTrackingFiltersCorrection(state
, state
->m_Frequency
);
1160 status
= ChannelConfiguration(state
, state
->m_Frequency
,
1165 msleep(state
->m_SettlingTime
); /* Allow AGC's to settle down */
1171 static int GetSignalStrength(s32
*pSignalStrength
, u32 RFAgc
, u32 IFAgc
)
1174 /* Scale this from 0 to 50000 */
1175 *pSignalStrength
= IFAgc
* 100;
1177 /* Scale range 500-1500 to 50000-80000 */
1178 *pSignalStrength
= 50000 + (IFAgc
- 500) * 30;
1185 static int get_if_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
1187 struct tda_state
*state
= fe
->tuner_priv
;
1189 *frequency
= state
->IF
;
1193 static int get_bandwidth(struct dvb_frontend
*fe
, u32
*bandwidth
)
1195 /* struct tda_state *state = fe->tuner_priv; */
1196 /* *bandwidth = priv->bandwidth; */
1201 static const struct dvb_tuner_ops tuner_ops
= {
1203 .name
= "NXP TDA18271C2D",
1204 .frequency_min_hz
= 47125 * kHz
,
1205 .frequency_max_hz
= 865 * MHz
,
1206 .frequency_step_hz
= 62500
1210 .set_params
= set_params
,
1212 .get_if_frequency
= get_if_frequency
,
1213 .get_bandwidth
= get_bandwidth
,
1216 struct dvb_frontend
*tda18271c2dd_attach(struct dvb_frontend
*fe
,
1217 struct i2c_adapter
*i2c
, u8 adr
)
1219 struct tda_state
*state
;
1221 state
= kzalloc(sizeof(struct tda_state
), GFP_KERNEL
);
1225 fe
->tuner_priv
= state
;
1228 memcpy(&fe
->ops
.tuner_ops
, &tuner_ops
, sizeof(struct dvb_tuner_ops
));
1234 EXPORT_SYMBOL_GPL(tda18271c2dd_attach
);
1236 MODULE_DESCRIPTION("TDA18271C2 driver");
1237 MODULE_AUTHOR("DD");
1238 MODULE_LICENSE("GPL");