initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / media / dvb / frontends / stv0299.c
blob17c1dd32acd5097a56c09b5746cbcb91ddc3947d
1 /*
2 Universal driver for STV0299/TDA5059/SL1935 based
3 DVB QPSK frontends
5 Alps BSRU6, LG TDQB-S00x
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 <ralph@convergence.de>,
9 <holger@convergence.de>,
10 <js@convergence.de>
13 Philips SU1278/SH
15 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
18 LG TDQF-S001F
20 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
21 & Andreas Oberritter <obi@linuxtv.org>
24 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
26 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
28 Support for Philips SU1278 on Technotrend hardware
30 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
32 This program is free software; you can redistribute it and/or modify
33 it under the terms of the GNU General Public License as published by
34 the Free Software Foundation; either version 2 of the License, or
35 (at your option) any later version.
37 This program is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
42 You should have received a copy of the GNU General Public License
43 along with this program; if not, write to the Free Software
44 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
46 */
48 #include <linux/init.h>
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/string.h>
52 #include <linux/slab.h>
53 #include <asm/div64.h>
55 #include "dvb_frontend.h"
56 #include "dvb_functions.h"
58 #if 0
59 #define dprintk(x...) printk(x)
60 #else
61 #define dprintk(x...)
62 #endif
64 static int stv0299_status = 0;
65 static int disable_typhoon = 0;
67 #define STATUS_BER 0
68 #define STATUS_UCBLOCKS 1
71 /* frontend types */
72 #define UNKNOWN_FRONTEND -1
73 #define PHILIPS_SU1278_TSA 0 // SU1278 with TSA5059 synth and datasheet recommended settings
74 #define ALPS_BSRU6 1
75 #define LG_TDQF_S001F 2
76 #define PHILIPS_SU1278_TUA 3 // SU1278 with TUA6100 synth
77 #define SAMSUNG_TBMU24112IMB 4
78 #define PHILIPS_SU1278_TSA_TT 5 // SU1278 with TSA5059 synth and TechnoTrend settings
79 #define PHILIPS_SU1278_TSA_TY 6 // SU1278 with TUA5059 synth and Typhoon wiring
81 /* Master Clock = 88 MHz */
82 #define M_CLK (88000000UL)
84 /* Master Clock for TT cards = 64 MHz */
85 #define M_CLK_SU1278_TSA_TT (64000000UL)
87 static struct dvb_frontend_info uni0299_info = {
88 .name = "STV0299/TSA5059/SL1935 based",
89 .type = FE_QPSK,
90 .frequency_min = 950000,
91 .frequency_max = 2150000,
92 .frequency_stepsize = 125, /* kHz for QPSK frontends */
93 .frequency_tolerance = M_CLK/2000,
94 .symbol_rate_min = 1000000,
95 .symbol_rate_max = 45000000,
96 .symbol_rate_tolerance = 500, /* ppm */
97 .notifier_delay = 0,
98 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
99 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
100 FE_CAN_QPSK |
101 FE_CAN_FEC_AUTO
105 struct stv0299_state {
106 u8 tuner_type;
107 u8 initialised:1;
108 u32 tuner_frequency;
109 u32 symbol_rate;
110 fe_code_rate_t fec_inner;
114 static u8 init_tab [] = {
115 0x04, 0x7d, /* F22FR = 0x7d */
116 /* F22 = f_VCO / 128 / 0x7d = 22 kHz */
118 /* I2C bus repeater */
119 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
121 /* general purpose DAC registers */
122 0x06, 0x40, /* DAC not used, set to high impendance mode */
123 0x07, 0x00, /* DAC LSB */
125 /* DiSEqC registers */
126 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
127 0x09, 0x00, /* FIFO */
129 /* Input/Output configuration register */
130 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
131 /* OP0 ctl = Normal, OP0 val = 1 (18 V) */
132 /* Nyquist filter = 00, QPSK reverse = 0 */
134 /* AGC1 control register */
135 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
137 /* Timing loop register */
138 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
140 0x10, 0x3f, // AGC2 0x3d
142 0x11, 0x84,
143 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
145 0x15, 0xc9, // lock detector threshold
147 0x16, 0x00,
148 0x17, 0x00,
149 0x18, 0x00,
150 0x19, 0x00,
151 0x1a, 0x00,
153 0x1f, 0x50,
155 0x20, 0x00,
156 0x21, 0x00,
157 0x22, 0x00,
158 0x23, 0x00,
160 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
162 0x29, 0x1e, // 1/2 threshold
163 0x2a, 0x14, // 2/3 threshold
164 0x2b, 0x0f, // 3/4 threshold
165 0x2c, 0x09, // 5/6 threshold
166 0x2d, 0x05, // 7/8 threshold
167 0x2e, 0x01,
169 0x31, 0x1f, // test all FECs
171 0x32, 0x19, // viterbi and synchro search
172 0x33, 0xfc, // rs control
173 0x34, 0x93, // error control
177 static u8 init_tab_samsung [] = {
178 0x01, 0x15,
179 0x02, 0x00,
180 0x03, 0x00,
181 0x04, 0x7D,
182 0x05, 0x35,
183 0x06, 0x02,
184 0x07, 0x00,
185 0x08, 0xC3,
186 0x0C, 0x00,
187 0x0D, 0x81,
188 0x0E, 0x23,
189 0x0F, 0x12,
190 0x10, 0x7E,
191 0x11, 0x84,
192 0x12, 0xB9,
193 0x13, 0x88,
194 0x14, 0x89,
195 0x15, 0xC9,
196 0x16, 0x00,
197 0x17, 0x5C,
198 0x18, 0x00,
199 0x19, 0x00,
200 0x1A, 0x00,
201 0x1C, 0x00,
202 0x1D, 0x00,
203 0x1E, 0x00,
204 0x1F, 0x3A,
205 0x20, 0x2E,
206 0x21, 0x80,
207 0x22, 0xFF,
208 0x23, 0xC1,
209 0x28, 0x00,
210 0x29, 0x1E,
211 0x2A, 0x14,
212 0x2B, 0x0F,
213 0x2C, 0x09,
214 0x2D, 0x05,
215 0x31, 0x1F,
216 0x32, 0x19,
217 0x33, 0xFE,
218 0x34, 0x93
222 static u8 init_tab_su1278_tsa_tt [] = {
223 0x01, 0x0f,
224 0x02, 0x30,
225 0x03, 0x00,
226 0x04, 0x5b,
227 0x05, 0x85,
228 0x06, 0x02,
229 0x07, 0x00,
230 0x08, 0x02,
231 0x09, 0x00,
232 0x0C, 0x01,
233 0x0D, 0x81,
234 0x0E, 0x44,
235 0x0f, 0x14,
236 0x10, 0x3c,
237 0x11, 0x84,
238 0x12, 0xda,
239 0x13, 0x97,
240 0x14, 0x95,
241 0x15, 0xc9,
242 0x16, 0x19,
243 0x17, 0x8c,
244 0x18, 0x59,
245 0x19, 0xf8,
246 0x1a, 0xfe,
247 0x1c, 0x7f,
248 0x1d, 0x00,
249 0x1e, 0x00,
250 0x1f, 0x50,
251 0x20, 0x00,
252 0x21, 0x00,
253 0x22, 0x00,
254 0x23, 0x00,
255 0x28, 0x00,
256 0x29, 0x28,
257 0x2a, 0x14,
258 0x2b, 0x0f,
259 0x2c, 0x09,
260 0x2d, 0x09,
261 0x31, 0x1f,
262 0x32, 0x19,
263 0x33, 0xfc,
264 0x34, 0x13
267 static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec);
268 static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner_type);
270 static int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
272 int ret;
273 u8 buf [] = { reg, data };
274 struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 };
276 ret = i2c->xfer (i2c, &msg, 1);
278 if (ret != 1)
279 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
280 "ret == %i)\n", __FUNCTION__, reg, data, ret);
282 return (ret != 1) ? -1 : 0;
286 static u8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg)
288 int ret;
289 u8 b0 [] = { reg };
290 u8 b1 [] = { 0 };
291 struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = b0, .len = 1 },
292 { .addr = 0x68, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
294 ret = i2c->xfer (i2c, msg, 2);
296 if (ret != 2)
297 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
298 __FUNCTION__, reg, ret);
300 return b1[0];
304 static int stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len)
306 int ret;
307 struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = &reg1, .len = 1 },
308 { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } };
310 ret = i2c->xfer (i2c, msg, 2);
312 if (ret != 2)
313 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
315 return ret == 2 ? 0 : ret;
319 static int pll_write (struct dvb_i2c_bus *i2c, u8 addr, u8 *data, int len)
321 int ret;
322 struct i2c_msg msg = { .addr = addr, .buf = data, .len = len };
325 stv0299_writereg(i2c, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
327 ret = i2c->xfer (i2c, &msg, 1);
329 stv0299_writereg(i2c, 0x05, 0x35); /* disable i2c repeater on stv0299 */
331 if (ret != 1)
332 dprintk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);
334 return (ret != 1) ? -1 : 0;
338 static int sl1935_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype)
340 u8 buf[4];
341 u32 div;
343 div = freq / 125;
345 dprintk("%s : freq = %i, div = %i\n", __FUNCTION__, freq, div);
347 buf[0] = (div >> 8) & 0x7f;
348 buf[1] = div & 0xff;
349 buf[2] = 0x84; // 0xC4
350 buf[3] = 0x08;
352 if (freq < 1500000) buf[3] |= 0x10;
354 return pll_write (i2c, 0x61, buf, sizeof(buf));
358 * set up the downconverter frequency divisor for a
359 * reference clock comparision frequency of 125 kHz.
361 static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate)
363 u8 addr;
364 u32 div;
365 u8 buf[4];
366 int divisor, regcode;
368 dprintk ("%s: freq %i, ftype %i\n", __FUNCTION__, freq, ftype);
370 if ((freq < 950000) || (freq > 2150000)) return -EINVAL;
372 if (ftype == PHILIPS_SU1278_TSA_TT) {
373 divisor = 500;
374 regcode = 2;
375 } else {
376 divisor = 125;
377 regcode = 4;
380 // setup frequency divisor
381 div = (freq + (divisor - 1)) / divisor; // round correctly
382 buf[0] = (div >> 8) & 0x7f;
383 buf[1] = div & 0xff;
384 buf[2] = 0x80 | ((div & 0x18000) >> 10) | regcode;
385 buf[3] = 0;
387 // tuner-specific settings
388 switch(ftype) {
389 case PHILIPS_SU1278_TSA:
390 case PHILIPS_SU1278_TSA_TT:
391 case PHILIPS_SU1278_TSA_TY:
392 if (ftype == PHILIPS_SU1278_TSA_TY)
393 addr = 0x61;
394 else
395 addr = 0x60;
397 buf[3] |= 0x20;
399 if (srate < 4000000) buf[3] |= 1;
401 if (freq < 1250000) buf[3] |= 0;
402 else if (freq < 1550000) buf[3] |= 0x40;
403 else if (freq < 2050000) buf[3] |= 0x80;
404 else if (freq < 2150000) buf[3] |= 0xC0;
405 break;
407 case ALPS_BSRU6:
408 addr = 0x61;
409 buf[3] = 0xC4;
410 if (freq > 1530000) buf[3] = 0xc0;
411 break;
413 default:
414 return -EINVAL;
417 return pll_write (i2c, addr, buf, sizeof(buf));
421 #define MIN2(a,b) ((a) < (b) ? (a) : (b))
422 #define MIN3(a,b,c) MIN2(MIN2(a,b),c)
424 static int tua6100_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq,
425 int ftype, int srate)
427 u8 reg0 [2] = { 0x00, 0x00 };
428 u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 };
429 u8 reg2 [3] = { 0x02, 0x00, 0x00 };
430 int _fband;
431 int first_ZF;
432 int R, A, N, P, M;
433 int err;
435 first_ZF = (freq) / 1000;
437 if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) <
438 abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890))))
439 _fband = 2;
440 else
441 _fband = 3;
443 if (_fband == 2) {
444 if (((first_ZF >= 950) && (first_ZF < 1350)) ||
445 ((first_ZF >= 1430) && (first_ZF < 1950)))
446 reg0[1] = 0x07;
447 else if (((first_ZF >= 1350) && (first_ZF < 1430)) ||
448 ((first_ZF >= 1950) && (first_ZF < 2150)))
449 reg0[1] = 0x0B;
452 if(_fband == 3) {
453 if (((first_ZF >= 950) && (first_ZF < 1350)) ||
454 ((first_ZF >= 1455) && (first_ZF < 1950)))
455 reg0[1] = 0x07;
456 else if (((first_ZF >= 1350) && (first_ZF < 1420)) ||
457 ((first_ZF >= 1950) && (first_ZF < 2150)))
458 reg0[1] = 0x0B;
459 else if ((first_ZF >= 1420) && (first_ZF < 1455))
460 reg0[1] = 0x0F;
463 if (first_ZF > 1525)
464 reg1[1] |= 0x80;
465 else
466 reg1[1] &= 0x7F;
468 if (_fband == 2) {
469 if (first_ZF > 1430) { /* 1430MHZ */
470 reg1[1] &= 0xCF; /* N2 */
471 reg2[1] &= 0xCF; /* R2 */
472 reg2[1] |= 0x10;
473 } else {
474 reg1[1] &= 0xCF; /* N2 */
475 reg1[1] |= 0x20;
476 reg2[1] &= 0xCF; /* R2 */
477 reg2[1] |= 0x10;
481 if (_fband == 3) {
482 if ((first_ZF >= 1455) &&
483 (first_ZF < 1630)) {
484 reg1[1] &= 0xCF; /* N2 */
485 reg1[1] |= 0x20;
486 reg2[1] &= 0xCF; /* R2 */
487 } else {
488 if (first_ZF < 1455) {
489 reg1[1] &= 0xCF; /* N2 */
490 reg1[1] |= 0x20;
491 reg2[1] &= 0xCF; /* R2 */
492 reg2[1] |= 0x10;
493 } else {
494 if (first_ZF >= 1630) {
495 reg1[1] &= 0xCF; /* N2 */
496 reg2[1] &= 0xCF; /* R2 */
497 reg2[1] |= 0x10;
503 /* set ports, enable P0 for symbol rates > 4Ms/s */
504 if (srate >= 4000000)
505 reg1[1] |= 0x0c;
506 else
507 reg1[1] |= 0x04;
509 reg2[1] |= 0x0c;
511 R = 64;
512 A = 64;
513 P = 64; //32
515 M = (freq * R) / 4; /* in Mhz */
516 N = (M - A * 1000) / (P * 1000);
518 reg1[1] |= (N >> 9) & 0x03;
519 reg1[2] = (N >> 1) & 0xff;
520 reg1[3] = (N << 7) & 0x80;
522 reg2[1] |= (R >> 8) & 0x03;
523 reg2[2] = R & 0xFF; /* R */
525 reg1[3] |= A & 0x7f; /* A */
527 if (P == 64)
528 reg1[1] |= 0x40; /* Prescaler 64/65 */
530 reg0[1] |= 0x03;
532 if ((err = pll_write(i2c, 0x60, reg0, sizeof(reg0))))
533 return err;
535 if ((err = pll_write(i2c, 0x60, reg1, sizeof(reg1))))
536 return err;
538 if ((err = pll_write(i2c, 0x60, reg2, sizeof(reg2))))
539 return err;
541 return 0;
545 static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate)
547 switch(ftype) {
548 case SAMSUNG_TBMU24112IMB:
549 return sl1935_set_tv_freq(i2c, freq, ftype);
551 case LG_TDQF_S001F:
552 return sl1935_set_tv_freq(i2c, freq, ftype);
554 case PHILIPS_SU1278_TUA:
555 return tua6100_set_tv_freq(i2c, freq, ftype, srate);
557 default:
558 return tsa5059_set_tv_freq(i2c, freq, ftype, srate);
562 #if 0
563 static int tsa5059_read_status (struct dvb_i2c_bus *i2c)
565 int ret;
566 u8 rpt1 [] = { 0x05, 0xb5 };
567 u8 stat [] = { 0 };
569 struct i2c_msg msg [] = {{ .addr = 0x68, .flags = 0, .buf = rpt1, .len = 2 },
570 { .addr = 0x60, .flags = I2C_M_RD, .buf = stat, .len = 1 }};
572 dprintk ("%s\n", __FUNCTION__);
574 ret = i2c->xfer (i2c, msg, 2);
576 if (ret != 2)
577 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
579 return stat[0];
581 #endif
584 static int stv0299_init (struct dvb_i2c_bus *i2c, int ftype)
586 int i;
588 dprintk("stv0299: init chip\n");
590 switch(ftype) {
591 case SAMSUNG_TBMU24112IMB:
592 dprintk("%s: init stv0299 chip for Samsung TBMU24112IMB\n", __FUNCTION__);
594 for (i=0; i<sizeof(init_tab_samsung); i+=2)
596 dprintk("%s: reg == 0x%02x, val == 0x%02x\n", __FUNCTION__, init_tab_samsung[i], init_tab_samsung[i+1]);
598 stv0299_writereg (i2c, init_tab_samsung[i], init_tab_samsung[i+1]);
600 break;
602 case PHILIPS_SU1278_TSA_TT:
603 for (i=0; i<sizeof(init_tab_su1278_tsa_tt); i+=2) {
604 stv0299_writereg (i2c, init_tab_su1278_tsa_tt[i], init_tab_su1278_tsa_tt[i+1]);
606 break;
608 default:
609 stv0299_writereg (i2c, 0x01, 0x15);
610 stv0299_writereg (i2c, 0x02, ftype == PHILIPS_SU1278_TUA ? 0x00 : 0x30);
611 stv0299_writereg (i2c, 0x03, 0x00);
613 for (i=0; i<sizeof(init_tab); i+=2)
614 stv0299_writereg (i2c, init_tab[i], init_tab[i+1]);
616 /* AGC1 reference register setup */
617 if (ftype == PHILIPS_SU1278_TSA || ftype == PHILIPS_SU1278_TSA_TY)
618 stv0299_writereg (i2c, 0x0f, 0x92); /* Iagc = Inverse, m1 = 18 */
619 else if (ftype == PHILIPS_SU1278_TUA)
620 stv0299_writereg (i2c, 0x0f, 0x94); /* Iagc = Inverse, m1 = 20 */
621 else
622 stv0299_writereg (i2c, 0x0f, 0x52); /* Iagc = Normal, m1 = 18 */
623 break;
626 switch(stv0299_status) {
627 case STATUS_BER:
628 stv0299_writereg(i2c, 0x34, 0x93);
629 break;
631 case STATUS_UCBLOCKS:
632 stv0299_writereg(i2c, 0x34, 0xB3);
633 break;
636 return 0;
640 static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec)
642 dprintk ("%s\n", __FUNCTION__);
644 switch (fec) {
645 case FEC_AUTO:
647 dprintk ("%s : FEC_AUTO\n", __FUNCTION__);
648 return stv0299_writereg (i2c, 0x31, 0x1f);
650 case FEC_1_2:
652 dprintk ("%s : FEC_1_2\n", __FUNCTION__);
653 return stv0299_writereg (i2c, 0x31, 0x01);
655 case FEC_2_3:
657 dprintk ("%s : FEC_2_3\n", __FUNCTION__);
658 return stv0299_writereg (i2c, 0x31, 0x02);
660 case FEC_3_4:
662 dprintk ("%s : FEC_3_4\n", __FUNCTION__);
663 return stv0299_writereg (i2c, 0x31, 0x04);
665 case FEC_5_6:
667 dprintk ("%s : FEC_5_6\n", __FUNCTION__);
668 return stv0299_writereg (i2c, 0x31, 0x08);
670 case FEC_7_8:
672 dprintk ("%s : FEC_7_8\n", __FUNCTION__);
673 return stv0299_writereg (i2c, 0x31, 0x10);
675 default:
677 dprintk ("%s : FEC invalid\n", __FUNCTION__);
678 return -EINVAL;
684 static fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c)
686 static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
687 FEC_7_8, FEC_1_2 };
688 u8 index;
690 dprintk ("%s\n", __FUNCTION__);
692 index = stv0299_readreg (i2c, 0x1b);
693 index &= 0x7;
695 if (index > 4)
696 return FEC_AUTO;
698 return fec_tab [index];
702 static int stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout)
704 unsigned long start = jiffies;
706 dprintk ("%s\n", __FUNCTION__);
708 while (stv0299_readreg(i2c, 0x0a) & 1) {
709 if (jiffies - start > timeout) {
710 dprintk ("%s: timeout!!\n", __FUNCTION__);
711 return -ETIMEDOUT;
713 dvb_delay(10);
716 return 0;
720 static int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout)
722 unsigned long start = jiffies;
724 dprintk ("%s\n", __FUNCTION__);
726 while ((stv0299_readreg(i2c, 0x0a) & 3) != 2 ) {
727 if (jiffies - start > timeout) {
728 dprintk ("%s: timeout!!\n", __FUNCTION__);
729 return -ETIMEDOUT;
731 dvb_delay(10);
734 return 0;
738 static int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c,
739 struct dvb_diseqc_master_cmd *m)
741 u8 val;
742 int i;
744 dprintk ("%s\n", __FUNCTION__);
746 if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
747 return -ETIMEDOUT;
749 val = stv0299_readreg (i2c, 0x08);
751 if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */
752 return -EREMOTEIO;
754 for (i=0; i<m->msg_len; i++) {
755 if (stv0299_wait_diseqc_fifo (i2c, 100) < 0)
756 return -ETIMEDOUT;
758 if (stv0299_writereg (i2c, 0x09, m->msg[i]))
759 return -EREMOTEIO;
762 if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
763 return -ETIMEDOUT;
765 return 0;
769 static int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst)
771 u8 val;
773 dprintk ("%s\n", __FUNCTION__);
775 if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
776 return -ETIMEDOUT;
778 val = stv0299_readreg (i2c, 0x08);
780 if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x2)) /* burst mode */
781 return -EREMOTEIO;
783 if (stv0299_writereg (i2c, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
784 return -EREMOTEIO;
786 if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
787 return -ETIMEDOUT;
789 if (stv0299_writereg (i2c, 0x08, val))
790 return -EREMOTEIO;
792 return 0;
796 static int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone)
798 u8 val;
800 dprintk("%s: %s\n", __FUNCTION__,
801 tone == SEC_TONE_ON ? "SEC_TONE_ON" :
802 tone == SEC_TONE_OFF ? "SEC_TONE_OFF" : "??");
804 if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
805 return -ETIMEDOUT;
807 val = stv0299_readreg (i2c, 0x08);
809 switch (tone) {
810 case SEC_TONE_ON:
812 dprintk("%s: TONE_ON\n", __FUNCTION__);
813 return stv0299_writereg (i2c, 0x08, val | 0x3);
815 case SEC_TONE_OFF:
817 dprintk("%s: TONE_OFF\n", __FUNCTION__);
818 return stv0299_writereg (i2c, 0x08, (val & ~0x3) | 0x02);
820 default:
822 dprintk("%s: TONE INVALID\n", __FUNCTION__);
823 return -EINVAL;
829 static int stv0299_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage,
830 int tuner_type)
832 u8 reg0x08;
833 u8 reg0x0c;
835 dprintk("%s: %s\n", __FUNCTION__,
836 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
837 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
839 reg0x08 = stv0299_readreg (i2c, 0x08);
840 reg0x0c = stv0299_readreg (i2c, 0x0c);
843 * H/V switching over OP0, OP1 and OP2 are LNB power enable bits
845 reg0x0c &= 0x0f;
847 if (voltage == SEC_VOLTAGE_OFF) {
848 stv0299_writereg (i2c, 0x0c, 0x00); /* LNB power off! */
849 return stv0299_writereg (i2c, 0x08, 0x00); /* LNB power off! */
852 stv0299_writereg (i2c, 0x08, reg0x08 | 0x40);
854 switch (voltage) {
855 case SEC_VOLTAGE_13:
856 if (tuner_type == PHILIPS_SU1278_TSA_TY)
857 return stv0299_writereg (i2c, 0x0c, reg0x0c | 0x10);
858 else
859 return stv0299_writereg (i2c, 0x0c, reg0x0c | 0x40);
861 case SEC_VOLTAGE_18:
862 return stv0299_writereg (i2c, 0x0c, reg0x0c | 0x50);
864 default:
865 return -EINVAL;
870 static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner_type)
872 u64 big = srate;
873 u32 ratio;
874 u8 aclk = 0;
875 u8 bclk = 0;
876 u8 m1;
877 int Mclk = M_CLK;
879 // check rate is within limits
880 if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
882 // calculate value to program
883 if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT;
884 big = big << 20;
885 big += (Mclk-1); // round correctly
886 do_div(big, Mclk);
887 ratio = big << 4;
889 // program registers
890 switch(tuner_type) {
891 case PHILIPS_SU1278_TSA_TT:
892 stv0299_writereg (i2c, 0x0e, 0x44);
893 if (srate >= 10000000) {
894 stv0299_writereg (i2c, 0x13, 0x97);
895 stv0299_writereg (i2c, 0x14, 0x95);
896 stv0299_writereg (i2c, 0x15, 0xc9);
897 stv0299_writereg (i2c, 0x17, 0x8c);
898 stv0299_writereg (i2c, 0x1a, 0xfe);
899 stv0299_writereg (i2c, 0x1c, 0x7f);
900 stv0299_writereg (i2c, 0x2d, 0x09);
901 } else {
902 stv0299_writereg (i2c, 0x13, 0x99);
903 stv0299_writereg (i2c, 0x14, 0x8d);
904 stv0299_writereg (i2c, 0x15, 0xce);
905 stv0299_writereg (i2c, 0x17, 0x43);
906 stv0299_writereg (i2c, 0x1a, 0x1d);
907 stv0299_writereg (i2c, 0x1c, 0x12);
908 stv0299_writereg (i2c, 0x2d, 0x05);
910 stv0299_writereg (i2c, 0x0e, 0x23);
911 stv0299_writereg (i2c, 0x0f, 0x94);
912 stv0299_writereg (i2c, 0x10, 0x39);
913 stv0299_writereg (i2c, 0x15, 0xc9);
915 stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff);
916 stv0299_writereg (i2c, 0x20, (ratio >> 8) & 0xff);
917 stv0299_writereg (i2c, 0x21, (ratio ) & 0xf0);
918 break;
920 case PHILIPS_SU1278_TSA_TY:
921 case PHILIPS_SU1278_TSA:
922 aclk = 0xb5;
923 if (srate < 2000000) bclk = 0x86;
924 else if (srate < 5000000) bclk = 0x89;
925 else if (srate < 15000000) bclk = 0x8f;
926 else if (srate < 45000000) bclk = 0x95;
928 m1 = 0x14;
929 if (srate < 4000000) m1 = 0x10;
931 stv0299_writereg (i2c, 0x13, aclk);
932 stv0299_writereg (i2c, 0x14, bclk);
933 stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff);
934 stv0299_writereg (i2c, 0x20, (ratio >> 8) & 0xff);
935 stv0299_writereg (i2c, 0x21, (ratio ) & 0xf0);
936 stv0299_writereg (i2c, 0x0f, (stv0299_readreg(i2c, 0x0f) & 0xc0) | m1);
937 break;
939 case ALPS_BSRU6:
940 default:
941 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
942 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
943 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
944 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
945 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
946 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
948 stv0299_writereg (i2c, 0x13, aclk);
949 stv0299_writereg (i2c, 0x14, bclk);
950 stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff);
951 stv0299_writereg (i2c, 0x20, (ratio >> 8) & 0xff);
952 stv0299_writereg (i2c, 0x21, (ratio ) & 0xf0);
953 break;
957 return 0;
961 static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c, int tuner_type)
963 u32 Mclk = M_CLK / 4096L;
964 u32 srate;
965 s32 offset;
966 u8 sfr[3];
967 s8 rtf;
969 dprintk ("%s\n", __FUNCTION__);
971 if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT / 4096L;
973 stv0299_readregs (i2c, 0x1f, sfr, 3);
974 stv0299_readregs (i2c, 0x1a, &rtf, 1);
976 srate = (sfr[0] << 8) | sfr[1];
977 srate *= Mclk;
978 srate /= 16;
979 srate += (sfr[2] >> 4) * Mclk / 256;
981 offset = (s32) rtf * (srate / 4096L);
982 offset /= 128;
984 dprintk ("%s : srate = %i\n", __FUNCTION__, srate);
985 dprintk ("%s : ofset = %i\n", __FUNCTION__, offset);
987 srate += offset;
989 srate += 1000;
990 srate /= 2000;
991 srate *= 2000;
993 return srate;
996 static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
998 struct dvb_i2c_bus *i2c = fe->i2c;
999 struct stv0299_state *state = (struct stv0299_state *) fe->data;
1001 dprintk ("%s\n", __FUNCTION__);
1003 switch (cmd) {
1004 case FE_GET_INFO:
1006 struct dvb_frontend_info* tmp = (struct dvb_frontend_info*) arg;
1007 memcpy (arg, &uni0299_info, sizeof(struct dvb_frontend_info));
1009 if (state->tuner_type == PHILIPS_SU1278_TSA_TT) {
1010 tmp->frequency_tolerance = M_CLK_SU1278_TSA_TT / 2000;
1012 break;
1015 case FE_READ_STATUS:
1017 fe_status_t *status = (fe_status_t *) arg;
1018 u8 signal = 0xff - stv0299_readreg (i2c, 0x18);
1019 u8 sync = stv0299_readreg (i2c, 0x1b);
1021 dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __FUNCTION__, sync);
1023 *status = 0;
1025 if (signal > 10)
1026 *status |= FE_HAS_SIGNAL;
1028 if (sync & 0x80)
1029 *status |= FE_HAS_CARRIER;
1031 if (sync & 0x10)
1032 *status |= FE_HAS_VITERBI;
1034 if (sync & 0x08)
1035 *status |= FE_HAS_SYNC;
1037 if ((sync & 0x98) == 0x98)
1038 *status |= FE_HAS_LOCK;
1040 break;
1043 case FE_READ_BER:
1044 if (stv0299_status == STATUS_BER) {
1045 *((u32*) arg) = (stv0299_readreg (i2c, 0x1d) << 8)
1046 | stv0299_readreg (i2c, 0x1e);
1047 } else {
1048 *((u32*) arg) = 0;
1050 break;
1052 case FE_READ_SIGNAL_STRENGTH:
1054 s32 signal = 0xffff - ((stv0299_readreg (i2c, 0x18) << 8)
1055 | stv0299_readreg (i2c, 0x19));
1057 dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __FUNCTION__,
1058 stv0299_readreg (i2c, 0x18),
1059 stv0299_readreg (i2c, 0x19), (int) signal);
1061 signal = signal * 5 / 4;
1062 *((u16*) arg) = (signal > 0xffff) ? 0xffff :
1063 (signal < 0) ? 0 : signal;
1064 break;
1066 case FE_READ_SNR:
1068 s32 snr = 0xffff - ((stv0299_readreg (i2c, 0x24) << 8)
1069 | stv0299_readreg (i2c, 0x25));
1070 snr = 3 * (snr - 0xa100);
1071 *((u16*) arg) = (snr > 0xffff) ? 0xffff :
1072 (snr < 0) ? 0 : snr;
1073 break;
1075 case FE_READ_UNCORRECTED_BLOCKS:
1076 if (stv0299_status == STATUS_UCBLOCKS) {
1077 *((u32*) arg) = (stv0299_readreg (i2c, 0x1d) << 8)
1078 | stv0299_readreg (i2c, 0x1e);
1079 } else {
1080 *((u32*) arg) = 0;
1082 break;
1084 case FE_SET_FRONTEND:
1086 struct dvb_frontend_parameters *p = arg;
1087 int invval = 0;
1089 dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
1091 // set the inversion
1092 if (p->inversion == INVERSION_OFF) invval = 0;
1093 else if (p->inversion == INVERSION_ON) invval = 1;
1094 else {
1095 printk("stv0299 does not support auto-inversion\n");
1096 return -EINVAL;
1098 if (state->tuner_type == ALPS_BSRU6) invval = (~invval) & 1;
1099 stv0299_writereg(i2c, 0x0c, (stv0299_readreg(i2c, 0x0c) & 0xfe) | invval);
1101 switch(state->tuner_type) {
1102 case PHILIPS_SU1278_TSA_TT:
1104 /* check if we should do a finetune */
1105 int frequency_delta = p->frequency - state->tuner_frequency;
1106 int minmax = p->u.qpsk.symbol_rate / 2000;
1107 if (minmax < 5000) minmax = 5000;
1109 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
1110 (state->fec_inner == p->u.qpsk.fec_inner) &&
1111 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
1112 int Drot_freq = (frequency_delta << 16) / (M_CLK_SU1278_TSA_TT / 1000);
1114 // zap the derotator registers first
1115 stv0299_writereg (i2c, 0x22, 0x00);
1116 stv0299_writereg (i2c, 0x23, 0x00);
1118 // now set them as we want
1119 stv0299_writereg (i2c, 0x22, Drot_freq >> 8);
1120 stv0299_writereg (i2c, 0x23, Drot_freq);
1121 } else {
1122 /* A "normal" tune is requested */
1123 pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate);
1124 stv0299_writereg (i2c, 0x32, 0x80);
1125 stv0299_writereg (i2c, 0x22, 0x00);
1126 stv0299_writereg (i2c, 0x23, 0x00);
1127 stv0299_writereg (i2c, 0x32, 0x19);
1128 stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, state->tuner_type);
1129 stv0299_set_FEC (i2c, p->u.qpsk.fec_inner);
1131 break;
1134 default:
1135 pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate);
1136 stv0299_set_FEC (i2c, p->u.qpsk.fec_inner);
1137 stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, state->tuner_type);
1138 stv0299_writereg (i2c, 0x22, 0x00);
1139 stv0299_writereg (i2c, 0x23, 0x00);
1140 stv0299_readreg (i2c, 0x23);
1141 stv0299_writereg (i2c, 0x12, 0xb9);
1142 break;
1145 state->tuner_frequency = p->frequency;
1146 state->fec_inner = p->u.qpsk.fec_inner;
1147 state->symbol_rate = p->u.qpsk.symbol_rate;
1148 break;
1151 case FE_GET_FRONTEND:
1153 struct dvb_frontend_parameters *p = arg;
1154 s32 derot_freq;
1155 int Mclk = M_CLK;
1156 int invval;
1158 if (state->tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT;
1160 derot_freq = (s32)(s16) ((stv0299_readreg (i2c, 0x22) << 8)
1161 | stv0299_readreg (i2c, 0x23));
1163 derot_freq *= (Mclk >> 16);
1164 derot_freq += 500;
1165 derot_freq /= 1000;
1167 p->frequency += derot_freq;
1169 invval = stv0299_readreg (i2c, 0x0c) & 1;
1170 if (state->tuner_type == ALPS_BSRU6) invval = (~invval) & 1;
1171 p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
1173 p->u.qpsk.fec_inner = stv0299_get_fec (i2c);
1174 p->u.qpsk.symbol_rate = stv0299_get_symbolrate (i2c, state->tuner_type);
1175 break;
1178 case FE_SLEEP:
1179 stv0299_writereg (i2c, 0x0c, 0x00); /* LNB power off! */
1180 stv0299_writereg (i2c, 0x08, 0x00); /* LNB power off! */
1181 stv0299_writereg (i2c, 0x02, 0x80);
1182 state->initialised = 0;
1183 break;
1185 case FE_INIT:
1186 switch(state->tuner_type) {
1187 case PHILIPS_SU1278_TSA_TT:
1188 state->tuner_frequency = 0;
1189 if (!state->initialised) {
1190 state->initialised = 1;
1191 return stv0299_init (i2c, state->tuner_type);
1193 break;
1195 default:
1196 return stv0299_init (i2c, state->tuner_type);
1198 break;
1200 case FE_DISEQC_SEND_MASTER_CMD:
1201 return stv0299_send_diseqc_msg (i2c, arg);
1203 case FE_DISEQC_SEND_BURST:
1204 return stv0299_send_diseqc_burst (i2c, (fe_sec_mini_cmd_t) arg);
1206 case FE_SET_TONE:
1207 return stv0299_set_tone (i2c, (fe_sec_tone_mode_t) arg);
1209 case FE_SET_VOLTAGE:
1210 return stv0299_set_voltage (i2c, (fe_sec_voltage_t) arg,
1211 state->tuner_type);
1213 case FE_GET_TUNE_SETTINGS:
1215 struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg;
1217 switch(state->tuner_type) {
1218 case PHILIPS_SU1278_TSA_TT:
1219 fesettings->min_delay_ms = 50;
1220 if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
1221 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
1222 fesettings->max_drift = 5000;
1223 } else {
1224 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
1225 fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
1227 break;
1229 default:
1230 fesettings->min_delay_ms = 100;
1231 if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
1232 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
1233 fesettings->max_drift = 5000;
1234 } else {
1235 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
1236 fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
1238 break;
1241 return 0;
1244 default:
1245 return -EOPNOTSUPP;
1248 return 0;
1251 static long probe_tuner (struct dvb_i2c_bus *i2c)
1253 struct dvb_adapter * adapter = (struct dvb_adapter *) i2c->adapter;
1255 /* read the status register of TSA5059 */
1256 u8 rpt[] = { 0x05, 0xb5 };
1257 u8 stat [] = { 0 };
1258 u8 tda6100_buf [] = { 0, 0 };
1259 int ret;
1260 struct i2c_msg msg1 [] = {{ .addr = 0x68, .buf = rpt, .len = 2 },
1261 { .addr = 0x60, .flags = I2C_M_RD, .buf = stat, .len = 1 }};
1262 struct i2c_msg msg2 [] = {{ .addr = 0x68, .buf = rpt, .len = 2 },
1263 { .addr = 0x61, .flags = I2C_M_RD, .buf = stat, .len = 1 }};
1264 struct i2c_msg msg3 [] = {{ .addr = 0x68, .buf = rpt, .len = 2 },
1265 { .addr = 0x60, .buf = tda6100_buf, .len = 2 }};
1267 stv0299_writereg (i2c, 0x01, 0x15);
1268 stv0299_writereg (i2c, 0x02, 0x30);
1269 stv0299_writereg (i2c, 0x03, 0x00);
1272 printk ("%s: try to attach to %s\n", __FUNCTION__, adapter->name);
1274 if ( strcmp(adapter->name, "SkyStar2") == 0 )
1276 printk ("%s: setup for tuner Samsung TBMU24112IMB\n", __FILE__);
1278 return SAMSUNG_TBMU24112IMB;
1281 if ((ret = i2c->xfer(i2c, msg1, 2)) == 2) {
1282 if ( strcmp(adapter->name, "TT-Budget/WinTV-NOVA-CI PCI") == 0 ) {
1283 // technotrend cards require non-datasheet settings
1284 printk ("%s: setup for tuner SU1278 (TSA5059 synth) on"
1285 " TechnoTrend hardware\n", __FILE__);
1286 return PHILIPS_SU1278_TSA_TT;
1287 } else {
1288 // fall back to datasheet-recommended settings
1289 printk ("%s: setup for tuner SU1278 (TSA5059 synth)\n",
1290 __FILE__);
1291 return PHILIPS_SU1278_TSA;
1295 if ((ret = i2c->xfer(i2c, msg2, 2)) == 2) {
1296 if ( strcmp(adapter->name, "KNC1 DVB-S") == 0 &&
1297 !disable_typhoon )
1299 // Typhoon cards have unusual wiring.
1300 printk ("%s: setup for tuner SU1278 (TSA5059 synth) on"
1301 " Typhoon hardware\n", __FILE__);
1302 return PHILIPS_SU1278_TSA_TY;
1304 //else if ((stat[0] & 0x3f) == 0) {
1305 else if (0) {
1306 printk ("%s: setup for tuner TDQF-S001F\n", __FILE__);
1307 return LG_TDQF_S001F;
1308 } else {
1309 printk ("%s: setup for tuner BSRU6, TDQB-S00x\n",
1310 __FILE__);
1311 return ALPS_BSRU6;
1316 * setup i2c timing for SU1278...
1318 stv0299_writereg (i2c, 0x02, 0x00);
1320 if ((ret = i2c->xfer(i2c, msg3, 2)) == 2) {
1321 printk ("%s: setup for tuner Philips SU1278 (TUA6100 synth)\n",
1322 __FILE__);
1323 return PHILIPS_SU1278_TUA;
1326 printk ("%s: unknown PLL synthesizer (ret == %i), "
1327 "please report to <linuxdvb@linuxtv.org>!!\n",
1328 __FILE__, ret);
1330 return UNKNOWN_FRONTEND;
1334 static int uni0299_attach (struct dvb_i2c_bus *i2c, void **data)
1336 struct stv0299_state* state;
1337 int tuner_type;
1338 u8 id;
1340 stv0299_writereg (i2c, 0x02, 0x34); /* standby off */
1341 dvb_delay(200);
1342 id = stv0299_readreg (i2c, 0x00);
1344 dprintk ("%s: id == 0x%02x\n", __FUNCTION__, id);
1346 /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
1347 /* register 0x00 might contain 0x80 when returning from standby */
1348 if (id != 0xa1 && id != 0x80)
1349 return -ENODEV;
1351 if ((tuner_type = probe_tuner(i2c)) < 0)
1352 return -ENODEV;
1354 if ((state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL)) == NULL) {
1355 return -ENOMEM;
1358 *data = state;
1359 state->tuner_type = tuner_type;
1360 state->tuner_frequency = 0;
1361 state->initialised = 0;
1362 return dvb_register_frontend (uni0299_ioctl, i2c, (void *) state,
1363 &uni0299_info);
1367 static void uni0299_detach (struct dvb_i2c_bus *i2c, void *data)
1369 dprintk ("%s\n", __FUNCTION__);
1370 kfree(data);
1371 dvb_unregister_frontend (uni0299_ioctl, i2c);
1375 static int __init init_uni0299 (void)
1377 dprintk ("%s\n", __FUNCTION__);
1378 return dvb_register_i2c_device (NULL, uni0299_attach, uni0299_detach);
1382 static void __exit exit_uni0299 (void)
1384 dprintk ("%s\n", __FUNCTION__);
1386 dvb_unregister_i2c_device (uni0299_attach);
1389 module_init (init_uni0299);
1390 module_exit (exit_uni0299);
1392 MODULE_DESCRIPTION("Universal STV0299/TSA5059/SL1935 DVB Frontend driver");
1393 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey");
1394 MODULE_LICENSE("GPL");
1396 MODULE_PARM(stv0299_status, "i");
1397 MODULE_PARM_DESC(stv0299_status, "Which status value to support (0: BER, 1: UCBLOCKS)");
1399 MODULE_PARM(disable_typhoon, "i");
1400 MODULE_PARM_DESC(disable_typhoon, "Disable support for Philips SU1278 on Typhoon hardware.");