]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/dvb/frontends/dvb-pll.c
V4L/DVB (5795): Fix: remove unused struct that could avoiding load the firmware
[mirror_ubuntu-artful-kernel.git] / drivers / media / dvb / frontends / dvb-pll.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 * descriptions + helper functions for simple dvb plls.
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/dvb/frontend.h>
23#include <asm/types.h>
24
25#include "dvb-pll.h"
26
47a9991e
MK
27struct dvb_pll_desc {
28 char *name;
29 u32 min;
30 u32 max;
31 u32 iffreq;
32 void (*set)(u8 *buf, const struct dvb_frontend_parameters *params);
33 u8 *initdata;
34 u8 *sleepdata;
35 int count;
36 struct {
37 u32 limit;
38 u32 stepsize;
39 u8 config;
40 u8 cb;
41 } entries[12];
42};
43
1da177e4
LT
44/* ----------------------------------------------------------- */
45/* descriptions */
46
26aed922
TP
47/* Set AGC TOP value to 103 dBuV:
48 0x80 = Control Byte
49 0x40 = 250 uA charge pump (irrelevant)
50 0x18 = Aux Byte to follow
51 0x06 = 64.5 kHz divider (irrelevant)
52 0x01 = Disable Vt (aka sleep)
53
54 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA)
55 0x50 = AGC Take over point = 103 dBuV */
56static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 };
57
b7754d74
TP
58/* 0x04 = 166.67 kHz divider
59
60 0x80 = AGC Time constant 50ms Iagc = 9 uA
61 0x20 = AGC Take over point = 112 dBuV */
62static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 };
63
47a9991e 64static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
1da177e4
LT
65 .name = "Thomson dtt7579",
66 .min = 177000000,
67 .max = 858000000,
df78cb0a 68 .iffreq= 36166667,
d519dcf6
TP
69 .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
70 .count = 4,
1da177e4 71 .entries = {
df78cb0a
TP
72 { 443250000, 166667, 0xb4, 0x02 },
73 { 542000000, 166667, 0xb4, 0x08 },
74 { 771000000, 166667, 0xbc, 0x08 },
75 { 999999999, 166667, 0xf4, 0x08 },
1da177e4
LT
76 },
77};
1da177e4 78
47a9991e 79static struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
1da177e4
LT
80 .name = "Thomson dtt7610",
81 .min = 44000000,
82 .max = 958000000,
df78cb0a 83 .iffreq= 44000000,
1da177e4
LT
84 .count = 3,
85 .entries = {
df78cb0a
TP
86 { 157250000, 62500, 0x8e, 0x39 },
87 { 454000000, 62500, 0x8e, 0x3a },
88 { 999999999, 62500, 0x8e, 0x3c },
1da177e4
LT
89 },
90};
1da177e4 91
77d67504
MK
92static void thomson_dtt759x_bw(u8 *buf,
93 const struct dvb_frontend_parameters *params)
1da177e4 94{
77d67504 95 if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth)
1da177e4
LT
96 buf[3] |= 0x10;
97}
98
47a9991e 99static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
1da177e4
LT
100 .name = "Thomson dtt759x",
101 .min = 177000000,
102 .max = 896000000,
77d67504 103 .set = thomson_dtt759x_bw,
df78cb0a 104 .iffreq= 36166667,
d519dcf6
TP
105 .sleepdata = (u8[]){ 2, 0x84, 0x03 },
106 .count = 5,
1da177e4 107 .entries = {
df78cb0a
TP
108 { 264000000, 166667, 0xb4, 0x02 },
109 { 470000000, 166667, 0xbc, 0x02 },
110 { 735000000, 166667, 0xbc, 0x08 },
111 { 835000000, 166667, 0xf4, 0x08 },
112 { 999999999, 166667, 0xfc, 0x08 },
1da177e4
LT
113 },
114};
1da177e4 115
47a9991e 116static struct dvb_pll_desc dvb_pll_lg_z201 = {
1da177e4
LT
117 .name = "LG z201",
118 .min = 174000000,
119 .max = 862000000,
df78cb0a 120 .iffreq= 36166667,
d519dcf6
TP
121 .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
122 .count = 5,
1da177e4 123 .entries = {
df78cb0a
TP
124 { 157500000, 166667, 0xbc, 0x01 },
125 { 443250000, 166667, 0xbc, 0x02 },
126 { 542000000, 166667, 0xbc, 0x04 },
127 { 830000000, 166667, 0xf4, 0x04 },
128 { 999999999, 166667, 0xfc, 0x04 },
1da177e4
LT
129 },
130};
1da177e4 131
47a9991e 132static struct dvb_pll_desc dvb_pll_microtune_4042 = {
d8667cbb
MM
133 .name = "Microtune 4042 FI5",
134 .min = 57000000,
135 .max = 858000000,
df78cb0a 136 .iffreq= 44000000,
d8667cbb
MM
137 .count = 3,
138 .entries = {
df78cb0a
TP
139 { 162000000, 62500, 0x8e, 0xa1 },
140 { 457000000, 62500, 0x8e, 0x91 },
141 { 999999999, 62500, 0x8e, 0x31 },
d8667cbb
MM
142 },
143};
d8667cbb 144
47a9991e 145static struct dvb_pll_desc dvb_pll_thomson_dtt761x = {
83ac8722
MK
146 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
147 .name = "Thomson dtt761x",
148 .min = 57000000,
149 .max = 863000000,
df78cb0a 150 .iffreq= 44000000,
0d723c09 151 .count = 3,
26aed922 152 .initdata = tua603x_agc103,
0d723c09 153 .entries = {
df78cb0a
TP
154 { 147000000, 62500, 0x8e, 0x39 },
155 { 417000000, 62500, 0x8e, 0x3a },
156 { 999999999, 62500, 0x8e, 0x3c },
0d723c09
MK
157 },
158};
0d723c09 159
47a9991e 160static struct dvb_pll_desc dvb_pll_unknown_1 = {
1da177e4
LT
161 .name = "unknown 1", /* used by dntv live dvb-t */
162 .min = 174000000,
163 .max = 862000000,
df78cb0a 164 .iffreq= 36166667,
1da177e4
LT
165 .count = 9,
166 .entries = {
df78cb0a
TP
167 { 150000000, 166667, 0xb4, 0x01 },
168 { 173000000, 166667, 0xbc, 0x01 },
169 { 250000000, 166667, 0xb4, 0x02 },
170 { 400000000, 166667, 0xbc, 0x02 },
171 { 420000000, 166667, 0xf4, 0x02 },
172 { 470000000, 166667, 0xfc, 0x02 },
173 { 600000000, 166667, 0xbc, 0x08 },
174 { 730000000, 166667, 0xf4, 0x08 },
175 { 999999999, 166667, 0xfc, 0x08 },
1da177e4
LT
176 },
177};
1da177e4 178
776338e1
JS
179/* Infineon TUA6010XS
180 * used in Thomson Cable Tuner
181 */
47a9991e 182static struct dvb_pll_desc dvb_pll_tua6010xs = {
776338e1
JS
183 .name = "Infineon TUA6010XS",
184 .min = 44250000,
185 .max = 858000000,
df78cb0a 186 .iffreq= 36125000,
776338e1
JS
187 .count = 3,
188 .entries = {
df78cb0a
TP
189 { 115750000, 62500, 0x8e, 0x03 },
190 { 403250000, 62500, 0x8e, 0x06 },
191 { 999999999, 62500, 0x8e, 0x85 },
776338e1
JS
192 },
193};
776338e1
JS
194
195/* Panasonic env57h1xd5 (some Philips PLL ?) */
47a9991e 196static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
776338e1
JS
197 .name = "Panasonic ENV57H1XD5",
198 .min = 44250000,
199 .max = 858000000,
df78cb0a 200 .iffreq= 36125000,
776338e1
JS
201 .count = 4,
202 .entries = {
df78cb0a
TP
203 { 153000000, 166667, 0xc2, 0x41 },
204 { 470000000, 166667, 0xc2, 0x42 },
205 { 526000000, 166667, 0xc2, 0x84 },
206 { 999999999, 166667, 0xc2, 0xa4 },
776338e1
JS
207 },
208};
776338e1
JS
209
210/* Philips TDA6650/TDA6651
211 * used in Panasonic ENV77H11D5
212 */
77d67504 213static void tda665x_bw(u8 *buf, const struct dvb_frontend_parameters *params)
776338e1 214{
77d67504 215 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
776338e1
JS
216 buf[3] |= 0x08;
217}
218
47a9991e 219static struct dvb_pll_desc dvb_pll_tda665x = {
776338e1
JS
220 .name = "Philips TDA6650/TDA6651",
221 .min = 44250000,
222 .max = 858000000,
77d67504 223 .set = tda665x_bw,
df78cb0a 224 .iffreq= 36166667,
fbfee868 225 .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab },
776338e1
JS
226 .count = 12,
227 .entries = {
df78cb0a
TP
228 { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
229 { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
230 { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
231 { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
232 { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
233 { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
234 { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
235 { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
236 { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
237 { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
238 { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
239 { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
776338e1
JS
240 }
241};
776338e1
JS
242
243/* Infineon TUA6034
244 * used in LG TDTP E102P
245 */
77d67504 246static void tua6034_bw(u8 *buf, const struct dvb_frontend_parameters *params)
776338e1 247{
77d67504 248 if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth)
776338e1
JS
249 buf[3] |= 0x08;
250}
251
47a9991e 252static struct dvb_pll_desc dvb_pll_tua6034 = {
776338e1
JS
253 .name = "Infineon TUA6034",
254 .min = 44250000,
255 .max = 858000000,
df78cb0a 256 .iffreq= 36166667,
776338e1 257 .count = 3,
77d67504 258 .set = tua6034_bw,
776338e1 259 .entries = {
df78cb0a
TP
260 { 174500000, 62500, 0xce, 0x01 },
261 { 230000000, 62500, 0xce, 0x02 },
262 { 999999999, 62500, 0xce, 0x04 },
776338e1
JS
263 },
264};
776338e1 265
1963c907 266/* Infineon TUA6034
d9e12f25 267 * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F
1963c907 268 */
47a9991e 269static struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = {
d9e12f25 270 .name = "LG TDVS-H06xF",
1963c907
MK
271 .min = 54000000,
272 .max = 863000000,
df78cb0a 273 .iffreq= 44000000,
6bdcc6e6 274 .initdata = tua603x_agc103,
1963c907
MK
275 .count = 3,
276 .entries = {
df78cb0a
TP
277 { 165000000, 62500, 0xce, 0x01 },
278 { 450000000, 62500, 0xce, 0x02 },
279 { 999999999, 62500, 0xce, 0x04 },
1963c907
MK
280 },
281};
1963c907 282
49dc82fd
PB
283/* Philips FMD1216ME
284 * used in Medion Hybrid PCMCIA card and USB Box
285 */
77d67504 286static void fmd1216me_bw(u8 *buf, const struct dvb_frontend_parameters *params)
49dc82fd 287{
77d67504
MK
288 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ &&
289 params->frequency >= 158870000)
49dc82fd
PB
290 buf[3] |= 0x08;
291}
292
47a9991e 293static struct dvb_pll_desc dvb_pll_fmd1216me = {
0589b8e4 294 .name = "Philips FMD1216ME",
49dc82fd
PB
295 .min = 50870000,
296 .max = 858000000,
df78cb0a 297 .iffreq= 36125000,
77d67504 298 .set = fmd1216me_bw,
b7754d74
TP
299 .initdata = tua603x_agc112,
300 .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
49dc82fd
PB
301 .count = 7,
302 .entries = {
df78cb0a
TP
303 { 143870000, 166667, 0xbc, 0x41 },
304 { 158870000, 166667, 0xf4, 0x41 },
305 { 329870000, 166667, 0xbc, 0x42 },
306 { 441870000, 166667, 0xf4, 0x42 },
307 { 625870000, 166667, 0xbc, 0x44 },
308 { 803870000, 166667, 0xf4, 0x44 },
309 { 999999999, 166667, 0xfc, 0x44 },
49dc82fd
PB
310 }
311};
49dc82fd 312
0589b8e4
PB
313/* ALPS TDED4
314 * used in Nebula-Cards and USB boxes
315 */
77d67504 316static void tded4_bw(u8 *buf, const struct dvb_frontend_parameters *params)
0589b8e4 317{
77d67504 318 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
0589b8e4
PB
319 buf[3] |= 0x04;
320}
321
47a9991e 322static struct dvb_pll_desc dvb_pll_tded4 = {
0589b8e4
PB
323 .name = "ALPS TDED4",
324 .min = 47000000,
325 .max = 863000000,
df78cb0a 326 .iffreq= 36166667,
77d67504 327 .set = tded4_bw,
0589b8e4
PB
328 .count = 4,
329 .entries = {
df78cb0a
TP
330 { 153000000, 166667, 0x85, 0x01 },
331 { 470000000, 166667, 0x85, 0x02 },
332 { 823000000, 166667, 0x85, 0x08 },
333 { 999999999, 166667, 0x85, 0x88 },
0589b8e4
PB
334 }
335};
0589b8e4 336
147418c9
KL
337/* ALPS TDHU2
338 * used in AverTVHD MCE A180
339 */
47a9991e 340static struct dvb_pll_desc dvb_pll_tdhu2 = {
147418c9
KL
341 .name = "ALPS TDHU2",
342 .min = 54000000,
343 .max = 864000000,
df78cb0a 344 .iffreq= 44000000,
147418c9
KL
345 .count = 4,
346 .entries = {
df78cb0a
TP
347 { 162000000, 62500, 0x85, 0x01 },
348 { 426000000, 62500, 0x85, 0x02 },
349 { 782000000, 62500, 0x85, 0x08 },
350 { 999999999, 62500, 0x85, 0x88 },
147418c9
KL
351 }
352};
147418c9
KL
353
354/* Philips TUV1236D
355 * used in ATI HDTV Wonder
356 */
4abe9f9d
MK
357static void tuv1236d_rf(u8 *buf, const struct dvb_frontend_parameters *params)
358{
359 switch (params->u.vsb.modulation) {
360 case QAM_64:
361 case QAM_256:
362 buf[3] |= 0x08;
363 break;
364 case VSB_8:
365 default:
366 buf[3] &= ~0x08;
367 }
368}
369
47a9991e 370static struct dvb_pll_desc dvb_pll_tuv1236d = {
147418c9 371 .name = "Philips TUV1236D",
04a45929 372 .min = 54000000,
147418c9 373 .max = 864000000,
df78cb0a 374 .iffreq= 44000000,
4abe9f9d 375 .set = tuv1236d_rf,
147418c9
KL
376 .count = 3,
377 .entries = {
df78cb0a
TP
378 { 157250000, 62500, 0xc6, 0x41 },
379 { 454000000, 62500, 0xc6, 0x42 },
380 { 999999999, 62500, 0xc6, 0x44 },
147418c9
KL
381 },
382};
147418c9 383
d76a6179 384/* Samsung TBMV30111IN / TBMV30712IN1
147418c9
KL
385 * used in Air2PC ATSC - 2nd generation (nxt2002)
386 */
47a9991e 387static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
28f3d4b3 388 .name = "Samsung TBMV30111IN / TBMV30712IN1",
147418c9
KL
389 .min = 54000000,
390 .max = 860000000,
df78cb0a 391 .iffreq= 44000000,
17c37efb 392 .count = 6,
147418c9 393 .entries = {
df78cb0a
TP
394 { 172000000, 166667, 0xb4, 0x01 },
395 { 214000000, 166667, 0xb4, 0x02 },
396 { 467000000, 166667, 0xbc, 0x02 },
397 { 721000000, 166667, 0xbc, 0x08 },
398 { 841000000, 166667, 0xf4, 0x08 },
399 { 999999999, 166667, 0xfc, 0x02 },
147418c9
KL
400 }
401};
147418c9 402
f8bf134d
RP
403/*
404 * Philips SD1878 Tuner.
405 */
47a9991e 406static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
f8bf134d
RP
407 .name = "Philips SD1878",
408 .min = 950000,
409 .max = 2150000,
df78cb0a 410 .iffreq= 249, /* zero-IF, offset 249 is to round up */
f8bf134d
RP
411 .count = 4,
412 .entries = {
df78cb0a
TP
413 { 1250000, 500, 0xc4, 0x00},
414 { 1550000, 500, 0xc4, 0x40},
415 { 2050000, 500, 0xc4, 0x80},
416 { 2150000, 500, 0xc4, 0xc0},
f8bf134d
RP
417 },
418};
f8bf134d 419
a78d0bfa
JAR
420/*
421 * Philips TD1316 Tuner.
422 */
77d67504 423static void td1316_bw(u8 *buf, const struct dvb_frontend_parameters *params)
a78d0bfa
JAR
424{
425 u8 band;
426
427 /* determine band */
77d67504 428 if (params->frequency < 161000000)
a78d0bfa 429 band = 1;
77d67504 430 else if (params->frequency < 444000000)
a78d0bfa
JAR
431 band = 2;
432 else
433 band = 4;
434
435 buf[3] |= band;
436
437 /* setup PLL filter */
77d67504 438 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
a78d0bfa
JAR
439 buf[3] |= 1 << 3;
440}
441
47a9991e 442static struct dvb_pll_desc dvb_pll_philips_td1316 = {
a78d0bfa
JAR
443 .name = "Philips TD1316",
444 .min = 87000000,
445 .max = 895000000,
df78cb0a 446 .iffreq= 36166667,
77d67504 447 .set = td1316_bw,
a78d0bfa
JAR
448 .count = 9,
449 .entries = {
df78cb0a
TP
450 { 93834000, 166667, 0xca, 0x60},
451 { 123834000, 166667, 0xca, 0xa0},
452 { 163834000, 166667, 0xca, 0xc0},
453 { 253834000, 166667, 0xca, 0x60},
454 { 383834000, 166667, 0xca, 0xa0},
455 { 443834000, 166667, 0xca, 0xc0},
456 { 583834000, 166667, 0xca, 0x60},
457 { 793834000, 166667, 0xca, 0xa0},
458 { 858834000, 166667, 0xca, 0xe0},
a78d0bfa
JAR
459 },
460};
a78d0bfa 461
780dfef3 462/* FE6600 used on DViCO Hybrid */
47a9991e 463static struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
91ae3299 464 .name = "Thomson FE6600",
780dfef3
CP
465 .min = 44250000,
466 .max = 858000000,
df78cb0a 467 .iffreq= 36125000,
780dfef3
CP
468 .count = 4,
469 .entries = {
df78cb0a
TP
470 { 250000000, 166667, 0xb4, 0x12 },
471 { 455000000, 166667, 0xfe, 0x11 },
472 { 775500000, 166667, 0xbc, 0x18 },
473 { 999999999, 166667, 0xf4, 0x18 },
780dfef3
CP
474 }
475};
47a9991e 476
77d67504 477static void opera1_bw(u8 *buf, const struct dvb_frontend_parameters *params)
941491f3 478{
77d67504 479 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
941491f3
MG
480 buf[2] |= 0x08;
481}
482
47a9991e 483static struct dvb_pll_desc dvb_pll_opera1 = {
941491f3
MG
484 .name = "Opera Tuner",
485 .min = 900000,
486 .max = 2250000,
487 .iffreq= 0,
77d67504 488 .set = opera1_bw,
941491f3
MG
489 .count = 8,
490 .entries = {
491 { 1064000, 500, 0xe5, 0xc6 },
492 { 1169000, 500, 0xe5, 0xe6 },
493 { 1299000, 500, 0xe5, 0x24 },
494 { 1444000, 500, 0xe5, 0x44 },
495 { 1606000, 500, 0xe5, 0x64 },
496 { 1777000, 500, 0xe5, 0x84 },
497 { 1941000, 500, 0xe5, 0xa4 },
498 { 2250000, 500, 0xe5, 0xc4 },
499 }
500};
47a9991e
MK
501
502/* ----------------------------------------------------------- */
503
504static struct dvb_pll_desc *pll_list[] = {
505 [DVB_PLL_UNDEFINED] = NULL,
506 [DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579,
507 [DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x,
508 [DVB_PLL_THOMSON_DTT7610] = &dvb_pll_thomson_dtt7610,
509 [DVB_PLL_LG_Z201] = &dvb_pll_lg_z201,
510 [DVB_PLL_MICROTUNE_4042] = &dvb_pll_microtune_4042,
511 [DVB_PLL_THOMSON_DTT761X] = &dvb_pll_thomson_dtt761x,
512 [DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1,
513 [DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs,
514 [DVB_PLL_ENV57H1XD5] = &dvb_pll_env57h1xd5,
515 [DVB_PLL_TUA6034] = &dvb_pll_tua6034,
516 [DVB_PLL_LG_TDVS_H06XF] = &dvb_pll_lg_tdvs_h06xf,
517 [DVB_PLL_TDA665X] = &dvb_pll_tda665x,
518 [DVB_PLL_FMD1216ME] = &dvb_pll_fmd1216me,
519 [DVB_PLL_TDED4] = &dvb_pll_tded4,
520 [DVB_PLL_TUV1236D] = &dvb_pll_tuv1236d,
521 [DVB_PLL_TDHU2] = &dvb_pll_tdhu2,
522 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
523 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
524 [DVB_PLL_PHILIPS_TD1316] = &dvb_pll_philips_td1316,
525 [DVB_PLL_THOMSON_FE6600] = &dvb_pll_thomson_fe6600,
526 [DVB_PLL_OPERA1] = &dvb_pll_opera1,
527};
528
529/* ----------------------------------------------------------- */
780dfef3 530
272bc4db
AQ
531struct dvb_pll_priv {
532 /* i2c details */
533 int pll_i2c_address;
534 struct i2c_adapter *i2c;
535
536 /* the PLL descriptor */
537 struct dvb_pll_desc *pll_desc;
538
539 /* cached frequency/bandwidth */
540 u32 frequency;
541 u32 bandwidth;
542};
543
1da177e4
LT
544/* ----------------------------------------------------------- */
545/* code */
546
547static int debug = 0;
548module_param(debug, int, 0644);
549MODULE_PARM_DESC(debug, "enable verbose debug messages");
550
4ce15678
TP
551static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
552 const struct dvb_frontend_parameters *params)
1da177e4
LT
553{
554 u32 div;
555 int i;
556
77d67504
MK
557 if (params->frequency != 0 && (params->frequency < desc->min ||
558 params->frequency > desc->max))
559 return -EINVAL;
1da177e4
LT
560
561 for (i = 0; i < desc->count; i++) {
77d67504 562 if (params->frequency > desc->entries[i].limit)
1da177e4
LT
563 continue;
564 break;
565 }
77d67504 566
1da177e4 567 if (debug)
77d67504
MK
568 printk("pll: %s: freq=%d | i=%d/%d\n", desc->name,
569 params->frequency, i, desc->count);
272bc4db
AQ
570 if (i == desc->count)
571 return -EINVAL;
1da177e4 572
77d67504
MK
573 div = (params->frequency + desc->iffreq +
574 desc->entries[i].stepsize/2) / desc->entries[i].stepsize;
1da177e4
LT
575 buf[0] = div >> 8;
576 buf[1] = div & 0xff;
ab66b22f
MK
577 buf[2] = desc->entries[i].config;
578 buf[3] = desc->entries[i].cb;
1da177e4 579
77d67504
MK
580 if (desc->set)
581 desc->set(buf, params);
1da177e4
LT
582
583 if (debug)
584 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
585 desc->name, div, buf[0], buf[1], buf[2], buf[3]);
586
89faeefc 587 // calculate the frequency we set it to
df78cb0a 588 return (div * desc->entries[i].stepsize) - desc->iffreq;
1da177e4
LT
589}
590EXPORT_SYMBOL(dvb_pll_configure);
591
272bc4db
AQ
592static int dvb_pll_release(struct dvb_frontend *fe)
593{
2213918a 594 kfree(fe->tuner_priv);
272bc4db
AQ
595 fe->tuner_priv = NULL;
596 return 0;
597}
598
599static int dvb_pll_sleep(struct dvb_frontend *fe)
600{
601 struct dvb_pll_priv *priv = fe->tuner_priv;
272bc4db 602
c162dff6
CP
603 if (priv->i2c == NULL)
604 return -EINVAL;
605
d519dcf6
TP
606 if (priv->pll_desc->sleepdata) {
607 struct i2c_msg msg = { .flags = 0,
608 .addr = priv->pll_i2c_address,
609 .buf = priv->pll_desc->sleepdata + 1,
610 .len = priv->pll_desc->sleepdata[0] };
272bc4db 611
d519dcf6 612 int result;
272bc4db 613
d519dcf6
TP
614 if (fe->ops.i2c_gate_ctrl)
615 fe->ops.i2c_gate_ctrl(fe, 1);
616 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
617 return result;
618 }
619 return 0;
272bc4db 620 }
d519dcf6
TP
621 /* Shouldn't be called when initdata is NULL, maybe BUG()? */
622 return -EINVAL;
272bc4db
AQ
623}
624
47ae9ae8
MK
625static int dvb_pll_set_params(struct dvb_frontend *fe,
626 struct dvb_frontend_parameters *params)
272bc4db
AQ
627{
628 struct dvb_pll_priv *priv = fe->tuner_priv;
629 u8 buf[4];
630 struct i2c_msg msg =
47ae9ae8
MK
631 { .addr = priv->pll_i2c_address, .flags = 0,
632 .buf = buf, .len = sizeof(buf) };
272bc4db 633 int result;
77d67504 634 u32 frequency = 0;
272bc4db
AQ
635
636 if (priv->i2c == NULL)
637 return -EINVAL;
638
77d67504 639 if ((result = dvb_pll_configure(priv->pll_desc, buf, params)) < 0)
272bc4db 640 return result;
89faeefc
MK
641 else
642 frequency = result;
272bc4db 643
dea74869
PB
644 if (fe->ops.i2c_gate_ctrl)
645 fe->ops.i2c_gate_ctrl(fe, 1);
272bc4db
AQ
646 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
647 return result;
648 }
649
89faeefc 650 priv->frequency = frequency;
77d67504 651 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
272bc4db
AQ
652
653 return 0;
654}
655
47ae9ae8
MK
656static int dvb_pll_calc_regs(struct dvb_frontend *fe,
657 struct dvb_frontend_parameters *params,
658 u8 *buf, int buf_len)
272bc4db
AQ
659{
660 struct dvb_pll_priv *priv = fe->tuner_priv;
661 int result;
77d67504 662 u32 frequency = 0;
272bc4db
AQ
663
664 if (buf_len < 5)
665 return -EINVAL;
666
77d67504 667 if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params)) < 0)
272bc4db 668 return result;
89faeefc
MK
669 else
670 frequency = result;
671
272bc4db
AQ
672 buf[0] = priv->pll_i2c_address;
673
89faeefc 674 priv->frequency = frequency;
77d67504 675 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
272bc4db
AQ
676
677 return 5;
678}
679
680static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency)
681{
682 struct dvb_pll_priv *priv = fe->tuner_priv;
683 *frequency = priv->frequency;
684 return 0;
685}
686
687static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
688{
689 struct dvb_pll_priv *priv = fe->tuner_priv;
690 *bandwidth = priv->bandwidth;
691 return 0;
692}
693
26aed922
TP
694static int dvb_pll_init(struct dvb_frontend *fe)
695{
696 struct dvb_pll_priv *priv = fe->tuner_priv;
697
698 if (priv->i2c == NULL)
699 return -EINVAL;
700
701 if (priv->pll_desc->initdata) {
702 struct i2c_msg msg = { .flags = 0,
703 .addr = priv->pll_i2c_address,
704 .buf = priv->pll_desc->initdata + 1,
705 .len = priv->pll_desc->initdata[0] };
706
707 int result;
708 if (fe->ops.i2c_gate_ctrl)
709 fe->ops.i2c_gate_ctrl(fe, 1);
710 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
711 return result;
712 }
713 return 0;
714 }
715 /* Shouldn't be called when initdata is NULL, maybe BUG()? */
716 return -EINVAL;
717}
718
272bc4db
AQ
719static struct dvb_tuner_ops dvb_pll_tuner_ops = {
720 .release = dvb_pll_release,
721 .sleep = dvb_pll_sleep,
d519dcf6 722 .init = dvb_pll_init,
272bc4db 723 .set_params = dvb_pll_set_params,
bd4956b8 724 .calc_regs = dvb_pll_calc_regs,
272bc4db
AQ
725 .get_frequency = dvb_pll_get_frequency,
726 .get_bandwidth = dvb_pll_get_bandwidth,
727};
728
47ae9ae8
MK
729struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
730 struct i2c_adapter *i2c,
47a9991e 731 unsigned int pll_desc_id)
272bc4db 732{
061b623c 733 u8 b1 [] = { 0 };
47ae9ae8
MK
734 struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
735 .buf = b1, .len = 1 };
272bc4db 736 struct dvb_pll_priv *priv = NULL;
061b623c 737 int ret;
47a9991e
MK
738 struct dvb_pll_desc *desc;
739
740 BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
741
742 desc = pll_list[pll_desc_id];
061b623c 743
55c05b6d
AQ
744 if (i2c != NULL) {
745 if (fe->ops.i2c_gate_ctrl)
746 fe->ops.i2c_gate_ctrl(fe, 1);
747
95faba22
AQ
748 ret = i2c_transfer (i2c, &msg, 1);
749 if (ret != 1)
2bfe031d 750 return NULL;
55c05b6d
AQ
751 if (fe->ops.i2c_gate_ctrl)
752 fe->ops.i2c_gate_ctrl(fe, 0);
753 }
272bc4db
AQ
754
755 priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
756 if (priv == NULL)
2bfe031d 757 return NULL;
272bc4db
AQ
758
759 priv->pll_i2c_address = pll_addr;
760 priv->i2c = i2c;
761 priv->pll_desc = desc;
762
47ae9ae8
MK
763 memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
764 sizeof(struct dvb_tuner_ops));
765
982dd1bd
TP
766 strncpy(fe->ops.tuner_ops.info.name, desc->name,
767 sizeof(fe->ops.tuner_ops.info.name));
dea74869
PB
768 fe->ops.tuner_ops.info.frequency_min = desc->min;
769 fe->ops.tuner_ops.info.frequency_min = desc->max;
d519dcf6
TP
770 if (!desc->initdata)
771 fe->ops.tuner_ops.init = NULL;
772 if (!desc->sleepdata)
773 fe->ops.tuner_ops.sleep = NULL;
272bc4db
AQ
774
775 fe->tuner_priv = priv;
2bfe031d 776 return fe;
272bc4db
AQ
777}
778EXPORT_SYMBOL(dvb_pll_attach);
779
1da177e4
LT
780MODULE_DESCRIPTION("dvb pll library");
781MODULE_AUTHOR("Gerd Knorr");
782MODULE_LICENSE("GPL");