blob: f8e01030fbc73853828fef2e041f0f2c57bdeee0 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
3 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
4 *
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -07005 * Extended 3 / 2005 by Hartmut Hackmann to support various
6 * cards with the tda10046 DVB-T channel decoder
7 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/init.h>
24#include <linux/list.h>
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/delay.h>
29#include <linux/kthread.h>
30#include <linux/suspend.h>
31
Michael Krufky55ee3b82005-07-12 13:59:08 -070032
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include "saa7134-reg.h"
34#include "saa7134.h"
35
Michael Krufky29780bb2005-07-27 11:45:59 -070036#ifdef HAVE_MT352
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -070037# include "mt352.h"
38# include "mt352_priv.h" /* FIXME */
39#endif
Michael Krufky29780bb2005-07-27 11:45:59 -070040#ifdef HAVE_TDA1004X
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -070041# include "tda1004x.h"
42#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
45MODULE_LICENSE("GPL");
46
47static unsigned int antenna_pwr = 0;
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049module_param(antenna_pwr, int, 0444);
50MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
51
52/* ------------------------------------------------------------------ */
53
Michael Krufky29780bb2005-07-27 11:45:59 -070054#ifdef HAVE_MT352
Linus Torvalds1da177e2005-04-16 15:20:36 -070055static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
56{
57 u32 ok;
58
59 if (!on) {
60 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
61 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
62 return 0;
63 }
64
65 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
66 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
67 udelay(10);
68
69 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 28));
70 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
71 udelay(10);
72 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
73 udelay(10);
74 ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
75 printk("%s: %s %s\n", dev->name, __FUNCTION__,
76 ok ? "on" : "off");
77
78 if (!ok)
79 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
80 return ok;
81}
82
83static int mt352_pinnacle_init(struct dvb_frontend* fe)
84{
85 static u8 clock_config [] = { CLOCK_CTL, 0x3d, 0x28 };
86 static u8 reset [] = { RESET, 0x80 };
87 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
88 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
89 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x31 };
90 static u8 fsm_ctl_cfg[] = { 0x7b, 0x04 };
91 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x0f };
92 static u8 scan_ctl_cfg [] = { SCAN_CTL, 0x0d };
93 static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
94 struct saa7134_dev *dev= fe->dvb->priv;
95
96 printk("%s: %s called\n",dev->name,__FUNCTION__);
97
98 mt352_write(fe, clock_config, sizeof(clock_config));
99 udelay(200);
100 mt352_write(fe, reset, sizeof(reset));
101 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
102 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
103 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
104 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
105
106 mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg));
107 mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg));
108 mt352_write(fe, irq_cfg, sizeof(irq_cfg));
109 return 0;
110}
111
112static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
113 struct dvb_frontend_parameters* params,
114 u8* pllbuf)
115{
116 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
117 static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE;
118 struct saa7134_dev *dev = fe->dvb->priv;
119 struct v4l2_frequency f;
120
121 /* set frequency (mt2050) */
122 f.tuner = 0;
123 f.type = V4L2_TUNER_DIGITAL_TV;
124 f.frequency = params->frequency / 1000 * 16 / 1000;
125 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
126 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
127 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off);
128
129 pinnacle_antenna_pwr(dev, antenna_pwr);
130
131 /* mt352 setup */
132 mt352_pinnacle_init(fe);
133 pllbuf[0] = 0xc2;
134 pllbuf[1] = 0x00;
135 pllbuf[2] = 0x00;
136 pllbuf[3] = 0x80;
137 pllbuf[4] = 0x00;
138 return 0;
139}
140
141static struct mt352_config pinnacle_300i = {
142 .demod_address = 0x3c >> 1,
143 .adc_clock = 20333,
144 .if2 = 36150,
145 .no_tuner = 1,
146 .demod_init = mt352_pinnacle_init,
147 .pll_set = mt352_pinnacle_pll_set,
148};
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700149#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151/* ------------------------------------------------------------------ */
152
Michael Krufky29780bb2005-07-27 11:45:59 -0700153#ifdef HAVE_TDA1004X
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800155static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700156{
157 struct saa7134_dev *dev = fe->dvb->priv;
158 u8 tuner_buf[4];
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800159 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700160 sizeof(tuner_buf) };
161 int tuner_frequency = 0;
162 u8 band, cp, filter;
163
164 /* determine charge pump */
165 tuner_frequency = params->frequency + 36166000;
166 if (tuner_frequency < 87000000)
167 return -EINVAL;
168 else if (tuner_frequency < 130000000)
169 cp = 3;
170 else if (tuner_frequency < 160000000)
171 cp = 5;
172 else if (tuner_frequency < 200000000)
173 cp = 6;
174 else if (tuner_frequency < 290000000)
175 cp = 3;
176 else if (tuner_frequency < 420000000)
177 cp = 5;
178 else if (tuner_frequency < 480000000)
179 cp = 6;
180 else if (tuner_frequency < 620000000)
181 cp = 3;
182 else if (tuner_frequency < 830000000)
183 cp = 5;
184 else if (tuner_frequency < 895000000)
185 cp = 7;
186 else
187 return -EINVAL;
188
189 /* determine band */
190 if (params->frequency < 49000000)
191 return -EINVAL;
192 else if (params->frequency < 161000000)
193 band = 1;
194 else if (params->frequency < 444000000)
195 band = 2;
196 else if (params->frequency < 861000000)
197 band = 4;
198 else
199 return -EINVAL;
200
201 /* setup PLL filter */
202 switch (params->u.ofdm.bandwidth) {
203 case BANDWIDTH_6_MHZ:
204 filter = 0;
205 break;
206
207 case BANDWIDTH_7_MHZ:
208 filter = 0;
209 break;
210
211 case BANDWIDTH_8_MHZ:
212 filter = 1;
213 break;
214
215 default:
216 return -EINVAL;
217 }
218
219 /* calculate divisor
220 * ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
221 */
222 tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
223
224 /* setup tuner buffer */
225 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
226 tuner_buf[1] = tuner_frequency & 0xff;
227 tuner_buf[2] = 0xca;
228 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
229
230 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
231 return -EIO;
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700232 msleep(1);
233 return 0;
234}
235
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800236static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
237{
238 struct saa7134_dev *dev = fe->dvb->priv;
239 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
240 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
241
242 /* setup PLL configuration */
243 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
244 return -EIO;
245 msleep(1);
246
247 return 0;
248}
249
250/* ------------------------------------------------------------------ */
251
252static int philips_tu1216_pll_60_init(struct dvb_frontend *fe)
253{
254 return philips_tda6651_pll_init(0x60, fe);
255}
256
257static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
258{
259 return philips_tda6651_pll_set(0x60, fe, params);
260}
261
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700262static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
263 const struct firmware **fw, char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264{
265 struct saa7134_dev *dev = fe->dvb->priv;
266 return request_firmware(fw, name, &dev->pci->dev);
267}
268
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800269static struct tda1004x_config philips_tu1216_60_config = {
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700270
271 .demod_address = 0x8,
272 .invert = 1,
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800273 .invert_oclk = 0,
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700274 .xtal_freq = TDA10046_XTAL_4M,
275 .agc_config = TDA10046_AGC_DEFAULT,
276 .if_freq = TDA10046_FREQ_3617,
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800277 .pll_init = philips_tu1216_pll_60_init,
278 .pll_set = philips_tu1216_pll_60_set,
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700279 .pll_sleep = NULL,
280 .request_firmware = philips_tu1216_request_firmware,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281};
282
283/* ------------------------------------------------------------------ */
284
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800285static int philips_tu1216_pll_61_init(struct dvb_frontend *fe)
286{
287 return philips_tda6651_pll_init(0x61, fe);
288}
289
290static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
291{
292 return philips_tda6651_pll_set(0x61, fe, params);
293}
294
295static struct tda1004x_config philips_tu1216_61_config = {
296
297 .demod_address = 0x8,
298 .invert = 1,
299 .invert_oclk = 0,
300 .xtal_freq = TDA10046_XTAL_4M,
301 .agc_config = TDA10046_AGC_DEFAULT,
302 .if_freq = TDA10046_FREQ_3617,
303 .pll_init = philips_tu1216_pll_61_init,
304 .pll_set = philips_tu1216_pll_61_set,
305 .pll_sleep = NULL,
306 .request_firmware = philips_tu1216_request_firmware,
307};
308
309/* ------------------------------------------------------------------ */
310
311static int philips_europa_pll_init(struct dvb_frontend *fe)
312{
313 struct saa7134_dev *dev = fe->dvb->priv;
314 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
315 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
316
317 /* setup PLL configuration */
318 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
319 return -EIO;
320 msleep(1);
321
322 /* switch the board to dvb mode */
323 init_msg.addr = 0x43;
324 init_msg.len = 0x02;
325 msg[0] = 0x00;
326 msg[1] = 0x40;
327 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
328 return -EIO;
329
330 return 0;
331}
332
333static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
334{
335 return philips_tda6651_pll_set(0x61, fe, params);
336}
337
338static void philips_europa_analog(struct dvb_frontend *fe)
339{
340 struct saa7134_dev *dev = fe->dvb->priv;
341 /* this message actually turns the tuner back to analog mode */
342 static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
343 struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
344
345 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
346 msleep(1);
347
348 /* switch the board to analog mode */
349 analog_msg.addr = 0x43;
350 analog_msg.len = 0x02;
351 msg[0] = 0x00;
352 msg[1] = 0x14;
353 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
354}
355
356static struct tda1004x_config philips_europa_config = {
357
358 .demod_address = 0x8,
359 .invert = 0,
360 .invert_oclk = 0,
361 .xtal_freq = TDA10046_XTAL_4M,
362 .agc_config = TDA10046_AGC_IFO_AUTO_POS,
363 .if_freq = TDA10046_FREQ_052,
364 .pll_init = philips_europa_pll_init,
365 .pll_set = philips_td1316_pll_set,
366 .pll_sleep = philips_europa_analog,
367 .request_firmware = NULL,
368};
369
370/* ------------------------------------------------------------------ */
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700371
372static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
373{
374 struct saa7134_dev *dev = fe->dvb->priv;
375 /* this message is to set up ATC and ALC */
376 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
377 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
378
379 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
380 return -EIO;
381 msleep(1);
382
383 return 0;
384}
385
386static void philips_fmd1216_analog(struct dvb_frontend *fe)
387{
388 struct saa7134_dev *dev = fe->dvb->priv;
389 /* this message actually turns the tuner back to analog mode */
390 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 };
391 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
392
393 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
394 msleep(1);
395 fmd1216_init[2] = 0x86;
396 fmd1216_init[3] = 0x54;
397 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
398 msleep(1);
399}
400
401static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
402{
403 struct saa7134_dev *dev = fe->dvb->priv;
404 u8 tuner_buf[4];
405 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = tuner_buf,.len =
406 sizeof(tuner_buf) };
407 int tuner_frequency = 0;
408 int divider = 0;
409 u8 band, mode, cp;
410
411 /* determine charge pump */
412 tuner_frequency = params->frequency + 36130000;
413 if (tuner_frequency < 87000000)
414 return -EINVAL;
415 /* low band */
416 else if (tuner_frequency < 180000000) {
417 band = 1;
418 mode = 7;
419 cp = 0;
420 } else if (tuner_frequency < 195000000) {
421 band = 1;
422 mode = 6;
423 cp = 1;
424 /* mid band */
425 } else if (tuner_frequency < 366000000) {
426 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
427 band = 10;
428 } else {
429 band = 2;
430 }
431 mode = 7;
432 cp = 0;
433 } else if (tuner_frequency < 478000000) {
434 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
435 band = 10;
436 } else {
437 band = 2;
438 }
439 mode = 6;
440 cp = 1;
441 /* high band */
442 } else if (tuner_frequency < 662000000) {
443 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
444 band = 12;
445 } else {
446 band = 4;
447 }
448 mode = 7;
449 cp = 0;
450 } else if (tuner_frequency < 840000000) {
451 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
452 band = 12;
453 } else {
454 band = 4;
455 }
456 mode = 6;
457 cp = 1;
458 } else {
459 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
460 band = 12;
461 } else {
462 band = 4;
463 }
464 mode = 7;
465 cp = 1;
466
467 }
468 /* calculate divisor */
469 /* ((36166000 + Finput) / 166666) rounded! */
470 divider = (tuner_frequency + 83333) / 166667;
471
472 /* setup tuner buffer */
473 tuner_buf[0] = (divider >> 8) & 0x7f;
474 tuner_buf[1] = divider & 0xff;
475 tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4;
476 tuner_buf[3] = 0x40 | band;
477
478 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
479 return -EIO;
480 return 0;
481}
482
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700483static struct tda1004x_config medion_cardbus = {
484 .demod_address = 0x08,
485 .invert = 1,
486 .invert_oclk = 0,
487 .xtal_freq = TDA10046_XTAL_16M,
488 .agc_config = TDA10046_AGC_IFO_AUTO_NEG,
489 .if_freq = TDA10046_FREQ_3613,
490 .pll_init = philips_fmd1216_pll_init,
491 .pll_set = philips_fmd1216_pll_set,
492 .pll_sleep = philips_fmd1216_analog,
493 .request_firmware = NULL,
494};
495
496/* ------------------------------------------------------------------ */
497
498struct tda827x_data {
499 u32 lomax;
500 u8 spd;
501 u8 bs;
502 u8 bp;
503 u8 cp;
504 u8 gc3;
505 u8 div1p5;
506};
507
508static struct tda827x_data tda827x_dvbt[] = {
509 { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
510 { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
511 { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
512 { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
513 { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
514 { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
515 { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
516 { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
517 { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
518 { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
519 { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
520 { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
521 { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
522 { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
523 { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
524 { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
525 { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
526 { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
527 { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
528 { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
529 { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
530 { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
531 { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
532 { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
533 { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
534 { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
535 { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
536 { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
537 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
538};
539
540static int philips_tda827x_pll_init(struct dvb_frontend *fe)
541{
542 return 0;
543}
544
545static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
546{
547 struct saa7134_dev *dev = fe->dvb->priv;
548 u8 tuner_buf[14];
549
550 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
551 .len = sizeof(tuner_buf) };
552 int i, tuner_freq, if_freq;
553 u32 N;
554 switch (params->u.ofdm.bandwidth) {
555 case BANDWIDTH_6_MHZ:
556 if_freq = 4000000;
557 break;
558 case BANDWIDTH_7_MHZ:
559 if_freq = 4500000;
560 break;
561 default: /* 8 MHz or Auto */
562 if_freq = 5000000;
563 break;
564 }
565 tuner_freq = params->frequency + if_freq;
566
567 i = 0;
568 while (tda827x_dvbt[i].lomax < tuner_freq) {
569 if(tda827x_dvbt[i + 1].lomax == 0)
570 break;
571 i++;
572 }
573
574 N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2);
575 tuner_buf[0] = 0;
576 tuner_buf[1] = (N>>8) | 0x40;
577 tuner_buf[2] = N & 0xff;
578 tuner_buf[3] = 0;
579 tuner_buf[4] = 0x52;
580 tuner_buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) +
581 (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp;
582 tuner_buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f;
583 tuner_buf[7] = 0xbf;
584 tuner_buf[8] = 0x2a;
585 tuner_buf[9] = 0x05;
586 tuner_buf[10] = 0xff;
587 tuner_buf[11] = 0x00;
588 tuner_buf[12] = 0x00;
589 tuner_buf[13] = 0x40;
590
591 tuner_msg.len = 14;
592 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
593 return -EIO;
594
595 msleep(500);
596 /* correct CP value */
597 tuner_buf[0] = 0x30;
598 tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp;
599 tuner_msg.len = 2;
600 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
601
602 return 0;
603}
604
605static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
606{
607 struct saa7134_dev *dev = fe->dvb->priv;
608 static u8 tda827x_sleep[] = { 0x30, 0xd0};
609 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
610 .len = sizeof(tda827x_sleep) };
611 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
612}
613
614static struct tda1004x_config tda827x_lifeview_config = {
615 .demod_address = 0x08,
616 .invert = 1,
617 .invert_oclk = 0,
618 .xtal_freq = TDA10046_XTAL_16M,
619 .agc_config = TDA10046_AGC_TDA827X,
620 .if_freq = TDA10046_FREQ_045,
621 .pll_init = philips_tda827x_pll_init,
622 .pll_set = philips_tda827x_pll_set,
623 .pll_sleep = philips_tda827x_pll_sleep,
624 .request_firmware = NULL,
625};
626#endif
627
628/* ------------------------------------------------------------------ */
629
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630static int dvb_init(struct saa7134_dev *dev)
631{
632 /* init struct videobuf_dvb */
633 dev->ts.nr_bufs = 32;
634 dev->ts.nr_packets = 32*4;
635 dev->dvb.name = dev->name;
636 videobuf_queue_init(&dev->dvb.dvbq, &saa7134_ts_qops,
637 dev->pci, &dev->slock,
638 V4L2_BUF_TYPE_VIDEO_CAPTURE,
639 V4L2_FIELD_ALTERNATE,
640 sizeof(struct saa7134_buf),
641 dev);
642
643 switch (dev->board) {
Michael Krufky29780bb2005-07-27 11:45:59 -0700644#ifdef HAVE_MT352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
646 printk("%s: pinnacle 300i dvb setup\n",dev->name);
647 dev->dvb.frontend = mt352_attach(&pinnacle_300i,
648 &dev->i2c_adap);
649 break;
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700650#endif
Michael Krufky29780bb2005-07-27 11:45:59 -0700651#ifdef HAVE_TDA1004X
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 case SAA7134_BOARD_MD7134:
653 dev->dvb.frontend = tda10046_attach(&medion_cardbus,
654 &dev->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 break;
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700656 case SAA7134_BOARD_PHILIPS_TOUGH:
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800657 dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700658 &dev->i2c_adap);
659 break;
660 case SAA7134_BOARD_FLYDVBTDUO:
661 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
662 &dev->i2c_adap);
663 break;
664 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
665 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
666 &dev->i2c_adap);
667 break;
Hartmut Hackmann2cf36ac2005-11-08 21:36:32 -0800668 case SAA7134_BOARD_PHILIPS_EUROPA:
669 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
670 &dev->i2c_adap);
671 break;
672 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
673 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
674 &dev->i2c_adap);
675 break;
676 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
677 dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
678 &dev->i2c_adap);
679 break;
Mauro Carvalho Chehab86ddd962005-07-12 13:58:47 -0700680#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 default:
682 printk("%s: Huh? unknown DVB card?\n",dev->name);
683 break;
684 }
685
686 if (NULL == dev->dvb.frontend) {
687 printk("%s: frontend initialization failed\n",dev->name);
688 return -1;
689 }
690
691 /* register everything else */
692 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
693}
694
695static int dvb_fini(struct saa7134_dev *dev)
696{
697 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
698
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 switch (dev->board) {
700 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
701 /* otherwise we don't detect the tuner on next insmod */
702 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
703 break;
704 };
705 videobuf_dvb_unregister(&dev->dvb);
706 return 0;
707}
708
709static struct saa7134_mpeg_ops dvb_ops = {
710 .type = SAA7134_MPEG_DVB,
711 .init = dvb_init,
712 .fini = dvb_fini,
713};
714
715static int __init dvb_register(void)
716{
717 return saa7134_ts_register(&dvb_ops);
718}
719
720static void __exit dvb_unregister(void)
721{
722 saa7134_ts_unregister(&dvb_ops);
723}
724
725module_init(dvb_register);
726module_exit(dvb_unregister);
727
728/* ------------------------------------------------------------------ */
729/*
730 * Local variables:
731 * c-basic-offset: 8
732 * End:
733 */