blob: b4a23bf00104f85a1a8929afd3279bb751cef201 [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
67enum ERegister
68{
69 ID = 0,
70 TM,
71 PL,
72 EP1, EP2, EP3, EP4, EP5,
73 CPD, CD1, CD2, CD3,
74 MPD, MD1, MD2, MD3,
75 EB1, EB2, EB3, EB4, EB5, EB6, EB7, EB8, EB9, EB10,
76 EB11, EB12, EB13, EB14, EB15, EB16, EB17, EB18, EB19, EB20,
77 EB21, EB22, EB23,
78 NUM_REGS
79};
80
81struct tda_state {
82 struct i2c_adapter *i2c;
83 u8 adr;
84
85 u32 m_Frequency;
86 u32 IF;
87
88 u8 m_IFLevelAnalog;
89 u8 m_IFLevelDigital;
90 u8 m_IFLevelDVBC;
91 u8 m_IFLevelDVBT;
92
93 u8 m_EP4;
94 u8 m_EP3_Standby;
95
96 bool m_bMaster;
97
98 s32 m_SettlingTime;
99
100 u8 m_Regs[NUM_REGS];
101
102 /* Tracking filter settings for band 0..6 */
103 u32 m_RF1[7];
104 s32 m_RF_A1[7];
105 s32 m_RF_B1[7];
106 u32 m_RF2[7];
107 s32 m_RF_A2[7];
108 s32 m_RF_B2[7];
109 u32 m_RF3[7];
110
111 u8 m_TMValue_RFCal; /* Calibration temperatur */
112
113 bool m_bFMInput; /* true to use Pin 8 for FM Radio */
114
115};
116
117static int PowerScan(struct tda_state *state,
118 u8 RFBand,u32 RF_in,
119 u32 * pRF_Out, bool *pbcal);
120
121static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len)
122{
123 struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
124 .buf = data, .len = len}};
125 return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
126}
127
128static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
129{
130 struct i2c_msg msg = {.addr = adr, .flags = 0,
131 .buf = data, .len = len};
132
133 if (i2c_transfer(adap, &msg, 1) != 1) {
134 printk("i2c_write error\n");
135 return -1;
136 }
137 return 0;
138}
139
140static int WriteRegs(struct tda_state *state,
141 u8 SubAddr, u8 *Regs, u16 nRegs)
142{
143 u8 data[nRegs+1];
144
145 data[0] = SubAddr;
146 memcpy(data + 1, Regs, nRegs);
147 return i2c_write(state->i2c, state->adr, data, nRegs+1);
148}
149
150static int WriteReg(struct tda_state *state, u8 SubAddr,u8 Reg)
151{
152 u8 msg[2] = {SubAddr, Reg};
153
154 return i2c_write(state->i2c, state->adr, msg, 2);
155}
156
157static int Read(struct tda_state *state, u8 * Regs)
158{
159 return i2c_readn(state->i2c, state->adr, Regs, 16);
160}
161
162static int ReadExtented(struct tda_state *state, u8 * Regs)
163{
164 return i2c_readn(state->i2c, state->adr, Regs, NUM_REGS);
165}
166
167static int UpdateRegs(struct tda_state *state, u8 RegFrom,u8 RegTo)
168{
169 return WriteRegs(state, RegFrom,
170 &state->m_Regs[RegFrom], RegTo-RegFrom+1);
171}
172static int UpdateReg(struct tda_state *state, u8 Reg)
173{
174 return WriteReg(state, Reg,state->m_Regs[Reg]);
175}
176
177#include "tda18271c2dd_maps.h"
178
179#undef CHK_ERROR
180#define CHK_ERROR(s) if ((status = s) < 0) break
181
182static void reset(struct tda_state *state)
183{
184 u32 ulIFLevelAnalog = 0;
185 u32 ulIFLevelDigital = 2;
186 u32 ulIFLevelDVBC = 7;
187 u32 ulIFLevelDVBT = 6;
188 u32 ulXTOut = 0;
189 u32 ulStandbyMode = 0x06; // Send in stdb, but leave osc on
190 u32 ulSlave = 0;
191 u32 ulFMInput = 0;
192 u32 ulSettlingTime = 100;
193
194 state->m_Frequency = 0;
195 state->m_SettlingTime = 100;
196 state->m_IFLevelAnalog = (ulIFLevelAnalog & 0x07) << 2;
197 state->m_IFLevelDigital = (ulIFLevelDigital & 0x07) << 2;
198 state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07) << 2;
199 state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07) << 2;
200
201 state->m_EP4 = 0x20;
202 if( ulXTOut != 0 ) state->m_EP4 |= 0x40;
203
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
217 while ((Map[i].m_Frequency != 0) && (Frequency > Map[i].m_Frequency) )
218 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) &&
231 (Frequency > Map[i].m_Frequency) )
232 i += 1;
233 if (Map[i].m_Frequency == 0)
234 return false;
235 *pParam = Map[i].m_Param;
236 return true;
237}
238
239static bool SearchMap3(struct SMap2 Map[],u32 Frequency,
240 u8 *pParam1, u8 *pParam2)
241{
242 int i = 0;
243
244 while ((Map[i].m_Frequency != 0) &&
245 (Frequency > Map[i].m_Frequency) )
246 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;
274 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 ) ) {
278 state->m_Regs[TM] ^= 0x20;
279 CHK_ERROR(UpdateReg(state,TM));
280 msleep(10);
281 CHK_ERROR(Read(state,Regs));
282 }
283 *pTM_Value = (Regs[TM] & 0x20 ) ? m_Thermometer_Map_2[Regs[TM] & 0x0F] :
284 m_Thermometer_Map_1[Regs[TM] & 0x0F] ;
285 state->m_Regs[TM] &= ~0x10; // Thermometer off
286 CHK_ERROR(UpdateReg(state,TM));
287 state->m_Regs[EP4] &= ~0x03; // CAL_mode = 0 ?????????
288 CHK_ERROR(UpdateReg(state,EP4));
289 } while(0);
290
291 return status;
292}
293
294static int StandBy(struct tda_state *state)
295{
296 int status = 0;
297 do {
298 state->m_Regs[EB12] &= ~0x20; // PD_AGC1_Det = 0
299 CHK_ERROR(UpdateReg(state,EB12));
300 state->m_Regs[EB18] &= ~0x83; // AGC1_loop_off = 0, AGC1_Gain = 6 dB
301 CHK_ERROR(UpdateReg(state,EB18));
302 state->m_Regs[EB21] |= 0x03; // AGC2_Gain = -6 dB
303 state->m_Regs[EP3] = state->m_EP3_Standby;
304 CHK_ERROR(UpdateReg(state,EP3));
305 state->m_Regs[EB23] &= ~0x06; // ForceLP_Fc2_En = 0, LP_Fc[2] = 0
306 CHK_ERROR(UpdateRegs(state,EB21,EB23));
307 } while(0);
308 return status;
309}
310
311static int CalcMainPLL(struct tda_state *state, u32 freq)
312{
313
314 u8 PostDiv;
315 u8 Div;
316 u64 OscFreq;
317 u32 MainDiv;
318
319 if (!SearchMap3(m_Main_PLL_Map, freq, &PostDiv, &Div)) {
320 return -EINVAL;
321 }
322
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);
331 state->m_Regs[MD3] = ((MainDiv ) & 0xFF);
332
333 return UpdateRegs(state, MPD, MD3);
334}
335
336static int CalcCalPLL(struct tda_state *state, u32 freq)
337{
338 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "(%d)\n",freq));
339
340 u8 PostDiv;
341 u8 Div;
342 u64 OscFreq;
343 u32 CalDiv;
344
345 if( !SearchMap3(m_Cal_PLL_Map,freq,&PostDiv,&Div) )
346 {
347 return -EINVAL;
348 }
349
350 OscFreq = (u64)freq * (u64)Div;
351 //CalDiv = u32( OscFreq * 16384 / 16000000 );
352 OscFreq*=(u64)16384;
353 do_div(OscFreq, (u64)16000000);
354 CalDiv=OscFreq;
355
356 state->m_Regs[CPD] = PostDiv;
357 state->m_Regs[CD1] = ((CalDiv >> 16) & 0xFF);
358 state->m_Regs[CD2] = ((CalDiv >> 8) & 0xFF);
359 state->m_Regs[CD3] = ((CalDiv ) & 0xFF);
360
361 return UpdateRegs(state,CPD,CD3);
362}
363
364static int CalibrateRF(struct tda_state *state,
365 u8 RFBand,u32 freq, s32 * pCprog)
366{
367 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ " ID = %02x\n",state->m_Regs[ID]));
368 int status = 0;
369 u8 Regs[NUM_REGS];
370 do {
371 u8 BP_Filter=0;
372 u8 GainTaper=0;
373 u8 RFC_K=0;
374 u8 RFC_M=0;
375
376 state->m_Regs[EP4] &= ~0x03; // CAL_mode = 0
377 CHK_ERROR(UpdateReg(state,EP4));
378 state->m_Regs[EB18] |= 0x03; // AGC1_Gain = 3
379 CHK_ERROR(UpdateReg(state,EB18));
380
381 // Switching off LT (as datasheet says) causes calibration on C1 to fail
382 // (Readout of Cprog is allways 255)
383 if( state->m_Regs[ID] != 0x83 ) // C1: ID == 83, C2: ID == 84
384 {
385 state->m_Regs[EP3] |= 0x40; // SM_LT = 1
386 }
387
388 if( ! ( SearchMap1(m_BP_Filter_Map,freq,&BP_Filter) &&
389 SearchMap1(m_GainTaper_Map,freq,&GainTaper) &&
390 SearchMap3(m_KM_Map,freq,&RFC_K,&RFC_M)) )
391 {
392 return -EINVAL;
393 }
394
395 state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | BP_Filter;
396 state->m_Regs[EP2] = (RFBand << 5) | GainTaper;
397
398 state->m_Regs[EB13] = (state->m_Regs[EB13] & ~0x7C) | (RFC_K << 4) | (RFC_M << 2);
399
400 CHK_ERROR(UpdateRegs(state,EP1,EP3));
401 CHK_ERROR(UpdateReg(state,EB13));
402
403 state->m_Regs[EB4] |= 0x20; // LO_ForceSrce = 1
404 CHK_ERROR(UpdateReg(state,EB4));
405
406 state->m_Regs[EB7] |= 0x20; // CAL_ForceSrce = 1
407 CHK_ERROR(UpdateReg(state,EB7));
408
409 state->m_Regs[EB14] = 0; // RFC_Cprog = 0
410 CHK_ERROR(UpdateReg(state,EB14));
411
412 state->m_Regs[EB20] &= ~0x20; // ForceLock = 0;
413 CHK_ERROR(UpdateReg(state,EB20));
414
415 state->m_Regs[EP4] |= 0x03; // CAL_Mode = 3
416 CHK_ERROR(UpdateRegs(state,EP4,EP5));
417
418 CHK_ERROR(CalcCalPLL(state,freq));
419 CHK_ERROR(CalcMainPLL(state,freq + 1000000));
420
421 msleep(5);
422 CHK_ERROR(UpdateReg(state,EP2));
423 CHK_ERROR(UpdateReg(state,EP1));
424 CHK_ERROR(UpdateReg(state,EP2));
425 CHK_ERROR(UpdateReg(state,EP1));
426
427 state->m_Regs[EB4] &= ~0x20; // LO_ForceSrce = 0
428 CHK_ERROR(UpdateReg(state,EB4));
429
430 state->m_Regs[EB7] &= ~0x20; // CAL_ForceSrce = 0
431 CHK_ERROR(UpdateReg(state,EB7));
432 msleep(10);
433
434 state->m_Regs[EB20] |= 0x20; // ForceLock = 1;
435 CHK_ERROR(UpdateReg(state,EB20));
436 msleep(60);
437
438 state->m_Regs[EP4] &= ~0x03; // CAL_Mode = 0
439 state->m_Regs[EP3] &= ~0x40; // SM_LT = 0
440 state->m_Regs[EB18] &= ~0x03; // AGC1_Gain = 0
441 CHK_ERROR(UpdateReg(state,EB18));
442 CHK_ERROR(UpdateRegs(state,EP3,EP4));
443 CHK_ERROR(UpdateReg(state,EP1));
444
445 CHK_ERROR(ReadExtented(state,Regs));
446
447 *pCprog = Regs[EB14];
448 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ " Cprog = %d\n",Regs[EB14]));
449
450 } while(0);
451 return status;
452}
453
454static int RFTrackingFiltersInit(struct tda_state *state,
455 u8 RFBand)
456{
457 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
458 int status = 0;
459
460 u32 RF1 = m_RF_Band_Map[RFBand].m_RF1_Default;
461 u32 RF2 = m_RF_Band_Map[RFBand].m_RF2_Default;
462 u32 RF3 = m_RF_Band_Map[RFBand].m_RF3_Default;
463 bool bcal = false;
464
465 s32 Cprog_cal1 = 0;
466 s32 Cprog_table1 = 0;
467 s32 Cprog_cal2 = 0;
468 s32 Cprog_table2 = 0;
469 s32 Cprog_cal3 = 0;
470 s32 Cprog_table3 = 0;
471
472 state->m_RF_A1[RFBand] = 0;
473 state->m_RF_B1[RFBand] = 0;
474 state->m_RF_A2[RFBand] = 0;
475 state->m_RF_B2[RFBand] = 0;
476
477 do {
478 CHK_ERROR(PowerScan(state,RFBand,RF1,&RF1,&bcal));
479 if( bcal ) {
480 CHK_ERROR(CalibrateRF(state,RFBand,RF1,&Cprog_cal1));
481 }
482 SearchMap2(m_RF_Cal_Map,RF1,&Cprog_table1);
483 if( !bcal ) {
484 Cprog_cal1 = Cprog_table1;
485 }
486 state->m_RF_B1[RFBand] = Cprog_cal1 - Cprog_table1;
487 //state->m_RF_A1[RF_Band] = ????
488
489 if( RF2 == 0 ) break;
490
491 CHK_ERROR(PowerScan(state,RFBand,RF2,&RF2,&bcal));
492 if( bcal ) {
493 CHK_ERROR(CalibrateRF(state,RFBand,RF2,&Cprog_cal2));
494 }
495 SearchMap2(m_RF_Cal_Map,RF2,&Cprog_table2);
496 if( !bcal )
497 {
498 Cprog_cal2 = Cprog_table2;
499 }
500
501 state->m_RF_A1[RFBand] =
502 (Cprog_cal2 - Cprog_table2 - Cprog_cal1 + Cprog_table1) /
503 ((s32)(RF2)-(s32)(RF1));
504
505 if( RF3 == 0 ) break;
506
507 CHK_ERROR(PowerScan(state,RFBand,RF3,&RF3,&bcal));
508 if( bcal )
509 {
510 CHK_ERROR(CalibrateRF(state,RFBand,RF3,&Cprog_cal3));
511 }
512 SearchMap2(m_RF_Cal_Map,RF3,&Cprog_table3);
513 if( !bcal )
514 {
515 Cprog_cal3 = Cprog_table3;
516 }
517 state->m_RF_A2[RFBand] = (Cprog_cal3 - Cprog_table3 - Cprog_cal2 + Cprog_table2) / ((s32)(RF3)-(s32)(RF2));
518 state->m_RF_B2[RFBand] = Cprog_cal2 - Cprog_table2;
519
520 } while(0);
521
522 state->m_RF1[RFBand] = RF1;
523 state->m_RF2[RFBand] = RF2;
524 state->m_RF3[RFBand] = RF3;
525
526#if 0
527 printk("%s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __FUNCTION__,
528 RFBand,RF1,state->m_RF_A1[RFBand],state->m_RF_B1[RFBand],RF2,
529 state->m_RF_A2[RFBand],state->m_RF_B2[RFBand],RF3);
530#endif
531
532 return status;
533}
534
535static int PowerScan(struct tda_state *state,
536 u8 RFBand,u32 RF_in, u32 * pRF_Out, bool *pbcal)
537{
538 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "(%d,%d)\n",RFBand,RF_in));
539 int status = 0;
540 do {
541 u8 Gain_Taper=0;
542 s32 RFC_Cprog=0;
543 u8 CID_Target=0;
544 u8 CountLimit=0;
545 u32 freq_MainPLL;
546 u8 Regs[NUM_REGS];
547 u8 CID_Gain;
548 s32 Count = 0;
549 int sign = 1;
550 bool wait = false;
551
552 if( ! (SearchMap2(m_RF_Cal_Map,RF_in,&RFC_Cprog) &&
553 SearchMap1(m_GainTaper_Map,RF_in,&Gain_Taper) &&
554 SearchMap3(m_CID_Target_Map,RF_in,&CID_Target,&CountLimit) )) {
555 printk("%s Search map failed\n", __FUNCTION__);
556 return -EINVAL;
557 }
558
559 state->m_Regs[EP2] = (RFBand << 5) | Gain_Taper;
560 state->m_Regs[EB14] = (RFC_Cprog);
561 CHK_ERROR(UpdateReg(state,EP2));
562 CHK_ERROR(UpdateReg(state,EB14));
563
564 freq_MainPLL = RF_in + 1000000;
565 CHK_ERROR(CalcMainPLL(state,freq_MainPLL));
566 msleep(5);
567 state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x03) | 1; // CAL_mode = 1
568 CHK_ERROR(UpdateReg(state,EP4));
569 CHK_ERROR(UpdateReg(state,EP2)); // Launch power measurement
570 CHK_ERROR(ReadExtented(state,Regs));
571 CID_Gain = Regs[EB10] & 0x3F;
572 state->m_Regs[ID] = Regs[ID]; // Chip version, (needed for C1 workarround in CalibrateRF )
573
574 *pRF_Out = RF_in;
575
576 while( CID_Gain < CID_Target ) {
577 freq_MainPLL = RF_in + sign * Count + 1000000;
578 CHK_ERROR(CalcMainPLL(state,freq_MainPLL));
579 msleep( wait ? 5 : 1 );
580 wait = false;
581 CHK_ERROR(UpdateReg(state,EP2)); // Launch power measurement
582 CHK_ERROR(ReadExtented(state,Regs));
583 CID_Gain = Regs[EB10] & 0x3F;
584 Count += 200000;
585
586 if( Count < CountLimit * 100000 ) continue;
587 if( sign < 0 ) break;
588
589 sign = -sign;
590 Count = 200000;
591 wait = true;
592 }
593 CHK_ERROR(status);
594 if( CID_Gain >= CID_Target )
595 {
596 *pbcal = true;
597 *pRF_Out = freq_MainPLL - 1000000;
598 }
599 else
600 {
601 *pbcal = false;
602 }
603 } while(0);
604 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ " Found = %d RF = %d\n",*pbcal,*pRF_Out));
605 return status;
606}
607
608static int PowerScanInit(struct tda_state *state)
609{
610 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
611 int status = 0;
612 do
613 {
614 state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | 0x12;
615 state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x1F); // If level = 0, Cal mode = 0
616 CHK_ERROR(UpdateRegs(state,EP3,EP4));
617 state->m_Regs[EB18] = (state->m_Regs[EB18] & ~0x03 ); // AGC 1 Gain = 0
618 CHK_ERROR(UpdateReg(state,EB18));
619 state->m_Regs[EB21] = (state->m_Regs[EB21] & ~0x03 ); // AGC 2 Gain = 0 (Datasheet = 3)
620 state->m_Regs[EB23] = (state->m_Regs[EB23] | 0x06 ); // ForceLP_Fc2_En = 1, LPFc[2] = 1
621 CHK_ERROR(UpdateRegs(state,EB21,EB23));
622 } while(0);
623 return status;
624}
625
626static int CalcRFFilterCurve(struct tda_state *state)
627{
628 //KdPrintEx((MSG_TRACE " - " __FUNCTION__ "\n"));
629 int status = 0;
630 do
631 {
632 msleep(200); // Temperature stabilisation
633 CHK_ERROR(PowerScanInit(state));
634 CHK_ERROR(RFTrackingFiltersInit(state,0));
635 CHK_ERROR(RFTrackingFiltersInit(state,1));
636 CHK_ERROR(RFTrackingFiltersInit(state,2));
637 CHK_ERROR(RFTrackingFiltersInit(state,3));
638 CHK_ERROR(RFTrackingFiltersInit(state,4));
639 CHK_ERROR(RFTrackingFiltersInit(state,5));
640 CHK_ERROR(RFTrackingFiltersInit(state,6));
641 CHK_ERROR(ThermometerRead(state,&state->m_TMValue_RFCal)); // also switches off Cal mode !!!
642 } while(0);
643
644 return status;
645}
646
647static int FixedContentsI2CUpdate(struct tda_state *state)
648{
649 static u8 InitRegs[] = {
650 0x08,0x80,0xC6,
651 0xDF,0x16,0x60,0x80,
652 0x80,0x00,0x00,0x00,
653 0x00,0x00,0x00,0x00,
654 0xFC,0x01,0x84,0x41,
655 0x01,0x84,0x40,0x07,
656 0x00,0x00,0x96,0x3F,
657 0xC1,0x00,0x8F,0x00,
658 0x00,0x8C,0x00,0x20,
659 0xB3,0x48,0xB0,
660 };
661 int status = 0;
662 memcpy(&state->m_Regs[TM],InitRegs,EB23-TM+1);
663 do {
664 CHK_ERROR(UpdateRegs(state,TM,EB23));
665
666 // AGC1 gain setup
667 state->m_Regs[EB17] = 0x00;
668 CHK_ERROR(UpdateReg(state,EB17));
669 state->m_Regs[EB17] = 0x03;
670 CHK_ERROR(UpdateReg(state,EB17));
671 state->m_Regs[EB17] = 0x43;
672 CHK_ERROR(UpdateReg(state,EB17));
673 state->m_Regs[EB17] = 0x4C;
674 CHK_ERROR(UpdateReg(state,EB17));
675
676 // IRC Cal Low band
677 state->m_Regs[EP3] = 0x1F;
678 state->m_Regs[EP4] = 0x66;
679 state->m_Regs[EP5] = 0x81;
680 state->m_Regs[CPD] = 0xCC;
681 state->m_Regs[CD1] = 0x6C;
682 state->m_Regs[CD2] = 0x00;
683 state->m_Regs[CD3] = 0x00;
684 state->m_Regs[MPD] = 0xC5;
685 state->m_Regs[MD1] = 0x77;
686 state->m_Regs[MD2] = 0x08;
687 state->m_Regs[MD3] = 0x00;
688 CHK_ERROR(UpdateRegs(state,EP2,MD3)); // diff between sw and datasheet (ep3-md3)
689
690 //state->m_Regs[EB4] = 0x61; // missing in sw
691 //CHK_ERROR(UpdateReg(state,EB4));
692 //msleep(1);
693 //state->m_Regs[EB4] = 0x41;
694 //CHK_ERROR(UpdateReg(state,EB4));
695
696 msleep(5);
697 CHK_ERROR(UpdateReg(state,EP1));
698 msleep(5);
699
700 state->m_Regs[EP5] = 0x85;
701 state->m_Regs[CPD] = 0xCB;
702 state->m_Regs[CD1] = 0x66;
703 state->m_Regs[CD2] = 0x70;
704 CHK_ERROR(UpdateRegs(state,EP3,CD3));
705 msleep(5);
706 CHK_ERROR(UpdateReg(state,EP2));
707 msleep(30);
708
709 // IRC Cal mid band
710 state->m_Regs[EP5] = 0x82;
711 state->m_Regs[CPD] = 0xA8;
712 state->m_Regs[CD2] = 0x00;
713 state->m_Regs[MPD] = 0xA1; // Datasheet = 0xA9
714 state->m_Regs[MD1] = 0x73;
715 state->m_Regs[MD2] = 0x1A;
716 CHK_ERROR(UpdateRegs(state,EP3,MD3));
717
718 msleep(5);
719 CHK_ERROR(UpdateReg(state,EP1));
720 msleep(5);
721
722 state->m_Regs[EP5] = 0x86;
723 state->m_Regs[CPD] = 0xA8;
724 state->m_Regs[CD1] = 0x66;
725 state->m_Regs[CD2] = 0xA0;
726 CHK_ERROR(UpdateRegs(state,EP3,CD3));
727 msleep(5);
728 CHK_ERROR(UpdateReg(state,EP2));
729 msleep(30);
730
731 // IRC Cal high band
732 state->m_Regs[EP5] = 0x83;
733 state->m_Regs[CPD] = 0x98;
734 state->m_Regs[CD1] = 0x65;
735 state->m_Regs[CD2] = 0x00;
736 state->m_Regs[MPD] = 0x91; // Datasheet = 0x91
737 state->m_Regs[MD1] = 0x71;
738 state->m_Regs[MD2] = 0xCD;
739 CHK_ERROR(UpdateRegs(state,EP3,MD3));
740 msleep(5);
741 CHK_ERROR(UpdateReg(state,EP1));
742 msleep(5);
743 state->m_Regs[EP5] = 0x87;
744 state->m_Regs[CD1] = 0x65;
745 state->m_Regs[CD2] = 0x50;
746 CHK_ERROR(UpdateRegs(state,EP3,CD3));
747 msleep(5);
748 CHK_ERROR(UpdateReg(state,EP2));
749 msleep(30);
750
751 // Back to normal
752 state->m_Regs[EP4] = 0x64;
753 CHK_ERROR(UpdateReg(state,EP4));
754 CHK_ERROR(UpdateReg(state,EP1));
755
756 } while(0);
757 return status;
758}
759
760static int InitCal(struct tda_state *state)
761{
762 int status = 0;
763
764 do
765 {
766 CHK_ERROR(FixedContentsI2CUpdate(state));
767 CHK_ERROR(CalcRFFilterCurve(state));
768 CHK_ERROR(StandBy(state));
769 //m_bInitDone = true;
770 } while(0);
771 return status;
772};
773
774static int RFTrackingFiltersCorrection(struct tda_state *state,
775 u32 Frequency)
776{
777 int status = 0;
778 s32 Cprog_table;
779 u8 RFBand;
780 u8 dCoverdT;
781
782 if( !SearchMap2(m_RF_Cal_Map,Frequency,&Cprog_table) ||
783 !SearchMap4(m_RF_Band_Map,Frequency,&RFBand) ||
784 !SearchMap1(m_RF_Cal_DC_Over_DT_Map,Frequency,&dCoverdT) )
785 {
786 return -EINVAL;
787 }
788
789 do
790 {
791 u8 TMValue_Current;
792 u32 RF1 = state->m_RF1[RFBand];
793 u32 RF2 = state->m_RF1[RFBand];
794 u32 RF3 = state->m_RF1[RFBand];
795 s32 RF_A1 = state->m_RF_A1[RFBand];
796 s32 RF_B1 = state->m_RF_B1[RFBand];
797 s32 RF_A2 = state->m_RF_A2[RFBand];
798 s32 RF_B2 = state->m_RF_B2[RFBand];
799 s32 Capprox = 0;
800 int TComp;
801
802 state->m_Regs[EP3] &= ~0xE0; // Power up
803 CHK_ERROR(UpdateReg(state,EP3));
804
805 CHK_ERROR(ThermometerRead(state,&TMValue_Current));
806
807 if( RF3 == 0 || Frequency < RF2 )
808 {
809 Capprox = RF_A1 * ((s32)(Frequency) - (s32)(RF1)) + RF_B1 + Cprog_table;
810 }
811 else
812 {
813 Capprox = RF_A2 * ((s32)(Frequency) - (s32)(RF2)) + RF_B2 + Cprog_table;
814 }
815
816 TComp = (int)(dCoverdT) * ((int)(TMValue_Current) - (int)(state->m_TMValue_RFCal))/1000;
817
818 Capprox += TComp;
819
820 if( Capprox < 0 ) Capprox = 0;
821 else if( Capprox > 255 ) Capprox = 255;
822
823
824 // TODO Temperature compensation. There is defenitely a scale factor
825 // missing in the datasheet, so leave it out for now.
826 state->m_Regs[EB14] = (Capprox );
827
828 CHK_ERROR(UpdateReg(state,EB14));
829
830 } while(0);
831 return status;
832}
833
834static int ChannelConfiguration(struct tda_state *state,
835 u32 Frequency, int Standard)
836{
837
838 s32 IntermediateFrequency = m_StandardTable[Standard].m_IFFrequency;
839 int status = 0;
840
841 u8 BP_Filter = 0;
842 u8 RF_Band = 0;
843 u8 GainTaper = 0;
844 u8 IR_Meas;
845
846 state->IF=IntermediateFrequency;
847 //printk("%s Freq = %d Standard = %d IF = %d\n",__FUNCTION__,Frequency,Standard,IntermediateFrequency);
848 // get values from tables
849
850 if(! ( SearchMap1(m_BP_Filter_Map,Frequency,&BP_Filter) &&
851 SearchMap1(m_GainTaper_Map,Frequency,&GainTaper) &&
852 SearchMap1(m_IR_Meas_Map,Frequency,&IR_Meas) &&
853 SearchMap4(m_RF_Band_Map,Frequency,&RF_Band) ) )
854 {
855 printk("%s SearchMap failed\n", __FUNCTION__);
856 return -EINVAL;
857 }
858
859 do
860 {
861 state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | m_StandardTable[Standard].m_EP3_4_0;
862 state->m_Regs[EP3] &= ~0x04; // switch RFAGC to high speed mode
863
864 // m_EP4 default for XToutOn, CAL_Mode (0)
865 state->m_Regs[EP4] = state->m_EP4 | ((Standard > HF_AnalogMax )? state->m_IFLevelDigital : state->m_IFLevelAnalog );
866 //state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
867 if( Standard <= HF_AnalogMax ) state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelAnalog;
868 else if( Standard <= HF_ATSC ) state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBT;
869 else if( Standard <= HF_DVBC ) state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBC;
870 else state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
871
872 if( (Standard == HF_FM_Radio) && state->m_bFMInput ) state->m_Regs[EP4] |= 80;
873
874 state->m_Regs[MPD] &= ~0x80;
875 if( Standard > HF_AnalogMax ) state->m_Regs[MPD] |= 0x80; // Add IF_notch for digital
876
877 state->m_Regs[EB22] = m_StandardTable[Standard].m_EB22;
878
879 // Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM )
880 if( Standard == HF_FM_Radio ) state->m_Regs[EB23] |= 0x06; // ForceLP_Fc2_En = 1, LPFc[2] = 1
881 else state->m_Regs[EB23] &= ~0x06; // ForceLP_Fc2_En = 0, LPFc[2] = 0
882
883 CHK_ERROR(UpdateRegs(state,EB22,EB23));
884
885 state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | 0x40 | BP_Filter; // Dis_Power_level = 1, Filter
886 state->m_Regs[EP5] = (state->m_Regs[EP5] & ~0x07) | IR_Meas;
887 state->m_Regs[EP2] = (RF_Band << 5) | GainTaper;
888
889 state->m_Regs[EB1] = (state->m_Regs[EB1] & ~0x07) |
890 (state->m_bMaster ? 0x04 : 0x00); // CALVCO_FortLOn = MS
891 // AGC1_always_master = 0
892 // AGC_firstn = 0
893 CHK_ERROR(UpdateReg(state,EB1));
894
895 if( state->m_bMaster )
896 {
897 CHK_ERROR(CalcMainPLL(state,Frequency + IntermediateFrequency));
898 CHK_ERROR(UpdateRegs(state,TM,EP5));
899 state->m_Regs[EB4] |= 0x20; // LO_forceSrce = 1
900 CHK_ERROR(UpdateReg(state,EB4));
901 msleep(1);
902 state->m_Regs[EB4] &= ~0x20; // LO_forceSrce = 0
903 CHK_ERROR(UpdateReg(state,EB4));
904 }
905 else
906 {
907 u8 PostDiv;
908 u8 Div;
909 CHK_ERROR(CalcCalPLL(state,Frequency + IntermediateFrequency));
910
911 SearchMap3(m_Cal_PLL_Map,Frequency + IntermediateFrequency,&PostDiv,&Div);
912 state->m_Regs[MPD] = (state->m_Regs[MPD] & ~0x7F) | (PostDiv & 0x77);
913 CHK_ERROR(UpdateReg(state,MPD));
914 CHK_ERROR(UpdateRegs(state,TM,EP5));
915
916 state->m_Regs[EB7] |= 0x20; // CAL_forceSrce = 1
917 CHK_ERROR(UpdateReg(state,EB7));
918 msleep(1);
919 state->m_Regs[EB7] &= ~0x20; // CAL_forceSrce = 0
920 CHK_ERROR(UpdateReg(state,EB7));
921 }
922 msleep(20);
923 if( Standard != HF_FM_Radio )
924 {
925 state->m_Regs[EP3] |= 0x04; // RFAGC to normal mode
926 }
927 CHK_ERROR(UpdateReg(state,EP3));
928
929 } while(0);
930 return status;
931}
932
933static int sleep(struct dvb_frontend* fe)
934{
935 struct tda_state *state = fe->tuner_priv;
936
937 StandBy(state);
938 return 0;
939}
940
941static int init(struct dvb_frontend* fe)
942{
943 //struct tda_state *state = fe->tuner_priv;
944 return 0;
945}
946
947static int release(struct dvb_frontend* fe)
948{
949 kfree(fe->tuner_priv);
950 fe->tuner_priv = NULL;
951 return 0;
952}
953
954static int set_params(struct dvb_frontend *fe,
955 struct dvb_frontend_parameters *params)
956{
957 struct tda_state *state = fe->tuner_priv;
958 int status = 0;
959 int Standard;
960
961 state->m_Frequency = params->frequency;
962
963 if (fe->ops.info.type == FE_OFDM)
964 switch (params->u.ofdm.bandwidth) {
965 case BANDWIDTH_6_MHZ:
966 Standard = HF_DVBT_6MHZ;
967 break;
968 case BANDWIDTH_7_MHZ:
969 Standard = HF_DVBT_7MHZ;
970 break;
971 default:
972 case BANDWIDTH_8_MHZ:
973 Standard = HF_DVBT_8MHZ;
974 break;
975 }
976 else if (fe->ops.info.type == FE_QAM) {
977 Standard = HF_DVBC_8MHZ;
978 } else
979 return -EINVAL;
980 do {
981 CHK_ERROR(RFTrackingFiltersCorrection(state,params->frequency));
982 CHK_ERROR(ChannelConfiguration(state,params->frequency,Standard));
983
984 msleep(state->m_SettlingTime); // Allow AGC's to settle down
985 } while(0);
986 return status;
987}
988
989#if 0
990static int GetSignalStrength(s32 * pSignalStrength,u32 RFAgc,u32 IFAgc)
991{
992 if( IFAgc < 500 ) {
993 // Scale this from 0 to 50000
994 *pSignalStrength = IFAgc * 100;
995 } else {
996 // Scale range 500-1500 to 50000-80000
997 *pSignalStrength = 50000 + (IFAgc - 500) * 30;
998 }
999
1000 return 0;
1001}
1002#endif
1003
1004static int get_frequency(struct dvb_frontend *fe, u32 *frequency)
1005{
1006 struct tda_state *state = fe->tuner_priv;
1007
1008 *frequency = state->IF;
1009 return 0;
1010}
1011
1012static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1013{
1014 //struct tda_state *state = fe->tuner_priv;
1015 //*bandwidth = priv->bandwidth;
1016 return 0;
1017}
1018
1019
1020static struct dvb_tuner_ops tuner_ops = {
1021 .info = {
1022 .name = "NXP TDA18271C2D",
1023 .frequency_min = 47125000,
1024 .frequency_max = 865000000,
1025 .frequency_step = 62500
1026 },
1027 .init = init,
1028 .sleep = sleep,
1029 .set_params = set_params,
1030 .release = release,
1031 .get_frequency = get_frequency,
1032 .get_bandwidth = get_bandwidth,
1033};
1034
1035struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
1036 struct i2c_adapter *i2c, u8 adr)
1037{
1038 struct tda_state *state;
1039
1040 state = kzalloc(sizeof(struct tda_state), GFP_KERNEL);
1041 if (!state)
1042 return NULL;
1043
1044 fe->tuner_priv = state;
1045 state->adr = adr;
1046 state->i2c = i2c;
1047 memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops));
1048 reset(state);
1049 InitCal(state);
1050
1051 return fe;
1052}
1053
1054EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
1055MODULE_DESCRIPTION("TDA18271C2 driver");
1056MODULE_AUTHOR("DD");
1057MODULE_LICENSE("GPL");
1058
1059/*
1060 * Local variables:
1061 * c-basic-offset: 8
1062 * End:
1063 */