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