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