Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/common/tuners/tda827x.c
15112 views
1
/*
2
*
3
* (c) 2005 Hartmut Hackmann
4
* (c) 2007 Michael Krufky
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 <linux/module.h>
22
#include <linux/slab.h>
23
#include <asm/types.h>
24
#include <linux/dvb/frontend.h>
25
#include <linux/videodev2.h>
26
27
#include "tda827x.h"
28
29
static int debug;
30
module_param(debug, int, 0644);
31
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
32
33
#define dprintk(args...) \
34
do { \
35
if (debug) printk(KERN_DEBUG "tda827x: " args); \
36
} while (0)
37
38
struct tda827x_priv {
39
int i2c_addr;
40
struct i2c_adapter *i2c_adap;
41
struct tda827x_config *cfg;
42
43
unsigned int sgIF;
44
unsigned char lpsel;
45
46
u32 frequency;
47
u32 bandwidth;
48
};
49
50
static void tda827x_set_std(struct dvb_frontend *fe,
51
struct analog_parameters *params)
52
{
53
struct tda827x_priv *priv = fe->tuner_priv;
54
char *mode;
55
56
priv->lpsel = 0;
57
if (params->std & V4L2_STD_MN) {
58
priv->sgIF = 92;
59
priv->lpsel = 1;
60
mode = "MN";
61
} else if (params->std & V4L2_STD_B) {
62
priv->sgIF = 108;
63
mode = "B";
64
} else if (params->std & V4L2_STD_GH) {
65
priv->sgIF = 124;
66
mode = "GH";
67
} else if (params->std & V4L2_STD_PAL_I) {
68
priv->sgIF = 124;
69
mode = "I";
70
} else if (params->std & V4L2_STD_DK) {
71
priv->sgIF = 124;
72
mode = "DK";
73
} else if (params->std & V4L2_STD_SECAM_L) {
74
priv->sgIF = 124;
75
mode = "L";
76
} else if (params->std & V4L2_STD_SECAM_LC) {
77
priv->sgIF = 20;
78
mode = "LC";
79
} else {
80
priv->sgIF = 124;
81
mode = "xx";
82
}
83
84
if (params->mode == V4L2_TUNER_RADIO) {
85
priv->sgIF = 88; /* if frequency is 5.5 MHz */
86
dprintk("setting tda827x to radio FM\n");
87
} else
88
dprintk("setting tda827x to system %s\n", mode);
89
}
90
91
92
/* ------------------------------------------------------------------ */
93
94
struct tda827x_data {
95
u32 lomax;
96
u8 spd;
97
u8 bs;
98
u8 bp;
99
u8 cp;
100
u8 gc3;
101
u8 div1p5;
102
};
103
104
static const struct tda827x_data tda827x_table[] = {
105
{ .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
106
{ .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
107
{ .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
108
{ .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
109
{ .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
110
{ .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
111
{ .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
112
{ .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
113
{ .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
114
{ .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
115
{ .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
116
{ .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
117
{ .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
118
{ .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
119
{ .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
120
{ .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
121
{ .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
122
{ .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
123
{ .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
124
{ .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
125
{ .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
126
{ .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
127
{ .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
128
{ .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
129
{ .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
130
{ .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
131
{ .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
132
{ .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
133
{ .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
134
};
135
136
static int tuner_transfer(struct dvb_frontend *fe,
137
struct i2c_msg *msg,
138
const int size)
139
{
140
int rc;
141
struct tda827x_priv *priv = fe->tuner_priv;
142
143
if (fe->ops.i2c_gate_ctrl)
144
fe->ops.i2c_gate_ctrl(fe, 1);
145
rc = i2c_transfer(priv->i2c_adap, msg, size);
146
if (fe->ops.i2c_gate_ctrl)
147
fe->ops.i2c_gate_ctrl(fe, 0);
148
149
if (rc >= 0 && rc != size)
150
return -EIO;
151
152
return rc;
153
}
154
155
static int tda827xo_set_params(struct dvb_frontend *fe,
156
struct dvb_frontend_parameters *params)
157
{
158
struct tda827x_priv *priv = fe->tuner_priv;
159
u8 buf[14];
160
int rc;
161
162
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
163
.buf = buf, .len = sizeof(buf) };
164
int i, tuner_freq, if_freq;
165
u32 N;
166
167
dprintk("%s:\n", __func__);
168
switch (params->u.ofdm.bandwidth) {
169
case BANDWIDTH_6_MHZ:
170
if_freq = 4000000;
171
break;
172
case BANDWIDTH_7_MHZ:
173
if_freq = 4500000;
174
break;
175
default: /* 8 MHz or Auto */
176
if_freq = 5000000;
177
break;
178
}
179
tuner_freq = params->frequency + if_freq;
180
181
i = 0;
182
while (tda827x_table[i].lomax < tuner_freq) {
183
if (tda827x_table[i + 1].lomax == 0)
184
break;
185
i++;
186
}
187
188
N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
189
buf[0] = 0;
190
buf[1] = (N>>8) | 0x40;
191
buf[2] = N & 0xff;
192
buf[3] = 0;
193
buf[4] = 0x52;
194
buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
195
(tda827x_table[i].bs << 3) +
196
tda827x_table[i].bp;
197
buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
198
buf[7] = 0xbf;
199
buf[8] = 0x2a;
200
buf[9] = 0x05;
201
buf[10] = 0xff;
202
buf[11] = 0x00;
203
buf[12] = 0x00;
204
buf[13] = 0x40;
205
206
msg.len = 14;
207
rc = tuner_transfer(fe, &msg, 1);
208
if (rc < 0)
209
goto err;
210
211
msleep(500);
212
/* correct CP value */
213
buf[0] = 0x30;
214
buf[1] = 0x50 + tda827x_table[i].cp;
215
msg.len = 2;
216
217
rc = tuner_transfer(fe, &msg, 1);
218
if (rc < 0)
219
goto err;
220
221
priv->frequency = params->frequency;
222
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
223
224
return 0;
225
226
err:
227
printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
228
__func__, priv->i2c_addr << 1);
229
return rc;
230
}
231
232
static int tda827xo_sleep(struct dvb_frontend *fe)
233
{
234
struct tda827x_priv *priv = fe->tuner_priv;
235
static u8 buf[] = { 0x30, 0xd0 };
236
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
237
.buf = buf, .len = sizeof(buf) };
238
239
dprintk("%s:\n", __func__);
240
tuner_transfer(fe, &msg, 1);
241
242
if (priv->cfg && priv->cfg->sleep)
243
priv->cfg->sleep(fe);
244
245
return 0;
246
}
247
248
/* ------------------------------------------------------------------ */
249
250
static int tda827xo_set_analog_params(struct dvb_frontend *fe,
251
struct analog_parameters *params)
252
{
253
unsigned char tuner_reg[8];
254
unsigned char reg2[2];
255
u32 N;
256
int i;
257
struct tda827x_priv *priv = fe->tuner_priv;
258
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
259
unsigned int freq = params->frequency;
260
261
tda827x_set_std(fe, params);
262
263
if (params->mode == V4L2_TUNER_RADIO)
264
freq = freq / 1000;
265
266
N = freq + priv->sgIF;
267
268
i = 0;
269
while (tda827x_table[i].lomax < N * 62500) {
270
if (tda827x_table[i + 1].lomax == 0)
271
break;
272
i++;
273
}
274
275
N = N << tda827x_table[i].spd;
276
277
tuner_reg[0] = 0;
278
tuner_reg[1] = (unsigned char)(N>>8);
279
tuner_reg[2] = (unsigned char) N;
280
tuner_reg[3] = 0x40;
281
tuner_reg[4] = 0x52 + (priv->lpsel << 5);
282
tuner_reg[5] = (tda827x_table[i].spd << 6) +
283
(tda827x_table[i].div1p5 << 5) +
284
(tda827x_table[i].bs << 3) + tda827x_table[i].bp;
285
tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
286
tuner_reg[7] = 0x8f;
287
288
msg.buf = tuner_reg;
289
msg.len = 8;
290
tuner_transfer(fe, &msg, 1);
291
292
msg.buf = reg2;
293
msg.len = 2;
294
reg2[0] = 0x80;
295
reg2[1] = 0;
296
tuner_transfer(fe, &msg, 1);
297
298
reg2[0] = 0x60;
299
reg2[1] = 0xbf;
300
tuner_transfer(fe, &msg, 1);
301
302
reg2[0] = 0x30;
303
reg2[1] = tuner_reg[4] + 0x80;
304
tuner_transfer(fe, &msg, 1);
305
306
msleep(1);
307
reg2[0] = 0x30;
308
reg2[1] = tuner_reg[4] + 4;
309
tuner_transfer(fe, &msg, 1);
310
311
msleep(1);
312
reg2[0] = 0x30;
313
reg2[1] = tuner_reg[4];
314
tuner_transfer(fe, &msg, 1);
315
316
msleep(550);
317
reg2[0] = 0x30;
318
reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
319
tuner_transfer(fe, &msg, 1);
320
321
reg2[0] = 0x60;
322
reg2[1] = 0x3f;
323
tuner_transfer(fe, &msg, 1);
324
325
reg2[0] = 0x80;
326
reg2[1] = 0x08; /* Vsync en */
327
tuner_transfer(fe, &msg, 1);
328
329
priv->frequency = params->frequency;
330
331
return 0;
332
}
333
334
static void tda827xo_agcf(struct dvb_frontend *fe)
335
{
336
struct tda827x_priv *priv = fe->tuner_priv;
337
unsigned char data[] = { 0x80, 0x0c };
338
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
339
.buf = data, .len = 2};
340
341
tuner_transfer(fe, &msg, 1);
342
}
343
344
/* ------------------------------------------------------------------ */
345
346
struct tda827xa_data {
347
u32 lomax;
348
u8 svco;
349
u8 spd;
350
u8 scr;
351
u8 sbs;
352
u8 gc3;
353
};
354
355
static struct tda827xa_data tda827xa_dvbt[] = {
356
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
357
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
358
{ .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
359
{ .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
360
{ .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
361
{ .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
362
{ .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
363
{ .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
364
{ .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
365
{ .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
366
{ .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
367
{ .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
368
{ .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
369
{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
370
{ .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
371
{ .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
372
{ .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
373
{ .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
374
{ .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
375
{ .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
376
{ .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
377
{ .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
378
{ .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
379
{ .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
380
{ .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
381
{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
382
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
383
};
384
385
static struct tda827xa_data tda827xa_dvbc[] = {
386
{ .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
387
{ .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
388
{ .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
389
{ .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
390
{ .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
391
{ .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
392
{ .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
393
{ .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
394
{ .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
395
{ .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
396
{ .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
397
{ .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
398
{ .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
399
{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
400
{ .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
401
{ .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
402
{ .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
403
{ .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
404
{ .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
405
{ .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
406
{ .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
407
{ .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
408
{ .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
409
{ .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
410
{ .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
411
{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
412
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
413
};
414
415
static struct tda827xa_data tda827xa_analog[] = {
416
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
417
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
418
{ .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
419
{ .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
420
{ .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
421
{ .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
422
{ .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
423
{ .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
424
{ .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
425
{ .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
426
{ .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
427
{ .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
428
{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
429
{ .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
430
{ .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
431
{ .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
432
{ .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
433
{ .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
434
{ .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
435
{ .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
436
{ .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
437
{ .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
438
{ .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
439
{ .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
440
{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
441
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
442
};
443
444
static int tda827xa_sleep(struct dvb_frontend *fe)
445
{
446
struct tda827x_priv *priv = fe->tuner_priv;
447
static u8 buf[] = { 0x30, 0x90 };
448
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
449
.buf = buf, .len = sizeof(buf) };
450
451
dprintk("%s:\n", __func__);
452
453
tuner_transfer(fe, &msg, 1);
454
455
if (priv->cfg && priv->cfg->sleep)
456
priv->cfg->sleep(fe);
457
458
return 0;
459
}
460
461
static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
462
struct analog_parameters *params)
463
{
464
struct tda827x_priv *priv = fe->tuner_priv;
465
unsigned char buf[] = {0x22, 0x01};
466
int arg;
467
int gp_func;
468
struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
469
470
if (NULL == priv->cfg) {
471
dprintk("tda827x_config not defined, cannot set LNA gain!\n");
472
return;
473
}
474
msg.addr = priv->cfg->switch_addr;
475
if (priv->cfg->config) {
476
if (high)
477
dprintk("setting LNA to high gain\n");
478
else
479
dprintk("setting LNA to low gain\n");
480
}
481
switch (priv->cfg->config) {
482
case 0: /* no LNA */
483
break;
484
case 1: /* switch is GPIO 0 of tda8290 */
485
case 2:
486
if (params == NULL) {
487
gp_func = 0;
488
arg = 0;
489
} else {
490
/* turn Vsync on */
491
gp_func = 1;
492
if (params->std & V4L2_STD_MN)
493
arg = 1;
494
else
495
arg = 0;
496
}
497
if (fe->callback)
498
fe->callback(priv->i2c_adap->algo_data,
499
DVB_FRONTEND_COMPONENT_TUNER,
500
gp_func, arg);
501
buf[1] = high ? 0 : 1;
502
if (priv->cfg->config == 2)
503
buf[1] = high ? 1 : 0;
504
tuner_transfer(fe, &msg, 1);
505
break;
506
case 3: /* switch with GPIO of saa713x */
507
if (fe->callback)
508
fe->callback(priv->i2c_adap->algo_data,
509
DVB_FRONTEND_COMPONENT_TUNER, 0, high);
510
break;
511
}
512
}
513
514
static int tda827xa_set_params(struct dvb_frontend *fe,
515
struct dvb_frontend_parameters *params)
516
{
517
struct tda827x_priv *priv = fe->tuner_priv;
518
struct tda827xa_data *frequency_map = tda827xa_dvbt;
519
u8 buf[11];
520
521
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
522
.buf = buf, .len = sizeof(buf) };
523
524
int i, tuner_freq, if_freq, rc;
525
u32 N;
526
527
dprintk("%s:\n", __func__);
528
529
tda827xa_lna_gain(fe, 1, NULL);
530
msleep(20);
531
532
switch (params->u.ofdm.bandwidth) {
533
case BANDWIDTH_6_MHZ:
534
if_freq = 4000000;
535
break;
536
case BANDWIDTH_7_MHZ:
537
if_freq = 4500000;
538
break;
539
default: /* 8 MHz or Auto */
540
if_freq = 5000000;
541
break;
542
}
543
tuner_freq = params->frequency + if_freq;
544
545
if (fe->ops.info.type == FE_QAM) {
546
dprintk("%s select tda827xa_dvbc\n", __func__);
547
frequency_map = tda827xa_dvbc;
548
}
549
550
i = 0;
551
while (frequency_map[i].lomax < tuner_freq) {
552
if (frequency_map[i + 1].lomax == 0)
553
break;
554
i++;
555
}
556
557
N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
558
buf[0] = 0; // subaddress
559
buf[1] = N >> 8;
560
buf[2] = N & 0xff;
561
buf[3] = 0;
562
buf[4] = 0x16;
563
buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
564
frequency_map[i].sbs;
565
buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
566
buf[7] = 0x1c;
567
buf[8] = 0x06;
568
buf[9] = 0x24;
569
buf[10] = 0x00;
570
msg.len = 11;
571
rc = tuner_transfer(fe, &msg, 1);
572
if (rc < 0)
573
goto err;
574
575
buf[0] = 0x90;
576
buf[1] = 0xff;
577
buf[2] = 0x60;
578
buf[3] = 0x00;
579
buf[4] = 0x59; // lpsel, for 6MHz + 2
580
msg.len = 5;
581
rc = tuner_transfer(fe, &msg, 1);
582
if (rc < 0)
583
goto err;
584
585
buf[0] = 0xa0;
586
buf[1] = 0x40;
587
msg.len = 2;
588
rc = tuner_transfer(fe, &msg, 1);
589
if (rc < 0)
590
goto err;
591
592
msleep(11);
593
msg.flags = I2C_M_RD;
594
rc = tuner_transfer(fe, &msg, 1);
595
if (rc < 0)
596
goto err;
597
msg.flags = 0;
598
599
buf[1] >>= 4;
600
dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
601
if ((buf[1]) < 2) {
602
tda827xa_lna_gain(fe, 0, NULL);
603
buf[0] = 0x60;
604
buf[1] = 0x0c;
605
rc = tuner_transfer(fe, &msg, 1);
606
if (rc < 0)
607
goto err;
608
}
609
610
buf[0] = 0xc0;
611
buf[1] = 0x99; // lpsel, for 6MHz + 2
612
rc = tuner_transfer(fe, &msg, 1);
613
if (rc < 0)
614
goto err;
615
616
buf[0] = 0x60;
617
buf[1] = 0x3c;
618
rc = tuner_transfer(fe, &msg, 1);
619
if (rc < 0)
620
goto err;
621
622
/* correct CP value */
623
buf[0] = 0x30;
624
buf[1] = 0x10 + frequency_map[i].scr;
625
rc = tuner_transfer(fe, &msg, 1);
626
if (rc < 0)
627
goto err;
628
629
msleep(163);
630
buf[0] = 0xc0;
631
buf[1] = 0x39; // lpsel, for 6MHz + 2
632
rc = tuner_transfer(fe, &msg, 1);
633
if (rc < 0)
634
goto err;
635
636
msleep(3);
637
/* freeze AGC1 */
638
buf[0] = 0x50;
639
buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
640
rc = tuner_transfer(fe, &msg, 1);
641
if (rc < 0)
642
goto err;
643
644
priv->frequency = params->frequency;
645
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
646
647
648
return 0;
649
650
err:
651
printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
652
__func__, priv->i2c_addr << 1);
653
return rc;
654
}
655
656
657
static int tda827xa_set_analog_params(struct dvb_frontend *fe,
658
struct analog_parameters *params)
659
{
660
unsigned char tuner_reg[11];
661
u32 N;
662
int i;
663
struct tda827x_priv *priv = fe->tuner_priv;
664
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
665
.buf = tuner_reg, .len = sizeof(tuner_reg) };
666
unsigned int freq = params->frequency;
667
668
tda827x_set_std(fe, params);
669
670
tda827xa_lna_gain(fe, 1, params);
671
msleep(10);
672
673
if (params->mode == V4L2_TUNER_RADIO)
674
freq = freq / 1000;
675
676
N = freq + priv->sgIF;
677
678
i = 0;
679
while (tda827xa_analog[i].lomax < N * 62500) {
680
if (tda827xa_analog[i + 1].lomax == 0)
681
break;
682
i++;
683
}
684
685
N = N << tda827xa_analog[i].spd;
686
687
tuner_reg[0] = 0;
688
tuner_reg[1] = (unsigned char)(N>>8);
689
tuner_reg[2] = (unsigned char) N;
690
tuner_reg[3] = 0;
691
tuner_reg[4] = 0x16;
692
tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
693
(tda827xa_analog[i].svco << 3) +
694
tda827xa_analog[i].sbs;
695
tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
696
tuner_reg[7] = 0x1c;
697
tuner_reg[8] = 4;
698
tuner_reg[9] = 0x20;
699
tuner_reg[10] = 0x00;
700
msg.len = 11;
701
tuner_transfer(fe, &msg, 1);
702
703
tuner_reg[0] = 0x90;
704
tuner_reg[1] = 0xff;
705
tuner_reg[2] = 0xe0;
706
tuner_reg[3] = 0;
707
tuner_reg[4] = 0x99 + (priv->lpsel << 1);
708
msg.len = 5;
709
tuner_transfer(fe, &msg, 1);
710
711
tuner_reg[0] = 0xa0;
712
tuner_reg[1] = 0xc0;
713
msg.len = 2;
714
tuner_transfer(fe, &msg, 1);
715
716
tuner_reg[0] = 0x30;
717
tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
718
tuner_transfer(fe, &msg, 1);
719
720
msg.flags = I2C_M_RD;
721
tuner_transfer(fe, &msg, 1);
722
msg.flags = 0;
723
tuner_reg[1] >>= 4;
724
dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
725
if (tuner_reg[1] < 1)
726
tda827xa_lna_gain(fe, 0, params);
727
728
msleep(100);
729
tuner_reg[0] = 0x60;
730
tuner_reg[1] = 0x3c;
731
tuner_transfer(fe, &msg, 1);
732
733
msleep(163);
734
tuner_reg[0] = 0x50;
735
tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
736
tuner_transfer(fe, &msg, 1);
737
738
tuner_reg[0] = 0x80;
739
tuner_reg[1] = 0x28;
740
tuner_transfer(fe, &msg, 1);
741
742
tuner_reg[0] = 0xb0;
743
tuner_reg[1] = 0x01;
744
tuner_transfer(fe, &msg, 1);
745
746
tuner_reg[0] = 0xc0;
747
tuner_reg[1] = 0x19 + (priv->lpsel << 1);
748
tuner_transfer(fe, &msg, 1);
749
750
priv->frequency = params->frequency;
751
752
return 0;
753
}
754
755
static void tda827xa_agcf(struct dvb_frontend *fe)
756
{
757
struct tda827x_priv *priv = fe->tuner_priv;
758
unsigned char data[] = {0x80, 0x2c};
759
struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
760
.buf = data, .len = 2};
761
tuner_transfer(fe, &msg, 1);
762
}
763
764
/* ------------------------------------------------------------------ */
765
766
static int tda827x_release(struct dvb_frontend *fe)
767
{
768
kfree(fe->tuner_priv);
769
fe->tuner_priv = NULL;
770
return 0;
771
}
772
773
static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
774
{
775
struct tda827x_priv *priv = fe->tuner_priv;
776
*frequency = priv->frequency;
777
return 0;
778
}
779
780
static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
781
{
782
struct tda827x_priv *priv = fe->tuner_priv;
783
*bandwidth = priv->bandwidth;
784
return 0;
785
}
786
787
static int tda827x_init(struct dvb_frontend *fe)
788
{
789
struct tda827x_priv *priv = fe->tuner_priv;
790
dprintk("%s:\n", __func__);
791
if (priv->cfg && priv->cfg->init)
792
priv->cfg->init(fe);
793
794
return 0;
795
}
796
797
static int tda827x_probe_version(struct dvb_frontend *fe);
798
799
static int tda827x_initial_init(struct dvb_frontend *fe)
800
{
801
int ret;
802
ret = tda827x_probe_version(fe);
803
if (ret)
804
return ret;
805
return fe->ops.tuner_ops.init(fe);
806
}
807
808
static int tda827x_initial_sleep(struct dvb_frontend *fe)
809
{
810
int ret;
811
ret = tda827x_probe_version(fe);
812
if (ret)
813
return ret;
814
return fe->ops.tuner_ops.sleep(fe);
815
}
816
817
static struct dvb_tuner_ops tda827xo_tuner_ops = {
818
.info = {
819
.name = "Philips TDA827X",
820
.frequency_min = 55000000,
821
.frequency_max = 860000000,
822
.frequency_step = 250000
823
},
824
.release = tda827x_release,
825
.init = tda827x_initial_init,
826
.sleep = tda827x_initial_sleep,
827
.set_params = tda827xo_set_params,
828
.set_analog_params = tda827xo_set_analog_params,
829
.get_frequency = tda827x_get_frequency,
830
.get_bandwidth = tda827x_get_bandwidth,
831
};
832
833
static struct dvb_tuner_ops tda827xa_tuner_ops = {
834
.info = {
835
.name = "Philips TDA827XA",
836
.frequency_min = 44000000,
837
.frequency_max = 906000000,
838
.frequency_step = 62500
839
},
840
.release = tda827x_release,
841
.init = tda827x_init,
842
.sleep = tda827xa_sleep,
843
.set_params = tda827xa_set_params,
844
.set_analog_params = tda827xa_set_analog_params,
845
.get_frequency = tda827x_get_frequency,
846
.get_bandwidth = tda827x_get_bandwidth,
847
};
848
849
static int tda827x_probe_version(struct dvb_frontend *fe)
850
{
851
u8 data;
852
int rc;
853
struct tda827x_priv *priv = fe->tuner_priv;
854
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
855
.buf = &data, .len = 1 };
856
857
rc = tuner_transfer(fe, &msg, 1);
858
859
if (rc < 0) {
860
printk("%s: could not read from tuner at addr: 0x%02x\n",
861
__func__, msg.addr << 1);
862
return rc;
863
}
864
if ((data & 0x3c) == 0) {
865
dprintk("tda827x tuner found\n");
866
fe->ops.tuner_ops.init = tda827x_init;
867
fe->ops.tuner_ops.sleep = tda827xo_sleep;
868
if (priv->cfg)
869
priv->cfg->agcf = tda827xo_agcf;
870
} else {
871
dprintk("tda827xa tuner found\n");
872
memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
873
if (priv->cfg)
874
priv->cfg->agcf = tda827xa_agcf;
875
}
876
return 0;
877
}
878
879
struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
880
struct i2c_adapter *i2c,
881
struct tda827x_config *cfg)
882
{
883
struct tda827x_priv *priv = NULL;
884
885
dprintk("%s:\n", __func__);
886
priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
887
if (priv == NULL)
888
return NULL;
889
890
priv->i2c_addr = addr;
891
priv->i2c_adap = i2c;
892
priv->cfg = cfg;
893
memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
894
fe->tuner_priv = priv;
895
896
dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
897
898
return fe;
899
}
900
EXPORT_SYMBOL_GPL(tda827x_attach);
901
902
MODULE_DESCRIPTION("DVB TDA827x driver");
903
MODULE_AUTHOR("Hartmut Hackmann <[email protected]>");
904
MODULE_AUTHOR("Michael Krufky <[email protected]>");
905
MODULE_LICENSE("GPL");
906
907
/*
908
* Overrides for Emacs so that we follow Linus's tabbing style.
909
* ---------------------------------------------------------------------------
910
* Local variables:
911
* c-basic-offset: 8
912
* End:
913
*/
914
915