1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * NXP TDA18250 silicon tuner driver |
4 | * |
5 | * Copyright (C) 2017 Olli Salonen <olli.salonen@iki.fi> |
6 | */ |
7 | |
8 | #include "tda18250_priv.h" |
9 | #include <linux/regmap.h> |
10 | |
11 | static const struct dvb_tuner_ops tda18250_ops; |
12 | |
13 | static int tda18250_power_control(struct dvb_frontend *fe, |
14 | unsigned int power_state) |
15 | { |
16 | struct i2c_client *client = fe->tuner_priv; |
17 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
18 | int ret; |
19 | unsigned int utmp; |
20 | |
21 | dev_dbg(&client->dev, "power state: %d" , power_state); |
22 | |
23 | switch (power_state) { |
24 | case TDA18250_POWER_NORMAL: |
25 | ret = regmap_write_bits(map: dev->regmap, R06_POWER2, mask: 0x07, val: 0x00); |
26 | if (ret) |
27 | goto err; |
28 | ret = regmap_write_bits(map: dev->regmap, R25_REF, mask: 0xc0, val: 0xc0); |
29 | if (ret) |
30 | goto err; |
31 | break; |
32 | case TDA18250_POWER_STANDBY: |
33 | if (dev->loopthrough) { |
34 | ret = regmap_write_bits(map: dev->regmap, |
35 | R25_REF, mask: 0xc0, val: 0x80); |
36 | if (ret) |
37 | goto err; |
38 | ret = regmap_write_bits(map: dev->regmap, |
39 | R06_POWER2, mask: 0x07, val: 0x02); |
40 | if (ret) |
41 | goto err; |
42 | ret = regmap_write_bits(map: dev->regmap, |
43 | R10_LT1, mask: 0x80, val: 0x00); |
44 | if (ret) |
45 | goto err; |
46 | } else { |
47 | ret = regmap_write_bits(map: dev->regmap, |
48 | R25_REF, mask: 0xc0, val: 0x80); |
49 | if (ret) |
50 | goto err; |
51 | ret = regmap_write_bits(map: dev->regmap, |
52 | R06_POWER2, mask: 0x07, val: 0x01); |
53 | if (ret) |
54 | goto err; |
55 | ret = regmap_read(map: dev->regmap, |
56 | R0D_AGC12, val: &utmp); |
57 | if (ret) |
58 | goto err; |
59 | ret = regmap_write_bits(map: dev->regmap, |
60 | R0D_AGC12, mask: 0x03, val: 0x03); |
61 | if (ret) |
62 | goto err; |
63 | ret = regmap_write_bits(map: dev->regmap, |
64 | R10_LT1, mask: 0x80, val: 0x80); |
65 | if (ret) |
66 | goto err; |
67 | ret = regmap_write_bits(map: dev->regmap, |
68 | R0D_AGC12, mask: 0x03, val: utmp & 0x03); |
69 | if (ret) |
70 | goto err; |
71 | } |
72 | break; |
73 | default: |
74 | ret = -EINVAL; |
75 | goto err; |
76 | } |
77 | |
78 | return 0; |
79 | err: |
80 | return ret; |
81 | } |
82 | |
83 | static int tda18250_wait_for_irq(struct dvb_frontend *fe, |
84 | int maxwait, int step, u8 irq) |
85 | { |
86 | struct i2c_client *client = fe->tuner_priv; |
87 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
88 | int ret; |
89 | unsigned long timeout; |
90 | bool triggered; |
91 | unsigned int utmp; |
92 | |
93 | triggered = false; |
94 | timeout = jiffies + msecs_to_jiffies(m: maxwait); |
95 | while (!time_after(jiffies, timeout)) { |
96 | // check for the IRQ |
97 | ret = regmap_read(map: dev->regmap, R08_IRQ1, val: &utmp); |
98 | if (ret) |
99 | goto err; |
100 | if ((utmp & irq) == irq) { |
101 | triggered = true; |
102 | break; |
103 | } |
104 | msleep(msecs: step); |
105 | } |
106 | |
107 | dev_dbg(&client->dev, "waited IRQ (0x%02x) %d ms, triggered: %s" , irq, |
108 | jiffies_to_msecs(jiffies) - |
109 | (jiffies_to_msecs(timeout) - maxwait), |
110 | triggered ? "true" : "false" ); |
111 | |
112 | if (!triggered) |
113 | return -ETIMEDOUT; |
114 | |
115 | return 0; |
116 | err: |
117 | return ret; |
118 | } |
119 | |
120 | static int tda18250_init(struct dvb_frontend *fe) |
121 | { |
122 | struct i2c_client *client = fe->tuner_priv; |
123 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
124 | int ret, i; |
125 | |
126 | /* default values for various regs */ |
127 | static const u8 init_regs[][2] = { |
128 | { R0C_AGC11, 0xc7 }, |
129 | { R0D_AGC12, 0x5d }, |
130 | { R0E_AGC13, 0x40 }, |
131 | { R0F_AGC14, 0x0e }, |
132 | { R10_LT1, 0x47 }, |
133 | { R11_LT2, 0x4e }, |
134 | { R12_AGC21, 0x26 }, |
135 | { R13_AGC22, 0x60 }, |
136 | { R18_AGC32, 0x37 }, |
137 | { R19_AGC33, 0x09 }, |
138 | { R1A_AGCK, 0x00 }, |
139 | { R1E_WI_FI, 0x29 }, |
140 | { R1F_RF_BPF, 0x06 }, |
141 | { R20_IR_MIX, 0xc6 }, |
142 | { R21_IF_AGC, 0x00 }, |
143 | { R2C_PS1, 0x75 }, |
144 | { R2D_PS2, 0x06 }, |
145 | { R2E_PS3, 0x07 }, |
146 | { R30_RSSI2, 0x0e }, |
147 | { R31_IRQ_CTRL, 0x00 }, |
148 | { R39_SD5, 0x00 }, |
149 | { R3B_REGU, 0x55 }, |
150 | { R3C_RCCAL1, 0xa7 }, |
151 | { R3F_IRCAL2, 0x85 }, |
152 | { R40_IRCAL3, 0x87 }, |
153 | { R41_IRCAL4, 0xc0 }, |
154 | { R43_PD1, 0x40 }, |
155 | { R44_PD2, 0xc0 }, |
156 | { R46_CPUMP, 0x0c }, |
157 | { R47_LNAPOL, 0x64 }, |
158 | { R4B_XTALOSC1, 0x30 }, |
159 | { R59_AGC2_UP2, 0x05 }, |
160 | { R5B_AGC_AUTO, 0x07 }, |
161 | { R5C_AGC_DEBUG, 0x00 }, |
162 | }; |
163 | |
164 | /* crystal related regs depend on frequency */ |
165 | static const u8 xtal_regs[][5] = { |
166 | /* reg: 4d 4e 4f 50 51 */ |
167 | [TDA18250_XTAL_FREQ_16MHZ] = { 0x3e, 0x80, 0x50, 0x00, 0x20 }, |
168 | [TDA18250_XTAL_FREQ_24MHZ] = { 0x5d, 0xc0, 0xec, 0x00, 0x18 }, |
169 | [TDA18250_XTAL_FREQ_25MHZ] = { 0x61, 0xa8, 0xec, 0x80, 0x19 }, |
170 | [TDA18250_XTAL_FREQ_27MHZ] = { 0x69, 0x78, 0x8d, 0x80, 0x1b }, |
171 | [TDA18250_XTAL_FREQ_30MHZ] = { 0x75, 0x30, 0x8f, 0x00, 0x1e }, |
172 | }; |
173 | |
174 | dev_dbg(&client->dev, "\n" ); |
175 | |
176 | ret = tda18250_power_control(fe, TDA18250_POWER_NORMAL); |
177 | if (ret) |
178 | goto err; |
179 | |
180 | msleep(msecs: 20); |
181 | |
182 | if (dev->warm) |
183 | goto warm; |
184 | |
185 | /* set initial register values */ |
186 | for (i = 0; i < ARRAY_SIZE(init_regs); i++) { |
187 | ret = regmap_write(map: dev->regmap, reg: init_regs[i][0], |
188 | val: init_regs[i][1]); |
189 | if (ret) |
190 | goto err; |
191 | } |
192 | |
193 | /* set xtal related regs */ |
194 | ret = regmap_bulk_write(map: dev->regmap, R4D_XTALFLX1, |
195 | val: xtal_regs[dev->xtal_freq], val_count: 5); |
196 | if (ret) |
197 | goto err; |
198 | |
199 | ret = regmap_write_bits(map: dev->regmap, R10_LT1, mask: 0x80, |
200 | val: dev->loopthrough ? 0x00 : 0x80); |
201 | if (ret) |
202 | goto err; |
203 | |
204 | /* clear IRQ */ |
205 | ret = regmap_write(map: dev->regmap, R0A_IRQ3, TDA18250_IRQ_HW_INIT); |
206 | if (ret) |
207 | goto err; |
208 | |
209 | /* start HW init */ |
210 | ret = regmap_write(map: dev->regmap, R2A_MSM1, val: 0x70); |
211 | if (ret) |
212 | goto err; |
213 | |
214 | ret = regmap_write(map: dev->regmap, R2B_MSM2, val: 0x01); |
215 | if (ret) |
216 | goto err; |
217 | |
218 | ret = tda18250_wait_for_irq(fe, maxwait: 500, step: 10, TDA18250_IRQ_HW_INIT); |
219 | if (ret) |
220 | goto err; |
221 | |
222 | /* tuner calibration */ |
223 | ret = regmap_write(map: dev->regmap, R2A_MSM1, val: 0x02); |
224 | if (ret) |
225 | goto err; |
226 | |
227 | ret = regmap_write(map: dev->regmap, R2B_MSM2, val: 0x01); |
228 | if (ret) |
229 | goto err; |
230 | |
231 | ret = tda18250_wait_for_irq(fe, maxwait: 500, step: 10, TDA18250_IRQ_CAL); |
232 | if (ret) |
233 | goto err; |
234 | |
235 | dev->warm = true; |
236 | |
237 | warm: |
238 | /* power up LNA */ |
239 | ret = regmap_write_bits(map: dev->regmap, R0C_AGC11, mask: 0x80, val: 0x00); |
240 | if (ret) |
241 | goto err; |
242 | |
243 | return 0; |
244 | err: |
245 | dev_dbg(&client->dev, "failed=%d" , ret); |
246 | return ret; |
247 | } |
248 | |
249 | static int tda18250_set_agc(struct dvb_frontend *fe) |
250 | { |
251 | struct i2c_client *client = fe->tuner_priv; |
252 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
253 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
254 | int ret; |
255 | u8 utmp, utmp2; |
256 | |
257 | dev_dbg(&client->dev, "\n" ); |
258 | |
259 | ret = regmap_write_bits(map: dev->regmap, R1F_RF_BPF, mask: 0x87, val: 0x06); |
260 | if (ret) |
261 | goto err; |
262 | |
263 | utmp = ((c->frequency < 100000000) && |
264 | ((c->delivery_system == SYS_DVBC_ANNEX_A) || |
265 | (c->delivery_system == SYS_DVBC_ANNEX_C)) && |
266 | (c->bandwidth_hz == 6000000)) ? 0x80 : 0x00; |
267 | ret = regmap_write(map: dev->regmap, R5A_H3H5, val: utmp); |
268 | if (ret) |
269 | goto err; |
270 | |
271 | /* AGC1 */ |
272 | switch (c->delivery_system) { |
273 | case SYS_ATSC: |
274 | case SYS_DVBT: |
275 | case SYS_DVBT2: |
276 | utmp = 4; |
277 | break; |
278 | default: /* DVB-C/QAM */ |
279 | switch (c->bandwidth_hz) { |
280 | case 6000000: |
281 | utmp = (c->frequency < 800000000) ? 6 : 4; |
282 | break; |
283 | default: /* 7.935 and 8 MHz */ |
284 | utmp = (c->frequency < 100000000) ? 2 : 3; |
285 | break; |
286 | } |
287 | break; |
288 | } |
289 | |
290 | ret = regmap_write_bits(map: dev->regmap, R0C_AGC11, mask: 0x07, val: utmp); |
291 | if (ret) |
292 | goto err; |
293 | |
294 | /* AGC2 */ |
295 | switch (c->delivery_system) { |
296 | case SYS_ATSC: |
297 | case SYS_DVBT: |
298 | case SYS_DVBT2: |
299 | utmp = (c->frequency < 320000000) ? 20 : 16; |
300 | utmp2 = (c->frequency < 320000000) ? 22 : 18; |
301 | break; |
302 | default: /* DVB-C/QAM */ |
303 | switch (c->bandwidth_hz) { |
304 | case 6000000: |
305 | if (c->frequency < 600000000) { |
306 | utmp = 18; |
307 | utmp2 = 22; |
308 | } else if (c->frequency < 800000000) { |
309 | utmp = 16; |
310 | utmp2 = 20; |
311 | } else { |
312 | utmp = 14; |
313 | utmp2 = 16; |
314 | } |
315 | break; |
316 | default: /* 7.935 and 8 MHz */ |
317 | utmp = (c->frequency < 320000000) ? 16 : 18; |
318 | utmp2 = (c->frequency < 320000000) ? 18 : 20; |
319 | break; |
320 | } |
321 | break; |
322 | } |
323 | ret = regmap_write_bits(map: dev->regmap, R58_AGC2_UP1, mask: 0x1f, val: utmp2+8); |
324 | if (ret) |
325 | goto err; |
326 | ret = regmap_write_bits(map: dev->regmap, R13_AGC22, mask: 0x1f, val: utmp); |
327 | if (ret) |
328 | goto err; |
329 | ret = regmap_write_bits(map: dev->regmap, R14_AGC23, mask: 0x1f, val: utmp2); |
330 | if (ret) |
331 | goto err; |
332 | |
333 | switch (c->delivery_system) { |
334 | case SYS_ATSC: |
335 | case SYS_DVBT: |
336 | case SYS_DVBT2: |
337 | utmp = 98; |
338 | break; |
339 | default: /* DVB-C/QAM */ |
340 | utmp = 90; |
341 | break; |
342 | } |
343 | ret = regmap_write_bits(map: dev->regmap, R16_AGC25, mask: 0xf8, val: utmp); |
344 | if (ret) |
345 | goto err; |
346 | |
347 | ret = regmap_write_bits(map: dev->regmap, R12_AGC21, mask: 0x60, |
348 | val: (c->frequency > 800000000) ? 0x40 : 0x20); |
349 | if (ret) |
350 | goto err; |
351 | |
352 | /* AGC3 */ |
353 | switch (c->delivery_system) { |
354 | case SYS_ATSC: |
355 | case SYS_DVBT: |
356 | case SYS_DVBT2: |
357 | utmp = (c->frequency < 320000000) ? 5 : 7; |
358 | utmp2 = (c->frequency < 320000000) ? 10 : 12; |
359 | break; |
360 | default: /* DVB-C/QAM */ |
361 | utmp = 7; |
362 | utmp2 = 12; |
363 | break; |
364 | } |
365 | ret = regmap_write(map: dev->regmap, R17_AGC31, val: (utmp << 4) | utmp2); |
366 | if (ret) |
367 | goto err; |
368 | |
369 | /* S2D */ |
370 | switch (c->delivery_system) { |
371 | case SYS_ATSC: |
372 | case SYS_DVBT: |
373 | case SYS_DVBT2: |
374 | if (c->bandwidth_hz == 8000000) |
375 | utmp = 0x04; |
376 | else |
377 | utmp = (c->frequency < 320000000) ? 0x04 : 0x02; |
378 | break; |
379 | default: /* DVB-C/QAM */ |
380 | if (c->bandwidth_hz == 6000000) |
381 | utmp = ((c->frequency > 172544000) && |
382 | (c->frequency < 320000000)) ? 0x04 : 0x02; |
383 | else /* 7.935 and 8 MHz */ |
384 | utmp = ((c->frequency > 320000000) && |
385 | (c->frequency < 600000000)) ? 0x02 : 0x04; |
386 | break; |
387 | } |
388 | ret = regmap_write_bits(map: dev->regmap, R20_IR_MIX, mask: 0x06, val: utmp); |
389 | if (ret) |
390 | goto err; |
391 | |
392 | switch (c->delivery_system) { |
393 | case SYS_ATSC: |
394 | case SYS_DVBT: |
395 | case SYS_DVBT2: |
396 | utmp = 0; |
397 | break; |
398 | default: /* DVB-C/QAM */ |
399 | utmp = (c->frequency < 600000000) ? 0 : 3; |
400 | break; |
401 | } |
402 | ret = regmap_write_bits(map: dev->regmap, R16_AGC25, mask: 0x03, val: utmp); |
403 | if (ret) |
404 | goto err; |
405 | |
406 | utmp = 0x09; |
407 | switch (c->delivery_system) { |
408 | case SYS_ATSC: |
409 | case SYS_DVBT: |
410 | case SYS_DVBT2: |
411 | if (c->bandwidth_hz == 8000000) |
412 | utmp = 0x0c; |
413 | break; |
414 | default: /* DVB-C/QAM */ |
415 | utmp = 0x0c; |
416 | break; |
417 | } |
418 | ret = regmap_write_bits(map: dev->regmap, R0F_AGC14, mask: 0x3f, val: utmp); |
419 | if (ret) |
420 | goto err; |
421 | |
422 | return 0; |
423 | err: |
424 | dev_dbg(&client->dev, "failed=%d" , ret); |
425 | return ret; |
426 | } |
427 | |
428 | static int tda18250_pll_calc(struct dvb_frontend *fe, u8 *rdiv, |
429 | u8 *ndiv, u8 *icp) |
430 | { |
431 | struct i2c_client *client = fe->tuner_priv; |
432 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
433 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
434 | int ret; |
435 | unsigned int uval, exp, lopd, scale; |
436 | unsigned long fvco; |
437 | |
438 | ret = regmap_read(map: dev->regmap, R34_MD1, val: &uval); |
439 | if (ret) |
440 | goto err; |
441 | |
442 | exp = (uval & 0x70) >> 4; |
443 | if (exp > 5) |
444 | exp = 0; |
445 | lopd = 1 << (exp - 1); |
446 | scale = uval & 0x0f; |
447 | fvco = lopd * scale * ((c->frequency / 1000) + dev->if_frequency); |
448 | |
449 | switch (dev->xtal_freq) { |
450 | case TDA18250_XTAL_FREQ_16MHZ: |
451 | *rdiv = 1; |
452 | *ndiv = 0; |
453 | *icp = (fvco < 6622000) ? 0x05 : 0x02; |
454 | break; |
455 | case TDA18250_XTAL_FREQ_24MHZ: |
456 | case TDA18250_XTAL_FREQ_25MHZ: |
457 | *rdiv = 3; |
458 | *ndiv = 1; |
459 | *icp = (fvco < 6622000) ? 0x05 : 0x02; |
460 | break; |
461 | case TDA18250_XTAL_FREQ_27MHZ: |
462 | if (fvco < 6643000) { |
463 | *rdiv = 2; |
464 | *ndiv = 0; |
465 | *icp = 0x05; |
466 | } else if (fvco < 6811000) { |
467 | *rdiv = 2; |
468 | *ndiv = 0; |
469 | *icp = 0x06; |
470 | } else { |
471 | *rdiv = 3; |
472 | *ndiv = 1; |
473 | *icp = 0x02; |
474 | } |
475 | break; |
476 | case TDA18250_XTAL_FREQ_30MHZ: |
477 | *rdiv = 2; |
478 | *ndiv = 0; |
479 | *icp = (fvco < 6811000) ? 0x05 : 0x02; |
480 | break; |
481 | default: |
482 | return -EINVAL; |
483 | } |
484 | |
485 | dev_dbg(&client->dev, |
486 | "lopd=%d scale=%u fvco=%lu, rdiv=%d ndiv=%d icp=%d" , |
487 | lopd, scale, fvco, *rdiv, *ndiv, *icp); |
488 | return 0; |
489 | err: |
490 | return ret; |
491 | } |
492 | |
493 | static int tda18250_set_params(struct dvb_frontend *fe) |
494 | { |
495 | struct i2c_client *client = fe->tuner_priv; |
496 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
497 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
498 | u32 if_khz; |
499 | int ret; |
500 | unsigned int i, j; |
501 | u8 utmp; |
502 | u8 buf[3]; |
503 | |
504 | #define REG 0 |
505 | #define MASK 1 |
506 | #define DVBT_6 2 |
507 | #define DVBT_7 3 |
508 | #define DVBT_8 4 |
509 | #define DVBC_6 5 |
510 | #define DVBC_8 6 |
511 | #define ATSC 7 |
512 | |
513 | static const u8 delsys_params[][16] = { |
514 | [REG] = { 0x22, 0x23, 0x24, 0x21, 0x0d, 0x0c, 0x0f, 0x14, |
515 | 0x0e, 0x12, 0x58, 0x59, 0x1a, 0x19, 0x1e, 0x30 }, |
516 | [MASK] = { 0x77, 0xff, 0xff, 0x87, 0xf0, 0x78, 0x07, 0xe0, |
517 | 0x60, 0x0f, 0x60, 0x0f, 0x33, 0x30, 0x80, 0x06 }, |
518 | [DVBT_6] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0, |
519 | 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 }, |
520 | [DVBT_7] = { 0x52, 0x03, 0x85, 0x82, 0x40, 0x48, 0x01, 0xe0, |
521 | 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 }, |
522 | [DVBT_8] = { 0x53, 0x03, 0x87, 0x82, 0x40, 0x48, 0x06, 0xe0, |
523 | 0x60, 0x07, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 }, |
524 | [DVBC_6] = { 0x32, 0x05, 0x86, 0x82, 0x50, 0x00, 0x06, 0x60, |
525 | 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 }, |
526 | [DVBC_8] = { 0x53, 0x03, 0x88, 0x82, 0x50, 0x00, 0x06, 0x60, |
527 | 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 }, |
528 | [ATSC] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0, |
529 | 0x40, 0x0e, 0x60, 0x05, 0x03, 0x00, 0x80, 0x04 }, |
530 | }; |
531 | |
532 | dev_dbg(&client->dev, |
533 | "delivery_system=%d frequency=%u bandwidth_hz=%u" , |
534 | c->delivery_system, c->frequency, c->bandwidth_hz); |
535 | |
536 | |
537 | switch (c->delivery_system) { |
538 | case SYS_ATSC: |
539 | j = ATSC; |
540 | if_khz = dev->if_atsc; |
541 | break; |
542 | case SYS_DVBT: |
543 | case SYS_DVBT2: |
544 | if (c->bandwidth_hz == 0) { |
545 | ret = -EINVAL; |
546 | goto err; |
547 | } else if (c->bandwidth_hz <= 6000000) { |
548 | j = DVBT_6; |
549 | if_khz = dev->if_dvbt_6; |
550 | } else if (c->bandwidth_hz <= 7000000) { |
551 | j = DVBT_7; |
552 | if_khz = dev->if_dvbt_7; |
553 | } else if (c->bandwidth_hz <= 8000000) { |
554 | j = DVBT_8; |
555 | if_khz = dev->if_dvbt_8; |
556 | } else { |
557 | ret = -EINVAL; |
558 | goto err; |
559 | } |
560 | break; |
561 | case SYS_DVBC_ANNEX_A: |
562 | case SYS_DVBC_ANNEX_C: |
563 | if (c->bandwidth_hz == 0) { |
564 | ret = -EINVAL; |
565 | goto err; |
566 | } else if (c->bandwidth_hz <= 6000000) { |
567 | j = DVBC_6; |
568 | if_khz = dev->if_dvbc_6; |
569 | } else if (c->bandwidth_hz <= 8000000) { |
570 | j = DVBC_8; |
571 | if_khz = dev->if_dvbc_8; |
572 | } else { |
573 | ret = -EINVAL; |
574 | goto err; |
575 | } |
576 | break; |
577 | default: |
578 | ret = -EINVAL; |
579 | dev_err(&client->dev, "unsupported delivery system=%d" , |
580 | c->delivery_system); |
581 | goto err; |
582 | } |
583 | |
584 | /* set delivery system dependent registers */ |
585 | for (i = 0; i < 16; i++) { |
586 | ret = regmap_write_bits(map: dev->regmap, reg: delsys_params[REG][i], |
587 | mask: delsys_params[MASK][i], val: delsys_params[j][i]); |
588 | if (ret) |
589 | goto err; |
590 | } |
591 | |
592 | /* set IF if needed */ |
593 | if (dev->if_frequency != if_khz) { |
594 | utmp = DIV_ROUND_CLOSEST(if_khz, 50); |
595 | ret = regmap_write(map: dev->regmap, R26_IF, val: utmp); |
596 | if (ret) |
597 | goto err; |
598 | dev->if_frequency = if_khz; |
599 | dev_dbg(&client->dev, "set IF=%u kHz" , if_khz); |
600 | |
601 | } |
602 | |
603 | ret = tda18250_set_agc(fe); |
604 | if (ret) |
605 | goto err; |
606 | |
607 | ret = regmap_write_bits(map: dev->regmap, R1A_AGCK, mask: 0x03, val: 0x01); |
608 | if (ret) |
609 | goto err; |
610 | |
611 | ret = regmap_write_bits(map: dev->regmap, R14_AGC23, mask: 0x40, val: 0x00); |
612 | if (ret) |
613 | goto err; |
614 | |
615 | /* set frequency */ |
616 | buf[0] = ((c->frequency / 1000) >> 16) & 0xff; |
617 | buf[1] = ((c->frequency / 1000) >> 8) & 0xff; |
618 | buf[2] = ((c->frequency / 1000) >> 0) & 0xff; |
619 | ret = regmap_bulk_write(map: dev->regmap, R27_RF1, val: buf, val_count: 3); |
620 | if (ret) |
621 | goto err; |
622 | |
623 | ret = regmap_write(map: dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE); |
624 | if (ret) |
625 | goto err; |
626 | |
627 | /* initial tune */ |
628 | ret = regmap_write(map: dev->regmap, R2A_MSM1, val: 0x01); |
629 | if (ret) |
630 | goto err; |
631 | |
632 | ret = regmap_write(map: dev->regmap, R2B_MSM2, val: 0x01); |
633 | if (ret) |
634 | goto err; |
635 | |
636 | ret = tda18250_wait_for_irq(fe, maxwait: 500, step: 10, TDA18250_IRQ_TUNE); |
637 | if (ret) |
638 | goto err; |
639 | |
640 | /* calc ndiv and rdiv */ |
641 | ret = tda18250_pll_calc(fe, rdiv: &buf[0], ndiv: &buf[1], icp: &buf[2]); |
642 | if (ret) |
643 | goto err; |
644 | |
645 | ret = regmap_write_bits(map: dev->regmap, R4F_XTALFLX3, mask: 0xe0, |
646 | val: (buf[0] << 6) | (buf[1] << 5)); |
647 | if (ret) |
648 | goto err; |
649 | |
650 | /* clear IRQ */ |
651 | ret = regmap_write(map: dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE); |
652 | if (ret) |
653 | goto err; |
654 | |
655 | ret = regmap_write_bits(map: dev->regmap, R46_CPUMP, mask: 0x07, val: 0x00); |
656 | if (ret) |
657 | goto err; |
658 | |
659 | ret = regmap_write_bits(map: dev->regmap, R39_SD5, mask: 0x03, val: 0x00); |
660 | if (ret) |
661 | goto err; |
662 | |
663 | /* tune again */ |
664 | ret = regmap_write(map: dev->regmap, R2A_MSM1, val: 0x01); /* tune */ |
665 | if (ret) |
666 | goto err; |
667 | |
668 | ret = regmap_write(map: dev->regmap, R2B_MSM2, val: 0x01); /* go */ |
669 | if (ret) |
670 | goto err; |
671 | |
672 | ret = tda18250_wait_for_irq(fe, maxwait: 500, step: 10, TDA18250_IRQ_TUNE); |
673 | if (ret) |
674 | goto err; |
675 | |
676 | /* pll locking */ |
677 | msleep(msecs: 20); |
678 | |
679 | ret = regmap_write_bits(map: dev->regmap, R2B_MSM2, mask: 0x04, val: 0x04); |
680 | if (ret) |
681 | goto err; |
682 | |
683 | msleep(msecs: 20); |
684 | |
685 | /* restore AGCK */ |
686 | ret = regmap_write_bits(map: dev->regmap, R1A_AGCK, mask: 0x03, val: 0x03); |
687 | if (ret) |
688 | goto err; |
689 | |
690 | ret = regmap_write_bits(map: dev->regmap, R14_AGC23, mask: 0x40, val: 0x40); |
691 | if (ret) |
692 | goto err; |
693 | |
694 | /* charge pump */ |
695 | ret = regmap_write_bits(map: dev->regmap, R46_CPUMP, mask: 0x07, val: buf[2]); |
696 | |
697 | return 0; |
698 | err: |
699 | return ret; |
700 | } |
701 | |
702 | static int tda18250_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) |
703 | { |
704 | struct i2c_client *client = fe->tuner_priv; |
705 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
706 | |
707 | *frequency = dev->if_frequency * 1000; |
708 | return 0; |
709 | } |
710 | |
711 | static int tda18250_sleep(struct dvb_frontend *fe) |
712 | { |
713 | struct i2c_client *client = fe->tuner_priv; |
714 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
715 | int ret; |
716 | |
717 | dev_dbg(&client->dev, "\n" ); |
718 | |
719 | /* power down LNA */ |
720 | ret = regmap_write_bits(map: dev->regmap, R0C_AGC11, mask: 0x80, val: 0x00); |
721 | if (ret) |
722 | return ret; |
723 | |
724 | /* set if freq to 0 in order to make sure it's set after wake up */ |
725 | dev->if_frequency = 0; |
726 | |
727 | ret = tda18250_power_control(fe, TDA18250_POWER_STANDBY); |
728 | return ret; |
729 | } |
730 | |
731 | static const struct dvb_tuner_ops tda18250_ops = { |
732 | .info = { |
733 | .name = "NXP TDA18250" , |
734 | .frequency_min_hz = 42 * MHz, |
735 | .frequency_max_hz = 870 * MHz, |
736 | }, |
737 | |
738 | .init = tda18250_init, |
739 | .set_params = tda18250_set_params, |
740 | .get_if_frequency = tda18250_get_if_frequency, |
741 | .sleep = tda18250_sleep, |
742 | }; |
743 | |
744 | static int tda18250_probe(struct i2c_client *client) |
745 | { |
746 | struct tda18250_config *cfg = client->dev.platform_data; |
747 | struct dvb_frontend *fe = cfg->fe; |
748 | struct tda18250_dev *dev; |
749 | int ret; |
750 | unsigned char chip_id[3]; |
751 | |
752 | /* some registers are always read from HW */ |
753 | static const struct regmap_range tda18250_yes_ranges[] = { |
754 | regmap_reg_range(R05_POWER1, R0B_IRQ4), |
755 | regmap_reg_range(R21_IF_AGC, R21_IF_AGC), |
756 | regmap_reg_range(R2A_MSM1, R2B_MSM2), |
757 | regmap_reg_range(R2F_RSSI1, R31_IRQ_CTRL), |
758 | }; |
759 | |
760 | static const struct regmap_access_table tda18250_volatile_table = { |
761 | .yes_ranges = tda18250_yes_ranges, |
762 | .n_yes_ranges = ARRAY_SIZE(tda18250_yes_ranges), |
763 | }; |
764 | |
765 | static const struct regmap_config tda18250_regmap_config = { |
766 | .reg_bits = 8, |
767 | .val_bits = 8, |
768 | .max_register = TDA18250_NUM_REGS - 1, |
769 | .volatile_table = &tda18250_volatile_table, |
770 | }; |
771 | |
772 | dev = kzalloc(size: sizeof(*dev), GFP_KERNEL); |
773 | if (!dev) { |
774 | ret = -ENOMEM; |
775 | goto err; |
776 | } |
777 | |
778 | i2c_set_clientdata(client, data: dev); |
779 | |
780 | dev->fe = cfg->fe; |
781 | dev->loopthrough = cfg->loopthrough; |
782 | if (cfg->xtal_freq < TDA18250_XTAL_FREQ_MAX) { |
783 | dev->xtal_freq = cfg->xtal_freq; |
784 | } else { |
785 | ret = -EINVAL; |
786 | dev_err(&client->dev, "xtal_freq invalid=%d" , cfg->xtal_freq); |
787 | goto err_kfree; |
788 | } |
789 | dev->if_dvbt_6 = cfg->if_dvbt_6; |
790 | dev->if_dvbt_7 = cfg->if_dvbt_7; |
791 | dev->if_dvbt_8 = cfg->if_dvbt_8; |
792 | dev->if_dvbc_6 = cfg->if_dvbc_6; |
793 | dev->if_dvbc_8 = cfg->if_dvbc_8; |
794 | dev->if_atsc = cfg->if_atsc; |
795 | |
796 | dev->if_frequency = 0; |
797 | dev->warm = false; |
798 | |
799 | dev->regmap = devm_regmap_init_i2c(client, &tda18250_regmap_config); |
800 | if (IS_ERR(ptr: dev->regmap)) { |
801 | ret = PTR_ERR(ptr: dev->regmap); |
802 | goto err_kfree; |
803 | } |
804 | |
805 | /* read the three chip ID registers */ |
806 | regmap_bulk_read(map: dev->regmap, R00_ID1, val: &chip_id, val_count: 3); |
807 | dev_dbg(&client->dev, "chip_id=%02x:%02x:%02x" , |
808 | chip_id[0], chip_id[1], chip_id[2]); |
809 | |
810 | switch (chip_id[0]) { |
811 | case 0xc7: |
812 | dev->slave = false; |
813 | break; |
814 | case 0x47: |
815 | dev->slave = true; |
816 | break; |
817 | default: |
818 | ret = -ENODEV; |
819 | goto err_kfree; |
820 | } |
821 | |
822 | if (chip_id[1] != 0x4a) { |
823 | ret = -ENODEV; |
824 | goto err_kfree; |
825 | } |
826 | |
827 | switch (chip_id[2]) { |
828 | case 0x20: |
829 | dev_info(&client->dev, |
830 | "NXP TDA18250AHN/%s successfully identified" , |
831 | dev->slave ? "S" : "M" ); |
832 | break; |
833 | case 0x21: |
834 | dev_info(&client->dev, |
835 | "NXP TDA18250BHN/%s successfully identified" , |
836 | dev->slave ? "S" : "M" ); |
837 | break; |
838 | default: |
839 | ret = -ENODEV; |
840 | goto err_kfree; |
841 | } |
842 | |
843 | fe->tuner_priv = client; |
844 | memcpy(&fe->ops.tuner_ops, &tda18250_ops, |
845 | sizeof(struct dvb_tuner_ops)); |
846 | |
847 | /* put the tuner in standby */ |
848 | tda18250_power_control(fe, TDA18250_POWER_STANDBY); |
849 | |
850 | return 0; |
851 | err_kfree: |
852 | kfree(objp: dev); |
853 | err: |
854 | dev_dbg(&client->dev, "failed=%d" , ret); |
855 | return ret; |
856 | } |
857 | |
858 | static void tda18250_remove(struct i2c_client *client) |
859 | { |
860 | struct tda18250_dev *dev = i2c_get_clientdata(client); |
861 | struct dvb_frontend *fe = dev->fe; |
862 | |
863 | dev_dbg(&client->dev, "\n" ); |
864 | |
865 | memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); |
866 | fe->tuner_priv = NULL; |
867 | kfree(objp: dev); |
868 | } |
869 | |
870 | static const struct i2c_device_id tda18250_id_table[] = { |
871 | {"tda18250" , 0}, |
872 | {} |
873 | }; |
874 | MODULE_DEVICE_TABLE(i2c, tda18250_id_table); |
875 | |
876 | static struct i2c_driver tda18250_driver = { |
877 | .driver = { |
878 | .name = "tda18250" , |
879 | }, |
880 | .probe = tda18250_probe, |
881 | .remove = tda18250_remove, |
882 | .id_table = tda18250_id_table, |
883 | }; |
884 | |
885 | module_i2c_driver(tda18250_driver); |
886 | |
887 | MODULE_DESCRIPTION("NXP TDA18250 silicon tuner driver" ); |
888 | MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>" ); |
889 | MODULE_LICENSE("GPL" ); |
890 | |