1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner |
4 | |
5 | Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org> |
6 | |
7 | */ |
8 | |
9 | #include "tda18271-priv.h" |
10 | |
11 | static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
12 | { |
13 | struct tda18271_priv *priv = fe->tuner_priv; |
14 | enum tda18271_i2c_gate gate; |
15 | int ret = 0; |
16 | |
17 | switch (priv->gate) { |
18 | case TDA18271_GATE_DIGITAL: |
19 | case TDA18271_GATE_ANALOG: |
20 | gate = priv->gate; |
21 | break; |
22 | case TDA18271_GATE_AUTO: |
23 | default: |
24 | switch (priv->mode) { |
25 | case TDA18271_DIGITAL: |
26 | gate = TDA18271_GATE_DIGITAL; |
27 | break; |
28 | case TDA18271_ANALOG: |
29 | default: |
30 | gate = TDA18271_GATE_ANALOG; |
31 | break; |
32 | } |
33 | } |
34 | |
35 | switch (gate) { |
36 | case TDA18271_GATE_ANALOG: |
37 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
38 | ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable); |
39 | break; |
40 | case TDA18271_GATE_DIGITAL: |
41 | if (fe->ops.i2c_gate_ctrl) |
42 | ret = fe->ops.i2c_gate_ctrl(fe, enable); |
43 | break; |
44 | default: |
45 | ret = -EINVAL; |
46 | break; |
47 | } |
48 | |
49 | return ret; |
50 | }; |
51 | |
52 | /*---------------------------------------------------------------------*/ |
53 | |
54 | static void tda18271_dump_regs(struct dvb_frontend *fe, int extended) |
55 | { |
56 | struct tda18271_priv *priv = fe->tuner_priv; |
57 | unsigned char *regs = priv->tda18271_regs; |
58 | |
59 | tda_reg("=== TDA18271 REG DUMP ===\n" ); |
60 | tda_reg("ID_BYTE = 0x%02x\n" , 0xff & regs[R_ID]); |
61 | tda_reg("THERMO_BYTE = 0x%02x\n" , 0xff & regs[R_TM]); |
62 | tda_reg("POWER_LEVEL_BYTE = 0x%02x\n" , 0xff & regs[R_PL]); |
63 | tda_reg("EASY_PROG_BYTE_1 = 0x%02x\n" , 0xff & regs[R_EP1]); |
64 | tda_reg("EASY_PROG_BYTE_2 = 0x%02x\n" , 0xff & regs[R_EP2]); |
65 | tda_reg("EASY_PROG_BYTE_3 = 0x%02x\n" , 0xff & regs[R_EP3]); |
66 | tda_reg("EASY_PROG_BYTE_4 = 0x%02x\n" , 0xff & regs[R_EP4]); |
67 | tda_reg("EASY_PROG_BYTE_5 = 0x%02x\n" , 0xff & regs[R_EP5]); |
68 | tda_reg("CAL_POST_DIV_BYTE = 0x%02x\n" , 0xff & regs[R_CPD]); |
69 | tda_reg("CAL_DIV_BYTE_1 = 0x%02x\n" , 0xff & regs[R_CD1]); |
70 | tda_reg("CAL_DIV_BYTE_2 = 0x%02x\n" , 0xff & regs[R_CD2]); |
71 | tda_reg("CAL_DIV_BYTE_3 = 0x%02x\n" , 0xff & regs[R_CD3]); |
72 | tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n" , 0xff & regs[R_MPD]); |
73 | tda_reg("MAIN_DIV_BYTE_1 = 0x%02x\n" , 0xff & regs[R_MD1]); |
74 | tda_reg("MAIN_DIV_BYTE_2 = 0x%02x\n" , 0xff & regs[R_MD2]); |
75 | tda_reg("MAIN_DIV_BYTE_3 = 0x%02x\n" , 0xff & regs[R_MD3]); |
76 | |
77 | /* only dump extended regs if DBG_ADV is set */ |
78 | if (!(tda18271_debug & DBG_ADV)) |
79 | return; |
80 | |
81 | /* W indicates write-only registers. |
82 | * Register dump for write-only registers shows last value written. */ |
83 | |
84 | tda_reg("EXTENDED_BYTE_1 = 0x%02x\n" , 0xff & regs[R_EB1]); |
85 | tda_reg("EXTENDED_BYTE_2 = 0x%02x\n" , 0xff & regs[R_EB2]); |
86 | tda_reg("EXTENDED_BYTE_3 = 0x%02x\n" , 0xff & regs[R_EB3]); |
87 | tda_reg("EXTENDED_BYTE_4 = 0x%02x\n" , 0xff & regs[R_EB4]); |
88 | tda_reg("EXTENDED_BYTE_5 = 0x%02x\n" , 0xff & regs[R_EB5]); |
89 | tda_reg("EXTENDED_BYTE_6 = 0x%02x\n" , 0xff & regs[R_EB6]); |
90 | tda_reg("EXTENDED_BYTE_7 = 0x%02x\n" , 0xff & regs[R_EB7]); |
91 | tda_reg("EXTENDED_BYTE_8 = 0x%02x\n" , 0xff & regs[R_EB8]); |
92 | tda_reg("EXTENDED_BYTE_9 W = 0x%02x\n" , 0xff & regs[R_EB9]); |
93 | tda_reg("EXTENDED_BYTE_10 = 0x%02x\n" , 0xff & regs[R_EB10]); |
94 | tda_reg("EXTENDED_BYTE_11 = 0x%02x\n" , 0xff & regs[R_EB11]); |
95 | tda_reg("EXTENDED_BYTE_12 = 0x%02x\n" , 0xff & regs[R_EB12]); |
96 | tda_reg("EXTENDED_BYTE_13 = 0x%02x\n" , 0xff & regs[R_EB13]); |
97 | tda_reg("EXTENDED_BYTE_14 = 0x%02x\n" , 0xff & regs[R_EB14]); |
98 | tda_reg("EXTENDED_BYTE_15 = 0x%02x\n" , 0xff & regs[R_EB15]); |
99 | tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n" , 0xff & regs[R_EB16]); |
100 | tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n" , 0xff & regs[R_EB17]); |
101 | tda_reg("EXTENDED_BYTE_18 = 0x%02x\n" , 0xff & regs[R_EB18]); |
102 | tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n" , 0xff & regs[R_EB19]); |
103 | tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n" , 0xff & regs[R_EB20]); |
104 | tda_reg("EXTENDED_BYTE_21 = 0x%02x\n" , 0xff & regs[R_EB21]); |
105 | tda_reg("EXTENDED_BYTE_22 = 0x%02x\n" , 0xff & regs[R_EB22]); |
106 | tda_reg("EXTENDED_BYTE_23 = 0x%02x\n" , 0xff & regs[R_EB23]); |
107 | } |
108 | |
109 | int tda18271_read_regs(struct dvb_frontend *fe) |
110 | { |
111 | struct tda18271_priv *priv = fe->tuner_priv; |
112 | unsigned char *regs = priv->tda18271_regs; |
113 | unsigned char buf = 0x00; |
114 | int ret; |
115 | struct i2c_msg msg[] = { |
116 | { .addr = priv->i2c_props.addr, .flags = 0, |
117 | .buf = &buf, .len = 1 }, |
118 | { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, |
119 | .buf = regs, .len = 16 } |
120 | }; |
121 | |
122 | tda18271_i2c_gate_ctrl(fe, enable: 1); |
123 | |
124 | /* read all registers */ |
125 | ret = i2c_transfer(adap: priv->i2c_props.adap, msgs: msg, num: 2); |
126 | |
127 | tda18271_i2c_gate_ctrl(fe, enable: 0); |
128 | |
129 | if (ret != 2) |
130 | tda_err("ERROR: i2c_transfer returned: %d\n" , ret); |
131 | |
132 | if (tda18271_debug & DBG_REG) |
133 | tda18271_dump_regs(fe, extended: 0); |
134 | |
135 | return (ret == 2 ? 0 : ret); |
136 | } |
137 | |
138 | int tda18271_read_extended(struct dvb_frontend *fe) |
139 | { |
140 | struct tda18271_priv *priv = fe->tuner_priv; |
141 | unsigned char *regs = priv->tda18271_regs; |
142 | unsigned char regdump[TDA18271_NUM_REGS]; |
143 | unsigned char buf = 0x00; |
144 | int ret, i; |
145 | struct i2c_msg msg[] = { |
146 | { .addr = priv->i2c_props.addr, .flags = 0, |
147 | .buf = &buf, .len = 1 }, |
148 | { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, |
149 | .buf = regdump, .len = TDA18271_NUM_REGS } |
150 | }; |
151 | |
152 | tda18271_i2c_gate_ctrl(fe, enable: 1); |
153 | |
154 | /* read all registers */ |
155 | ret = i2c_transfer(adap: priv->i2c_props.adap, msgs: msg, num: 2); |
156 | |
157 | tda18271_i2c_gate_ctrl(fe, enable: 0); |
158 | |
159 | if (ret != 2) |
160 | tda_err("ERROR: i2c_transfer returned: %d\n" , ret); |
161 | |
162 | for (i = 0; i < TDA18271_NUM_REGS; i++) { |
163 | /* don't update write-only registers */ |
164 | if ((i != R_EB9) && |
165 | (i != R_EB16) && |
166 | (i != R_EB17) && |
167 | (i != R_EB19) && |
168 | (i != R_EB20)) |
169 | regs[i] = regdump[i]; |
170 | } |
171 | |
172 | if (tda18271_debug & DBG_REG) |
173 | tda18271_dump_regs(fe, extended: 1); |
174 | |
175 | return (ret == 2 ? 0 : ret); |
176 | } |
177 | |
178 | static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len, |
179 | bool lock_i2c) |
180 | { |
181 | struct tda18271_priv *priv = fe->tuner_priv; |
182 | unsigned char *regs = priv->tda18271_regs; |
183 | unsigned char buf[TDA18271_NUM_REGS + 1]; |
184 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0, |
185 | .buf = buf }; |
186 | int i, ret = 1, max; |
187 | |
188 | BUG_ON((len == 0) || (idx + len > sizeof(buf))); |
189 | |
190 | switch (priv->small_i2c) { |
191 | case TDA18271_03_BYTE_CHUNK_INIT: |
192 | max = 3; |
193 | break; |
194 | case TDA18271_08_BYTE_CHUNK_INIT: |
195 | max = 8; |
196 | break; |
197 | case TDA18271_16_BYTE_CHUNK_INIT: |
198 | max = 16; |
199 | break; |
200 | case TDA18271_39_BYTE_CHUNK_INIT: |
201 | default: |
202 | max = 39; |
203 | } |
204 | |
205 | |
206 | /* |
207 | * If lock_i2c is true, it will take the I2C bus for tda18271 private |
208 | * usage during the entire write ops, as otherwise, bad things could |
209 | * happen. |
210 | * During device init, several write operations will happen. So, |
211 | * tda18271_init_regs controls the I2C lock directly, |
212 | * disabling lock_i2c here. |
213 | */ |
214 | if (lock_i2c) { |
215 | tda18271_i2c_gate_ctrl(fe, enable: 1); |
216 | i2c_lock_bus(adapter: priv->i2c_props.adap, I2C_LOCK_SEGMENT); |
217 | } |
218 | while (len) { |
219 | if (max > len) |
220 | max = len; |
221 | |
222 | buf[0] = idx; |
223 | for (i = 1; i <= max; i++) |
224 | buf[i] = regs[idx - 1 + i]; |
225 | |
226 | msg.len = max + 1; |
227 | |
228 | /* write registers */ |
229 | ret = __i2c_transfer(adap: priv->i2c_props.adap, msgs: &msg, num: 1); |
230 | if (ret != 1) |
231 | break; |
232 | |
233 | idx += max; |
234 | len -= max; |
235 | } |
236 | if (lock_i2c) { |
237 | i2c_unlock_bus(adapter: priv->i2c_props.adap, I2C_LOCK_SEGMENT); |
238 | tda18271_i2c_gate_ctrl(fe, enable: 0); |
239 | } |
240 | |
241 | if (ret != 1) |
242 | tda_err("ERROR: idx = 0x%x, len = %d, i2c_transfer returned: %d\n" , |
243 | idx, max, ret); |
244 | |
245 | return (ret == 1 ? 0 : ret); |
246 | } |
247 | |
248 | int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) |
249 | { |
250 | return __tda18271_write_regs(fe, idx, len, lock_i2c: true); |
251 | } |
252 | |
253 | /*---------------------------------------------------------------------*/ |
254 | |
255 | static int __tda18271_charge_pump_source(struct dvb_frontend *fe, |
256 | enum tda18271_pll pll, int force, |
257 | bool lock_i2c) |
258 | { |
259 | struct tda18271_priv *priv = fe->tuner_priv; |
260 | unsigned char *regs = priv->tda18271_regs; |
261 | |
262 | int r_cp = (pll == TDA18271_CAL_PLL) ? R_EB7 : R_EB4; |
263 | |
264 | regs[r_cp] &= ~0x20; |
265 | regs[r_cp] |= ((force & 1) << 5); |
266 | |
267 | return __tda18271_write_regs(fe, idx: r_cp, len: 1, lock_i2c); |
268 | } |
269 | |
270 | int tda18271_charge_pump_source(struct dvb_frontend *fe, |
271 | enum tda18271_pll pll, int force) |
272 | { |
273 | return __tda18271_charge_pump_source(fe, pll, force, lock_i2c: true); |
274 | } |
275 | |
276 | |
277 | int tda18271_init_regs(struct dvb_frontend *fe) |
278 | { |
279 | struct tda18271_priv *priv = fe->tuner_priv; |
280 | unsigned char *regs = priv->tda18271_regs; |
281 | |
282 | tda_dbg("initializing registers for device @ %d-%04x\n" , |
283 | i2c_adapter_id(priv->i2c_props.adap), |
284 | priv->i2c_props.addr); |
285 | |
286 | /* |
287 | * Don't let any other I2C transfer to happen at adapter during init, |
288 | * as those could cause bad things |
289 | */ |
290 | tda18271_i2c_gate_ctrl(fe, enable: 1); |
291 | i2c_lock_bus(adapter: priv->i2c_props.adap, I2C_LOCK_SEGMENT); |
292 | |
293 | /* initialize registers */ |
294 | switch (priv->id) { |
295 | case TDA18271HDC1: |
296 | regs[R_ID] = 0x83; |
297 | break; |
298 | case TDA18271HDC2: |
299 | regs[R_ID] = 0x84; |
300 | break; |
301 | } |
302 | |
303 | regs[R_TM] = 0x08; |
304 | regs[R_PL] = 0x80; |
305 | regs[R_EP1] = 0xc6; |
306 | regs[R_EP2] = 0xdf; |
307 | regs[R_EP3] = 0x16; |
308 | regs[R_EP4] = 0x60; |
309 | regs[R_EP5] = 0x80; |
310 | regs[R_CPD] = 0x80; |
311 | regs[R_CD1] = 0x00; |
312 | regs[R_CD2] = 0x00; |
313 | regs[R_CD3] = 0x00; |
314 | regs[R_MPD] = 0x00; |
315 | regs[R_MD1] = 0x00; |
316 | regs[R_MD2] = 0x00; |
317 | regs[R_MD3] = 0x00; |
318 | |
319 | switch (priv->id) { |
320 | case TDA18271HDC1: |
321 | regs[R_EB1] = 0xff; |
322 | break; |
323 | case TDA18271HDC2: |
324 | regs[R_EB1] = 0xfc; |
325 | break; |
326 | } |
327 | |
328 | regs[R_EB2] = 0x01; |
329 | regs[R_EB3] = 0x84; |
330 | regs[R_EB4] = 0x41; |
331 | regs[R_EB5] = 0x01; |
332 | regs[R_EB6] = 0x84; |
333 | regs[R_EB7] = 0x40; |
334 | regs[R_EB8] = 0x07; |
335 | regs[R_EB9] = 0x00; |
336 | regs[R_EB10] = 0x00; |
337 | regs[R_EB11] = 0x96; |
338 | |
339 | switch (priv->id) { |
340 | case TDA18271HDC1: |
341 | regs[R_EB12] = 0x0f; |
342 | break; |
343 | case TDA18271HDC2: |
344 | regs[R_EB12] = 0x33; |
345 | break; |
346 | } |
347 | |
348 | regs[R_EB13] = 0xc1; |
349 | regs[R_EB14] = 0x00; |
350 | regs[R_EB15] = 0x8f; |
351 | regs[R_EB16] = 0x00; |
352 | regs[R_EB17] = 0x00; |
353 | |
354 | switch (priv->id) { |
355 | case TDA18271HDC1: |
356 | regs[R_EB18] = 0x00; |
357 | break; |
358 | case TDA18271HDC2: |
359 | regs[R_EB18] = 0x8c; |
360 | break; |
361 | } |
362 | |
363 | regs[R_EB19] = 0x00; |
364 | regs[R_EB20] = 0x20; |
365 | |
366 | switch (priv->id) { |
367 | case TDA18271HDC1: |
368 | regs[R_EB21] = 0x33; |
369 | break; |
370 | case TDA18271HDC2: |
371 | regs[R_EB21] = 0xb3; |
372 | break; |
373 | } |
374 | |
375 | regs[R_EB22] = 0x48; |
376 | regs[R_EB23] = 0xb0; |
377 | |
378 | __tda18271_write_regs(fe, idx: 0x00, TDA18271_NUM_REGS, lock_i2c: false); |
379 | |
380 | /* setup agc1 gain */ |
381 | regs[R_EB17] = 0x00; |
382 | __tda18271_write_regs(fe, R_EB17, len: 1, lock_i2c: false); |
383 | regs[R_EB17] = 0x03; |
384 | __tda18271_write_regs(fe, R_EB17, len: 1, lock_i2c: false); |
385 | regs[R_EB17] = 0x43; |
386 | __tda18271_write_regs(fe, R_EB17, len: 1, lock_i2c: false); |
387 | regs[R_EB17] = 0x4c; |
388 | __tda18271_write_regs(fe, R_EB17, len: 1, lock_i2c: false); |
389 | |
390 | /* setup agc2 gain */ |
391 | if ((priv->id) == TDA18271HDC1) { |
392 | regs[R_EB20] = 0xa0; |
393 | __tda18271_write_regs(fe, R_EB20, len: 1, lock_i2c: false); |
394 | regs[R_EB20] = 0xa7; |
395 | __tda18271_write_regs(fe, R_EB20, len: 1, lock_i2c: false); |
396 | regs[R_EB20] = 0xe7; |
397 | __tda18271_write_regs(fe, R_EB20, len: 1, lock_i2c: false); |
398 | regs[R_EB20] = 0xec; |
399 | __tda18271_write_regs(fe, R_EB20, len: 1, lock_i2c: false); |
400 | } |
401 | |
402 | /* image rejection calibration */ |
403 | |
404 | /* low-band */ |
405 | regs[R_EP3] = 0x1f; |
406 | regs[R_EP4] = 0x66; |
407 | regs[R_EP5] = 0x81; |
408 | regs[R_CPD] = 0xcc; |
409 | regs[R_CD1] = 0x6c; |
410 | regs[R_CD2] = 0x00; |
411 | regs[R_CD3] = 0x00; |
412 | regs[R_MPD] = 0xcd; |
413 | regs[R_MD1] = 0x77; |
414 | regs[R_MD2] = 0x08; |
415 | regs[R_MD3] = 0x00; |
416 | |
417 | __tda18271_write_regs(fe, R_EP3, len: 11, lock_i2c: false); |
418 | |
419 | if ((priv->id) == TDA18271HDC2) { |
420 | /* main pll cp source on */ |
421 | __tda18271_charge_pump_source(fe, pll: TDA18271_MAIN_PLL, force: 1, lock_i2c: false); |
422 | msleep(msecs: 1); |
423 | |
424 | /* main pll cp source off */ |
425 | __tda18271_charge_pump_source(fe, pll: TDA18271_MAIN_PLL, force: 0, lock_i2c: false); |
426 | } |
427 | |
428 | msleep(msecs: 5); /* pll locking */ |
429 | |
430 | /* launch detector */ |
431 | __tda18271_write_regs(fe, R_EP1, len: 1, lock_i2c: false); |
432 | msleep(msecs: 5); /* wanted low measurement */ |
433 | |
434 | regs[R_EP5] = 0x85; |
435 | regs[R_CPD] = 0xcb; |
436 | regs[R_CD1] = 0x66; |
437 | regs[R_CD2] = 0x70; |
438 | |
439 | __tda18271_write_regs(fe, R_EP3, len: 7, lock_i2c: false); |
440 | msleep(msecs: 5); /* pll locking */ |
441 | |
442 | /* launch optimization algorithm */ |
443 | __tda18271_write_regs(fe, R_EP2, len: 1, lock_i2c: false); |
444 | msleep(msecs: 30); /* image low optimization completion */ |
445 | |
446 | /* mid-band */ |
447 | regs[R_EP5] = 0x82; |
448 | regs[R_CPD] = 0xa8; |
449 | regs[R_CD2] = 0x00; |
450 | regs[R_MPD] = 0xa9; |
451 | regs[R_MD1] = 0x73; |
452 | regs[R_MD2] = 0x1a; |
453 | |
454 | __tda18271_write_regs(fe, R_EP3, len: 11, lock_i2c: false); |
455 | msleep(msecs: 5); /* pll locking */ |
456 | |
457 | /* launch detector */ |
458 | __tda18271_write_regs(fe, R_EP1, len: 1, lock_i2c: false); |
459 | msleep(msecs: 5); /* wanted mid measurement */ |
460 | |
461 | regs[R_EP5] = 0x86; |
462 | regs[R_CPD] = 0xa8; |
463 | regs[R_CD1] = 0x66; |
464 | regs[R_CD2] = 0xa0; |
465 | |
466 | __tda18271_write_regs(fe, R_EP3, len: 7, lock_i2c: false); |
467 | msleep(msecs: 5); /* pll locking */ |
468 | |
469 | /* launch optimization algorithm */ |
470 | __tda18271_write_regs(fe, R_EP2, len: 1, lock_i2c: false); |
471 | msleep(msecs: 30); /* image mid optimization completion */ |
472 | |
473 | /* high-band */ |
474 | regs[R_EP5] = 0x83; |
475 | regs[R_CPD] = 0x98; |
476 | regs[R_CD1] = 0x65; |
477 | regs[R_CD2] = 0x00; |
478 | regs[R_MPD] = 0x99; |
479 | regs[R_MD1] = 0x71; |
480 | regs[R_MD2] = 0xcd; |
481 | |
482 | __tda18271_write_regs(fe, R_EP3, len: 11, lock_i2c: false); |
483 | msleep(msecs: 5); /* pll locking */ |
484 | |
485 | /* launch detector */ |
486 | __tda18271_write_regs(fe, R_EP1, len: 1, lock_i2c: false); |
487 | msleep(msecs: 5); /* wanted high measurement */ |
488 | |
489 | regs[R_EP5] = 0x87; |
490 | regs[R_CD1] = 0x65; |
491 | regs[R_CD2] = 0x50; |
492 | |
493 | __tda18271_write_regs(fe, R_EP3, len: 7, lock_i2c: false); |
494 | msleep(msecs: 5); /* pll locking */ |
495 | |
496 | /* launch optimization algorithm */ |
497 | __tda18271_write_regs(fe, R_EP2, len: 1, lock_i2c: false); |
498 | msleep(msecs: 30); /* image high optimization completion */ |
499 | |
500 | /* return to normal mode */ |
501 | regs[R_EP4] = 0x64; |
502 | __tda18271_write_regs(fe, R_EP4, len: 1, lock_i2c: false); |
503 | |
504 | /* synchronize */ |
505 | __tda18271_write_regs(fe, R_EP1, len: 1, lock_i2c: false); |
506 | |
507 | i2c_unlock_bus(adapter: priv->i2c_props.adap, I2C_LOCK_SEGMENT); |
508 | tda18271_i2c_gate_ctrl(fe, enable: 0); |
509 | |
510 | return 0; |
511 | } |
512 | |
513 | /*---------------------------------------------------------------------*/ |
514 | |
515 | /* |
516 | * Standby modes, EP3 [7:5] |
517 | * |
518 | * | SM || SM_LT || SM_XT || mode description |
519 | * |=====\\=======\\=======\\==================================== |
520 | * | 0 || 0 || 0 || normal mode |
521 | * |-----||-------||-------||------------------------------------ |
522 | * | || || || standby mode w/ slave tuner output |
523 | * | 1 || 0 || 0 || & loop through & xtal oscillator on |
524 | * |-----||-------||-------||------------------------------------ |
525 | * | 1 || 1 || 0 || standby mode w/ xtal oscillator on |
526 | * |-----||-------||-------||------------------------------------ |
527 | * | 1 || 1 || 1 || power off |
528 | * |
529 | */ |
530 | |
531 | int tda18271_set_standby_mode(struct dvb_frontend *fe, |
532 | int sm, int sm_lt, int sm_xt) |
533 | { |
534 | struct tda18271_priv *priv = fe->tuner_priv; |
535 | unsigned char *regs = priv->tda18271_regs; |
536 | |
537 | if (tda18271_debug & DBG_ADV) |
538 | tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n" , sm, sm_lt, sm_xt); |
539 | |
540 | regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ |
541 | regs[R_EP3] |= (sm ? (1 << 7) : 0) | |
542 | (sm_lt ? (1 << 6) : 0) | |
543 | (sm_xt ? (1 << 5) : 0); |
544 | |
545 | return tda18271_write_regs(fe, R_EP3, len: 1); |
546 | } |
547 | |
548 | /*---------------------------------------------------------------------*/ |
549 | |
550 | int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) |
551 | { |
552 | /* sets main post divider & divider bytes, but does not write them */ |
553 | struct tda18271_priv *priv = fe->tuner_priv; |
554 | unsigned char *regs = priv->tda18271_regs; |
555 | u8 d, pd; |
556 | u32 div; |
557 | |
558 | int ret = tda18271_lookup_pll_map(fe, map_type: MAIN_PLL, freq: &freq, post_div: &pd, div: &d); |
559 | if (tda_fail(ret)) |
560 | goto fail; |
561 | |
562 | regs[R_MPD] = (0x7f & pd); |
563 | |
564 | div = ((d * (freq / 1000)) << 7) / 125; |
565 | |
566 | regs[R_MD1] = 0x7f & (div >> 16); |
567 | regs[R_MD2] = 0xff & (div >> 8); |
568 | regs[R_MD3] = 0xff & div; |
569 | fail: |
570 | return ret; |
571 | } |
572 | |
573 | int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq) |
574 | { |
575 | /* sets cal post divider & divider bytes, but does not write them */ |
576 | struct tda18271_priv *priv = fe->tuner_priv; |
577 | unsigned char *regs = priv->tda18271_regs; |
578 | u8 d, pd; |
579 | u32 div; |
580 | |
581 | int ret = tda18271_lookup_pll_map(fe, map_type: CAL_PLL, freq: &freq, post_div: &pd, div: &d); |
582 | if (tda_fail(ret)) |
583 | goto fail; |
584 | |
585 | regs[R_CPD] = pd; |
586 | |
587 | div = ((d * (freq / 1000)) << 7) / 125; |
588 | |
589 | regs[R_CD1] = 0x7f & (div >> 16); |
590 | regs[R_CD2] = 0xff & (div >> 8); |
591 | regs[R_CD3] = 0xff & div; |
592 | fail: |
593 | return ret; |
594 | } |
595 | |
596 | /*---------------------------------------------------------------------*/ |
597 | |
598 | int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq) |
599 | { |
600 | /* sets bp filter bits, but does not write them */ |
601 | struct tda18271_priv *priv = fe->tuner_priv; |
602 | unsigned char *regs = priv->tda18271_regs; |
603 | u8 val; |
604 | |
605 | int ret = tda18271_lookup_map(fe, map_type: BP_FILTER, freq, val: &val); |
606 | if (tda_fail(ret)) |
607 | goto fail; |
608 | |
609 | regs[R_EP1] &= ~0x07; /* clear bp filter bits */ |
610 | regs[R_EP1] |= (0x07 & val); |
611 | fail: |
612 | return ret; |
613 | } |
614 | |
615 | int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq) |
616 | { |
617 | /* sets K & M bits, but does not write them */ |
618 | struct tda18271_priv *priv = fe->tuner_priv; |
619 | unsigned char *regs = priv->tda18271_regs; |
620 | u8 val; |
621 | |
622 | int ret = tda18271_lookup_map(fe, map_type: RF_CAL_KMCO, freq, val: &val); |
623 | if (tda_fail(ret)) |
624 | goto fail; |
625 | |
626 | regs[R_EB13] &= ~0x7c; /* clear k & m bits */ |
627 | regs[R_EB13] |= (0x7c & val); |
628 | fail: |
629 | return ret; |
630 | } |
631 | |
632 | int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq) |
633 | { |
634 | /* sets rf band bits, but does not write them */ |
635 | struct tda18271_priv *priv = fe->tuner_priv; |
636 | unsigned char *regs = priv->tda18271_regs; |
637 | u8 val; |
638 | |
639 | int ret = tda18271_lookup_map(fe, map_type: RF_BAND, freq, val: &val); |
640 | if (tda_fail(ret)) |
641 | goto fail; |
642 | |
643 | regs[R_EP2] &= ~0xe0; /* clear rf band bits */ |
644 | regs[R_EP2] |= (0xe0 & (val << 5)); |
645 | fail: |
646 | return ret; |
647 | } |
648 | |
649 | int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq) |
650 | { |
651 | /* sets gain taper bits, but does not write them */ |
652 | struct tda18271_priv *priv = fe->tuner_priv; |
653 | unsigned char *regs = priv->tda18271_regs; |
654 | u8 val; |
655 | |
656 | int ret = tda18271_lookup_map(fe, map_type: GAIN_TAPER, freq, val: &val); |
657 | if (tda_fail(ret)) |
658 | goto fail; |
659 | |
660 | regs[R_EP2] &= ~0x1f; /* clear gain taper bits */ |
661 | regs[R_EP2] |= (0x1f & val); |
662 | fail: |
663 | return ret; |
664 | } |
665 | |
666 | int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq) |
667 | { |
668 | /* sets IR Meas bits, but does not write them */ |
669 | struct tda18271_priv *priv = fe->tuner_priv; |
670 | unsigned char *regs = priv->tda18271_regs; |
671 | u8 val; |
672 | |
673 | int ret = tda18271_lookup_map(fe, map_type: IR_MEASURE, freq, val: &val); |
674 | if (tda_fail(ret)) |
675 | goto fail; |
676 | |
677 | regs[R_EP5] &= ~0x07; |
678 | regs[R_EP5] |= (0x07 & val); |
679 | fail: |
680 | return ret; |
681 | } |
682 | |
683 | int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) |
684 | { |
685 | /* sets rf cal byte (RFC_Cprog), but does not write it */ |
686 | struct tda18271_priv *priv = fe->tuner_priv; |
687 | unsigned char *regs = priv->tda18271_regs; |
688 | u8 val; |
689 | |
690 | int ret = tda18271_lookup_map(fe, map_type: RF_CAL, freq, val: &val); |
691 | /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range |
692 | * for frequencies above 61.1 MHz. In these cases, the internal RF |
693 | * tracking filters calibration mechanism is used. |
694 | * |
695 | * There is no need to warn the user about this. |
696 | */ |
697 | if (ret < 0) |
698 | goto fail; |
699 | |
700 | regs[R_EB14] = val; |
701 | fail: |
702 | return ret; |
703 | } |
704 | |
705 | void _tda_printk(struct tda18271_priv *state, const char *level, |
706 | const char *func, const char *fmt, ...) |
707 | { |
708 | struct va_format vaf; |
709 | va_list args; |
710 | |
711 | va_start(args, fmt); |
712 | |
713 | vaf.fmt = fmt; |
714 | vaf.va = &args; |
715 | |
716 | if (state) |
717 | printk("%s%s: [%d-%04x|%c] %pV" , |
718 | level, func, i2c_adapter_id(state->i2c_props.adap), |
719 | state->i2c_props.addr, |
720 | (state->role == TDA18271_MASTER) ? 'M' : 'S', |
721 | &vaf); |
722 | else |
723 | printk("%s%s: %pV" , level, func, &vaf); |
724 | |
725 | va_end(args); |
726 | } |
727 | |