aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorTodd Poynor <tpoynor@mvista.com>2005-07-11 22:34:39 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-07-12 18:58:44 -0400
commita98a5d04f400ad112e59cadd739dbabf89417e60 (patch)
tree5eeb7f45c0090de40c7523e2b9dfd5e86b22169e /drivers/media/dvb/frontends
parent751382dd5cb2702368d281a50b55c2d6c4e8fbfc (diff)
parent7ac3db59fd4410405ce55e2a25c397aec440d8da (diff)
Merge with rsync://fileserver/linux
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Kconfig13
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/cx22702.c29
-rw-r--r--drivers/media/dvb/frontends/cx22702.h5
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c85
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h6
-rw-r--r--drivers/media/dvb/frontends/l64781.c9
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.c611
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.h49
-rw-r--r--drivers/media/dvb/frontends/lgdt3302_priv.h72
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c800
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h41
-rw-r--r--drivers/media/dvb/frontends/stv0297.c8
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c235
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h31
-rw-r--r--drivers/media/dvb/frontends/tda80xx.c1
16 files changed, 1874 insertions, 123 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b4fddf513ebe..d847c62bd837 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -40,6 +40,12 @@ config DVB_VES1X93
40 help 40 help
41 A DVB-S tuner module. Say Y when you want to support this frontend. 41 A DVB-S tuner module. Say Y when you want to support this frontend.
42 42
43config DVB_S5H1420
44 tristate "Samsung S5H1420 based"
45 depends on DVB_CORE
46 help
47 A DVB-S tuner module. Say Y when you want to support this frontend.
48
43comment "DVB-T (terrestrial) frontends" 49comment "DVB-T (terrestrial) frontends"
44 depends on DVB_CORE 50 depends on DVB_CORE
45 51
@@ -181,4 +187,11 @@ config DVB_BCM3510
181 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to 187 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
182 support this frontend. 188 support this frontend.
183 189
190config DVB_LGDT3302
191 tristate "LGDT3302 based (DViCO FusionHDTV3 Gold)"
192 depends on DVB_CORE
193 help
194 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
195 to support this frontend.
196
184endmenu 197endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 91d6d3576d3d..de5e240cba7f 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -29,3 +29,5 @@ obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o 29obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o 30obj-$(CONFIG_DVB_OR51132) += or51132.o
31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
32obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
33obj-$(CONFIG_DVB_LGDT3302) += lgdt3302.o
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index f4aa44136c7c..9f639297a9f2 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -76,7 +76,6 @@ static u8 init_tab [] = {
76 0x49, 0x56, 76 0x49, 0x56,
77 0x6b, 0x1e, 77 0x6b, 0x1e,
78 0xc8, 0x02, 78 0xc8, 0x02,
79 0xf8, 0x02,
80 0xf9, 0x00, 79 0xf9, 0x00,
81 0xfa, 0x00, 80 0xfa, 0x00,
82 0xfb, 0x00, 81 0xfb, 0x00,
@@ -203,7 +202,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
203 struct cx22702_state* state = fe->demodulator_priv; 202 struct cx22702_state* state = fe->demodulator_priv;
204 203
205 /* set PLL */ 204 /* set PLL */
206 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); 205 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
207 if (state->config->pll_set) { 206 if (state->config->pll_set) {
208 state->config->pll_set(fe, p); 207 state->config->pll_set(fe, p);
209 } else if (state->config->pll_desc) { 208 } else if (state->config->pll_desc) {
@@ -217,7 +216,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
217 } else { 216 } else {
218 BUG(); 217 BUG();
219 } 218 }
220 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); 219 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
221 220
222 /* set inversion */ 221 /* set inversion */
223 cx22702_set_inversion (state, p->inversion); 222 cx22702_set_inversion (state, p->inversion);
@@ -256,7 +255,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
256 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc ); 255 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
257 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); 256 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
258 cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ 257 cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
259 printk("%s: Autodetecting\n",__FUNCTION__); 258 dprintk("%s: Autodetecting\n",__FUNCTION__);
260 return 0; 259 return 0;
261 } 260 }
262 261
@@ -347,10 +346,11 @@ static int cx22702_init (struct dvb_frontend* fe)
347 for (i=0; i<sizeof(init_tab); i+=2) 346 for (i=0; i<sizeof(init_tab); i+=2)
348 cx22702_writereg (state, init_tab[i], init_tab[i+1]); 347 cx22702_writereg (state, init_tab[i], init_tab[i+1]);
349 348
349 cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
350 350
351 /* init PLL */ 351 /* init PLL */
352 if (state->config->pll_init) { 352 if (state->config->pll_init) {
353 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); 353 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
354 state->config->pll_init(fe); 354 state->config->pll_init(fe);
355 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); 355 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
356 } 356 }
@@ -440,8 +440,10 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
440 440
441 /* RS Uncorrectable Packet Count then reset */ 441 /* RS Uncorrectable Packet Count then reset */
442 _ucblocks = cx22702_readreg (state, 0xE3); 442 _ucblocks = cx22702_readreg (state, 0xE3);
443 if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks); 443 if (state->prevUCBlocks < _ucblocks)
444 else *ucblocks = state->prevUCBlocks - _ucblocks; 444 *ucblocks = (_ucblocks - state->prevUCBlocks);
445 else
446 *ucblocks = state->prevUCBlocks - _ucblocks;
445 state->prevUCBlocks = _ucblocks; 447 state->prevUCBlocks = _ucblocks;
446 448
447 return 0; 449 return 0;
@@ -457,6 +459,12 @@ static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
457 return cx22702_get_tps (state, &p->u.ofdm); 459 return cx22702_get_tps (state, &p->u.ofdm);
458} 460}
459 461
462static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
463{
464 tune->min_delay_ms = 1000;
465 return 0;
466}
467
460static void cx22702_release(struct dvb_frontend* fe) 468static void cx22702_release(struct dvb_frontend* fe)
461{ 469{
462 struct cx22702_state* state = fe->demodulator_priv; 470 struct cx22702_state* state = fe->demodulator_priv;
@@ -472,7 +480,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
472 480
473 /* allocate memory for the internal state */ 481 /* allocate memory for the internal state */
474 state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); 482 state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
475 if (state == NULL) goto error; 483 if (state == NULL)
484 goto error;
476 485
477 /* setup the state */ 486 /* setup the state */
478 state->config = config; 487 state->config = config;
@@ -481,7 +490,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
481 state->prevUCBlocks = 0; 490 state->prevUCBlocks = 0;
482 491
483 /* check if the demod is there */ 492 /* check if the demod is there */
484 if (cx22702_readreg(state, 0x1f) != 0x3) goto error; 493 if (cx22702_readreg(state, 0x1f) != 0x3)
494 goto error;
485 495
486 /* create dvb_frontend */ 496 /* create dvb_frontend */
487 state->frontend.ops = &state->ops; 497 state->frontend.ops = &state->ops;
@@ -514,6 +524,7 @@ static struct dvb_frontend_ops cx22702_ops = {
514 524
515 .set_frontend = cx22702_set_tps, 525 .set_frontend = cx22702_set_tps,
516 .get_frontend = cx22702_get_frontend, 526 .get_frontend = cx22702_get_frontend,
527 .get_tune_settings = cx22702_get_tune_settings,
517 528
518 .read_status = cx22702_read_status, 529 .read_status = cx22702_read_status,
519 .read_ber = cx22702_read_ber, 530 .read_ber = cx22702_read_ber,
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 559fdb906669..11f86806756e 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -35,6 +35,11 @@ struct cx22702_config
35 /* the demodulator's i2c address */ 35 /* the demodulator's i2c address */
36 u8 demod_address; 36 u8 demod_address;
37 37
38 /* serial/parallel output */
39#define CX22702_PARALLEL_OUTPUT 0
40#define CX22702_SERIAL_OUTPUT 1
41 u8 output_mode;
42
38 /* PLL maintenance */ 43 /* PLL maintenance */
39 u8 pll_address; 44 u8 pll_address;
40 struct dvb_pll_desc *pll_desc; 45 struct dvb_pll_desc *pll_desc;
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index f73b5f48e235..5afeaa9b43b4 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -55,7 +55,7 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
55}; 55};
56EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); 56EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
57 57
58static void thomson_dtt759x_bw(u8 *buf, int bandwidth) 58static void thomson_dtt759x_bw(u8 *buf, u32 freq, int bandwidth)
59{ 59{
60 if (BANDWIDTH_7_MHZ == bandwidth) 60 if (BANDWIDTH_7_MHZ == bandwidth)
61 buf[3] |= 0x10; 61 buf[3] |= 0x10;
@@ -93,6 +93,32 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
93}; 93};
94EXPORT_SYMBOL(dvb_pll_lg_z201); 94EXPORT_SYMBOL(dvb_pll_lg_z201);
95 95
96struct dvb_pll_desc dvb_pll_microtune_4042 = {
97 .name = "Microtune 4042 FI5",
98 .min = 57000000,
99 .max = 858000000,
100 .count = 3,
101 .entries = {
102 { 162000000, 44000000, 62500, 0x8e, 0xa1 },
103 { 457000000, 44000000, 62500, 0x8e, 0x91 },
104 { 999999999, 44000000, 62500, 0x8e, 0x31 },
105 },
106};
107EXPORT_SYMBOL(dvb_pll_microtune_4042);
108
109struct dvb_pll_desc dvb_pll_thomson_dtt7611 = {
110 .name = "Thomson dtt7611",
111 .min = 44000000,
112 .max = 958000000,
113 .count = 3,
114 .entries = {
115 { 157250000, 44000000, 62500, 0x8e, 0x39 },
116 { 454000000, 44000000, 62500, 0x8e, 0x3a },
117 { 999999999, 44000000, 62500, 0x8e, 0x3c },
118 },
119};
120EXPORT_SYMBOL(dvb_pll_thomson_dtt7611);
121
96struct dvb_pll_desc dvb_pll_unknown_1 = { 122struct dvb_pll_desc dvb_pll_unknown_1 = {
97 .name = "unknown 1", /* used by dntv live dvb-t */ 123 .name = "unknown 1", /* used by dntv live dvb-t */
98 .min = 174000000, 124 .min = 174000000,
@@ -146,7 +172,7 @@ EXPORT_SYMBOL(dvb_pll_env57h1xd5);
146/* Philips TDA6650/TDA6651 172/* Philips TDA6650/TDA6651
147 * used in Panasonic ENV77H11D5 173 * used in Panasonic ENV77H11D5
148 */ 174 */
149static void tda665x_bw(u8 *buf, int bandwidth) 175static void tda665x_bw(u8 *buf, u32 freq, int bandwidth)
150{ 176{
151 if (bandwidth == BANDWIDTH_8_MHZ) 177 if (bandwidth == BANDWIDTH_8_MHZ)
152 buf[3] |= 0x08; 178 buf[3] |= 0x08;
@@ -178,7 +204,7 @@ EXPORT_SYMBOL(dvb_pll_tda665x);
178/* Infineon TUA6034 204/* Infineon TUA6034
179 * used in LG TDTP E102P 205 * used in LG TDTP E102P
180 */ 206 */
181static void tua6034_bw(u8 *buf, int bandwidth) 207static void tua6034_bw(u8 *buf, u32 freq, int bandwidth)
182{ 208{
183 if (BANDWIDTH_7_MHZ != bandwidth) 209 if (BANDWIDTH_7_MHZ != bandwidth)
184 buf[3] |= 0x08; 210 buf[3] |= 0x08;
@@ -198,6 +224,57 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
198}; 224};
199EXPORT_SYMBOL(dvb_pll_tua6034); 225EXPORT_SYMBOL(dvb_pll_tua6034);
200 226
227/* Philips FMD1216ME
228 * used in Medion Hybrid PCMCIA card and USB Box
229 */
230static void fmd1216me_bw(u8 *buf, u32 freq, int bandwidth)
231{
232 if (bandwidth == BANDWIDTH_8_MHZ && freq >= 158870000)
233 buf[3] |= 0x08;
234}
235
236struct dvb_pll_desc dvb_pll_fmd1216me = {
237 .name = "Philips FMD1216ME",
238 .min = 50870000,
239 .max = 858000000,
240 .setbw = fmd1216me_bw,
241 .count = 7,
242 .entries = {
243 { 143870000, 36213333, 166667, 0xbc, 0x41 },
244 { 158870000, 36213333, 166667, 0xf4, 0x41 },
245 { 329870000, 36213333, 166667, 0xbc, 0x42 },
246 { 441870000, 36213333, 166667, 0xf4, 0x42 },
247 { 625870000, 36213333, 166667, 0xbc, 0x44 },
248 { 803870000, 36213333, 166667, 0xf4, 0x44 },
249 { 999999999, 36213333, 166667, 0xfc, 0x44 },
250 }
251};
252EXPORT_SYMBOL(dvb_pll_fmd1216me);
253
254/* ALPS TDED4
255 * used in Nebula-Cards and USB boxes
256 */
257static void tded4_bw(u8 *buf, u32 freq, int bandwidth)
258{
259 if (bandwidth == BANDWIDTH_8_MHZ)
260 buf[3] |= 0x04;
261}
262
263struct dvb_pll_desc dvb_pll_tded4 = {
264 .name = "ALPS TDED4",
265 .min = 47000000,
266 .max = 863000000,
267 .setbw = tded4_bw,
268 .count = 4,
269 .entries = {
270 { 153000000, 36166667, 166667, 0x85, 0x01 },
271 { 470000000, 36166667, 166667, 0x85, 0x02 },
272 { 823000000, 36166667, 166667, 0x85, 0x08 },
273 { 999999999, 36166667, 166667, 0x85, 0x88 },
274 }
275};
276EXPORT_SYMBOL(dvb_pll_tded4);
277
201/* ----------------------------------------------------------- */ 278/* ----------------------------------------------------------- */
202/* code */ 279/* code */
203 280
@@ -231,7 +308,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
231 buf[3] = desc->entries[i].cb2; 308 buf[3] = desc->entries[i].cb2;
232 309
233 if (desc->setbw) 310 if (desc->setbw)
234 desc->setbw(buf, bandwidth); 311 desc->setbw(buf, freq, bandwidth);
235 312
236 if (debug) 313 if (debug)
237 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", 314 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index b796778624b6..cb794759d89e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -9,7 +9,7 @@ struct dvb_pll_desc {
9 char *name; 9 char *name;
10 u32 min; 10 u32 min;
11 u32 max; 11 u32 max;
12 void (*setbw)(u8 *buf, int bandwidth); 12 void (*setbw)(u8 *buf, u32 freq, int bandwidth);
13 int count; 13 int count;
14 struct { 14 struct {
15 u32 limit; 15 u32 limit;
@@ -24,12 +24,16 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
24extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; 24extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
25extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; 25extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
26extern struct dvb_pll_desc dvb_pll_lg_z201; 26extern struct dvb_pll_desc dvb_pll_lg_z201;
27extern struct dvb_pll_desc dvb_pll_microtune_4042;
28extern struct dvb_pll_desc dvb_pll_thomson_dtt7611;
27extern struct dvb_pll_desc dvb_pll_unknown_1; 29extern struct dvb_pll_desc dvb_pll_unknown_1;
28 30
29extern struct dvb_pll_desc dvb_pll_tua6010xs; 31extern struct dvb_pll_desc dvb_pll_tua6010xs;
30extern struct dvb_pll_desc dvb_pll_env57h1xd5; 32extern struct dvb_pll_desc dvb_pll_env57h1xd5;
31extern struct dvb_pll_desc dvb_pll_tua6034; 33extern struct dvb_pll_desc dvb_pll_tua6034;
32extern struct dvb_pll_desc dvb_pll_tda665x; 34extern struct dvb_pll_desc dvb_pll_tda665x;
35extern struct dvb_pll_desc dvb_pll_fmd1216me;
36extern struct dvb_pll_desc dvb_pll_tded4;
33 37
34int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 38int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
35 u32 freq, int bandwidth); 39 u32 freq, int bandwidth);
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index 031a1ddc7d11..faaad1ae8559 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -474,11 +474,12 @@ static int l64781_init(struct dvb_frontend* fe)
474 return 0; 474 return 0;
475} 475}
476 476
477static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 477static int l64781_get_tune_settings(struct dvb_frontend* fe,
478 struct dvb_frontend_tune_settings* fesettings)
478{ 479{
479 fesettings->min_delay_ms = 200; 480 fesettings->min_delay_ms = 4000;
480 fesettings->step_size = 166667; 481 fesettings->step_size = 0;
481 fesettings->max_drift = 166667*2; 482 fesettings->max_drift = 0;
482 return 0; 483 return 0;
483} 484}
484 485
diff --git a/drivers/media/dvb/frontends/lgdt3302.c b/drivers/media/dvb/frontends/lgdt3302.c
new file mode 100644
index 000000000000..09c914256e49
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302.c
@@ -0,0 +1,611 @@
1/*
2 * $Id: lgdt3302.c,v 1.5 2005/07/07 03:47:15 mkrufky Exp $
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
7 *
8 * Based on code from Kirk Lapray <kirk_lapray@bigfoot.com>
9 * Copyright (C) 2005
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26
27/*
28 * NOTES ABOUT THIS DRIVER
29 *
30 * This driver supports DViCO FusionHDTV 3 Gold under Linux.
31 *
32 * TODO:
33 * BER and signal strength always return 0.
34 *
35 */
36
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/moduleparam.h>
40#include <linux/init.h>
41#include <linux/delay.h>
42#include <asm/byteorder.h>
43
44#include "dvb_frontend.h"
45#include "dvb-pll.h"
46#include "lgdt3302_priv.h"
47#include "lgdt3302.h"
48
49static int debug = 0;
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug,"Turn on/off lgdt3302 frontend debugging (default:off).");
52#define dprintk(args...) \
53do { \
54if (debug) printk(KERN_DEBUG "lgdt3302: " args); \
55} while (0)
56
57struct lgdt3302_state
58{
59 struct i2c_adapter* i2c;
60 struct dvb_frontend_ops ops;
61
62 /* Configuration settings */
63 const struct lgdt3302_config* config;
64
65 struct dvb_frontend frontend;
66
67 /* Demodulator private data */
68 fe_modulation_t current_modulation;
69
70 /* Tuner private data */
71 u32 current_frequency;
72};
73
74static int i2c_writebytes (struct lgdt3302_state* state,
75 u8 addr, /* demod_address or pll_address */
76 u8 *buf, /* data bytes to send */
77 int len /* number of bytes to send */ )
78{
79 if (addr == state->config->pll_address) {
80 struct i2c_msg msg =
81 { .addr = addr, .flags = 0, .buf = buf, .len = len };
82 int err;
83
84 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
85 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
86 return -EREMOTEIO;
87 }
88 } else {
89 u8 tmp[] = { buf[0], buf[1] };
90 struct i2c_msg msg =
91 { .addr = addr, .flags = 0, .buf = tmp, .len = 2 };
92 int err;
93 int i;
94
95 for (i=1; i<len; i++) {
96 tmp[1] = buf[i];
97 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
98 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
99 return -EREMOTEIO;
100 }
101 tmp[0]++;
102 }
103 }
104 return 0;
105}
106static int i2c_readbytes (struct lgdt3302_state* state,
107 u8 addr, /* demod_address or pll_address */
108 u8 *buf, /* holds data bytes read */
109 int len /* number of bytes to read */ )
110{
111 struct i2c_msg msg =
112 { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
113 int err;
114
115 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
116 printk(KERN_WARNING "lgdt3302: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err);
117 return -EREMOTEIO;
118 }
119 return 0;
120}
121
122/*
123 * This routine writes the register (reg) to the demod bus
124 * then reads the data returned for (len) bytes.
125 */
126
127static u8 i2c_selectreadbytes (struct lgdt3302_state* state,
128 enum I2C_REG reg, u8* buf, int len)
129{
130 u8 wr [] = { reg };
131 struct i2c_msg msg [] = {
132 { .addr = state->config->demod_address,
133 .flags = 0, .buf = wr, .len = 1 },
134 { .addr = state->config->demod_address,
135 .flags = I2C_M_RD, .buf = buf, .len = len },
136 };
137 int ret;
138 ret = i2c_transfer(state->i2c, msg, 2);
139 if (ret != 2) {
140 printk(KERN_WARNING "lgdt3302: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
141 } else {
142 ret = 0;
143 }
144 return ret;
145}
146
147/* Software reset */
148int lgdt3302_SwReset(struct lgdt3302_state* state)
149{
150 u8 ret;
151 u8 reset[] = {
152 IRQ_MASK,
153 0x00 /* bit 6 is active low software reset
154 * bits 5-0 are 1 to mask interrupts */
155 };
156
157 ret = i2c_writebytes(state,
158 state->config->demod_address,
159 reset, sizeof(reset));
160 if (ret == 0) {
161 /* spec says reset takes 100 ns why wait */
162 /* mdelay(100); */ /* keep low for 100mS */
163 reset[1] = 0x7f; /* force reset high (inactive)
164 * and unmask interrupts */
165 ret = i2c_writebytes(state,
166 state->config->demod_address,
167 reset, sizeof(reset));
168 }
169 /* Spec does not indicate a need for this either */
170 /*mdelay(5); */ /* wait 5 msec before doing more */
171 return ret;
172}
173
174static int lgdt3302_init(struct dvb_frontend* fe)
175{
176 /* Hardware reset is done using gpio[0] of cx23880x chip.
177 * I'd like to do it here, but don't know how to find chip address.
178 * cx88-cards.c arranges for the reset bit to be inactive (high).
179 * Maybe there needs to be a callable function in cx88-core or
180 * the caller of this function needs to do it. */
181
182 dprintk("%s entered\n", __FUNCTION__);
183 return lgdt3302_SwReset((struct lgdt3302_state*) fe->demodulator_priv);
184}
185
186static int lgdt3302_read_ber(struct dvb_frontend* fe, u32* ber)
187{
188 *ber = 0; /* Dummy out for now */
189 return 0;
190}
191
192static int lgdt3302_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
193{
194 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
195 u8 buf[2];
196
197 i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf));
198
199 *ucblocks = (buf[0] << 8) | buf[1];
200 return 0;
201}
202
203static int lgdt3302_set_parameters(struct dvb_frontend* fe,
204 struct dvb_frontend_parameters *param)
205{
206 u8 buf[4];
207 struct lgdt3302_state* state =
208 (struct lgdt3302_state*) fe->demodulator_priv;
209
210 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
211 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
212 static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 };
213 static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
214 static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
215 static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
216 static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x00, 0x00, 0x00 };
217 static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
218
219 /* Change only if we are actually changing the modulation */
220 if (state->current_modulation != param->u.vsb.modulation) {
221 switch(param->u.vsb.modulation) {
222 case VSB_8:
223 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
224
225 /* Select VSB mode and serial MPEG interface */
226 top_ctrl_cfg[1] = 0x07;
227 break;
228
229 case QAM_64:
230 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
231
232 /* Select QAM_64 mode and serial MPEG interface */
233 top_ctrl_cfg[1] = 0x04;
234 break;
235
236 case QAM_256:
237 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
238
239 /* Select QAM_256 mode and serial MPEG interface */
240 top_ctrl_cfg[1] = 0x05;
241 break;
242 default:
243 printk(KERN_WARNING "lgdt3302: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
244 return -1;
245 }
246 /* Initializations common to all modes */
247
248 /* Select the requested mode */
249 i2c_writebytes(state, state->config->demod_address,
250 top_ctrl_cfg, sizeof(top_ctrl_cfg));
251
252 /* Change the value of IFBW[11:0]
253 of AGC IF/RF loop filter bandwidth register */
254 i2c_writebytes(state, state->config->demod_address,
255 agc_rf_cfg, sizeof(agc_rf_cfg));
256
257 /* Change the value of bit 6, 'nINAGCBY' and
258 'NSSEL[1:0] of ACG function control register 2 */
259 /* Change the value of bit 6 'RFFIX'
260 of AGC function control register 3 */
261 i2c_writebytes(state, state->config->demod_address,
262 agc_ctrl_cfg, sizeof(agc_ctrl_cfg));
263
264 /* Change the TPCLK pin polarity
265 data is valid on falling clock */
266 i2c_writebytes(state, state->config->demod_address,
267 demux_ctrl_cfg, sizeof(demux_ctrl_cfg));
268
269 if (param->u.vsb.modulation == VSB_8) {
270 /* Initialization for VSB modes only */
271 /* Change the value of NCOCTFV[25:0]of carrier
272 recovery center frequency register for VSB */
273 i2c_writebytes(state, state->config->demod_address,
274 vsb_freq_cfg, sizeof(vsb_freq_cfg));
275 } else {
276 /* Initialization for QAM modes only */
277 /* Set the value of 'INLVTHD' register 0x2a/0x2c
278 to value from 'IFACC' register 0x39/0x3b -1 */
279 int value;
280 i2c_selectreadbytes(state, AGC_RFIF_ACC0,
281 &agc_delay_cfg[1], 3);
282 value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];
283 value = value -1;
284 dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);
285 agc_delay_cfg[1] = (value >> 8) & 0x0f;
286 agc_delay_cfg[2] = 0x00;
287 agc_delay_cfg[3] = value & 0xff;
288 i2c_writebytes(state, state->config->demod_address,
289 agc_delay_cfg, sizeof(agc_delay_cfg));
290
291 /* Change the value of IAGCBW[15:8]
292 of inner AGC loop filter bandwith */
293 i2c_writebytes(state, state->config->demod_address,
294 agc_loop_cfg, sizeof(agc_loop_cfg));
295 }
296
297 state->config->set_ts_params(fe, 0);
298 lgdt3302_SwReset(state);
299 state->current_modulation = param->u.vsb.modulation;
300 }
301
302 /* Change only if we are actually changing the channel */
303 if (state->current_frequency != param->frequency) {
304 dvb_pll_configure(state->config->pll_desc, buf,
305 param->frequency, 0);
306 dprintk("%s: tuner bytes: 0x%02x 0x%02x "
307 "0x%02x 0x%02x\n", __FUNCTION__, buf[0],buf[1],buf[2],buf[3]);
308 i2c_writebytes(state, state->config->pll_address ,buf, 4);
309
310 /* Check the status of the tuner pll */
311 i2c_readbytes(state, state->config->pll_address, buf, 1);
312 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
313
314 lgdt3302_SwReset(state);
315
316 /* Update current frequency */
317 state->current_frequency = param->frequency;
318 }
319 return 0;
320}
321
322static int lgdt3302_get_frontend(struct dvb_frontend* fe,
323 struct dvb_frontend_parameters* param)
324{
325 struct lgdt3302_state *state = fe->demodulator_priv;
326 param->frequency = state->current_frequency;
327 return 0;
328}
329
330static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
331{
332 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
333 u8 buf[3];
334
335 *status = 0; /* Reset status result */
336
337 /* Check the status of the tuner pll */
338 i2c_readbytes(state, state->config->pll_address, buf, 1);
339 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
340 if ((buf[0] & 0xc0) != 0x40)
341 return 0; /* Tuner PLL not locked or not powered on */
342
343 /*
344 * You must set the Mask bits to 1 in the IRQ_MASK in order
345 * to see that status bit in the IRQ_STATUS register.
346 * This is done in SwReset();
347 */
348
349 /* AGC status register */
350 i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
351 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
352 if ((buf[0] & 0x0c) == 0x8){
353 /* Test signal does not exist flag */
354 /* as well as the AGC lock flag. */
355 *status |= FE_HAS_SIGNAL;
356 } else {
357 /* Without a signal all other status bits are meaningless */
358 return 0;
359 }
360
361 /* signal status */
362 i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
363 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
364
365#if 0
366 /* Alternative method to check for a signal */
367 /* using the SNR good/bad interrupts. */
368 if ((buf[2] & 0x30) == 0x10)
369 *status |= FE_HAS_SIGNAL;
370#endif
371
372 /* sync status */
373 if ((buf[2] & 0x03) == 0x01) {
374 *status |= FE_HAS_SYNC;
375 }
376
377 /* FEC error status */
378 if ((buf[2] & 0x0c) == 0x08) {
379 *status |= FE_HAS_LOCK;
380 *status |= FE_HAS_VITERBI;
381 }
382
383 /* Carrier Recovery Lock Status Register */
384 i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
385 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
386 switch (state->current_modulation) {
387 case QAM_256:
388 case QAM_64:
389 /* Need to undestand why there are 3 lock levels here */
390 if ((buf[0] & 0x07) == 0x07)
391 *status |= FE_HAS_CARRIER;
392 break;
393 case VSB_8:
394 if ((buf[0] & 0x80) == 0x80)
395 *status |= FE_HAS_CARRIER;
396 break;
397 default:
398 printk("KERN_WARNING lgdt3302: %s: Modulation set to unsupported value\n", __FUNCTION__);
399 }
400
401 return 0;
402}
403
404static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
405{
406 /* not directly available. */
407 return 0;
408}
409
410static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
411{
412#ifdef SNR_IN_DB
413 /*
414 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
415 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
416 * respectively. The following tables are built on these formulas.
417 * The usual definition is SNR = 20 log10(signal/noise)
418 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
419 *
420 * This table is a an ordered list of noise values computed by the
421 * formula from the spec sheet such that the index into the table
422 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
423 * value entries at the beginning because the SNR varies more than
424 * 1 db for a change of 1 digit in noise at very small values of noise.
425 *
426 * Examples from SNR_EQ table:
427 * noise SNR
428 * 0 43
429 * 1 42
430 * 2 39
431 * 3 37
432 * 4 36
433 * 5 35
434 * 6 34
435 * 7 33
436 * 8 33
437 * 9 32
438 * 10 32
439 * 11 31
440 * 12 31
441 * 13 30
442 */
443
444 static const u32 SNR_EQ[] =
445 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
446 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
447 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
448 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
449 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
450 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
451 };
452
453 static const u32 SNR_PH[] =
454 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
455 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
456 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
457 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
458 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
459 90833, 114351, 143960, 181235, 228161, 0x040000
460 };
461
462 static u8 buf[5];/* read data buffer */
463 static u32 noise; /* noise value */
464 static u32 snr_db; /* index into SNR_EQ[] */
465 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
466
467 /* read both equalizer and pase tracker noise data */
468 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
469
470 if (state->current_modulation == VSB_8) {
471 /* Equalizer Mean-Square Error Register for VSB */
472 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
473
474 /*
475 * Look up noise value in table.
476 * A better search algorithm could be used...
477 * watch out there are duplicate entries.
478 */
479 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
480 if (noise < SNR_EQ[snr_db]) {
481 *snr = 43 - snr_db;
482 break;
483 }
484 }
485 } else {
486 /* Phase Tracker Mean-Square Error Register for QAM */
487 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
488
489 /* Look up noise value in table. */
490 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
491 if (noise < SNR_PH[snr_db]) {
492 *snr = 45 - snr_db;
493 break;
494 }
495 }
496 }
497#else
498 /* Return the raw noise value */
499 static u8 buf[5];/* read data buffer */
500 static u32 noise; /* noise value */
501 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
502
503 /* read both equalizer and pase tracker noise data */
504 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
505
506 if (state->current_modulation == VSB_8) {
507 /* Equalizer Mean-Square Error Register for VSB */
508 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
509 } else {
510 /* Phase Tracker Mean-Square Error Register for QAM */
511 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
512 }
513
514 /* Small values for noise mean signal is better so invert noise */
515 /* Noise is 19 bit value so discard 3 LSB*/
516 *snr = ~noise>>3;
517#endif
518
519 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
520
521 return 0;
522}
523
524static int lgdt3302_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
525{
526 /* I have no idea about this - it may not be needed */
527 fe_tune_settings->min_delay_ms = 500;
528 fe_tune_settings->step_size = 0;
529 fe_tune_settings->max_drift = 0;
530 return 0;
531}
532
533static void lgdt3302_release(struct dvb_frontend* fe)
534{
535 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
536 kfree(state);
537}
538
539static struct dvb_frontend_ops lgdt3302_ops;
540
541struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
542 struct i2c_adapter* i2c)
543{
544 struct lgdt3302_state* state = NULL;
545 u8 buf[1];
546
547 /* Allocate memory for the internal state */
548 state = (struct lgdt3302_state*) kmalloc(sizeof(struct lgdt3302_state), GFP_KERNEL);
549 if (state == NULL)
550 goto error;
551 memset(state,0,sizeof(*state));
552
553 /* Setup the state */
554 state->config = config;
555 state->i2c = i2c;
556 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
557 /* Verify communication with demod chip */
558 if (i2c_selectreadbytes(state, 2, buf, 1))
559 goto error;
560
561 state->current_frequency = -1;
562 state->current_modulation = -1;
563
564 /* Create dvb_frontend */
565 state->frontend.ops = &state->ops;
566 state->frontend.demodulator_priv = state;
567 return &state->frontend;
568
569error:
570 if (state)
571 kfree(state);
572 dprintk("%s: ERROR\n",__FUNCTION__);
573 return NULL;
574}
575
576static struct dvb_frontend_ops lgdt3302_ops = {
577 .info = {
578 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
579 .type = FE_ATSC,
580 .frequency_min= 54000000,
581 .frequency_max= 858000000,
582 .frequency_stepsize= 62500,
583 /* Symbol rate is for all VSB modes need to check QAM */
584 .symbol_rate_min = 10762000,
585 .symbol_rate_max = 10762000,
586 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
587 },
588 .init = lgdt3302_init,
589 .set_frontend = lgdt3302_set_parameters,
590 .get_frontend = lgdt3302_get_frontend,
591 .get_tune_settings = lgdt3302_get_tune_settings,
592 .read_status = lgdt3302_read_status,
593 .read_ber = lgdt3302_read_ber,
594 .read_signal_strength = lgdt3302_read_signal_strength,
595 .read_snr = lgdt3302_read_snr,
596 .read_ucblocks = lgdt3302_read_ucblocks,
597 .release = lgdt3302_release,
598};
599
600MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
601MODULE_AUTHOR("Wilson Michaels");
602MODULE_LICENSE("GPL");
603
604EXPORT_SYMBOL(lgdt3302_attach);
605
606/*
607 * Local variables:
608 * c-basic-offset: 8
609 * compile-command: "make DVB=1"
610 * End:
611 */
diff --git a/drivers/media/dvb/frontends/lgdt3302.h b/drivers/media/dvb/frontends/lgdt3302.h
new file mode 100644
index 000000000000..81587a40032b
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302.h
@@ -0,0 +1,49 @@
1/*
2 * $Id: lgdt3302.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
7 *
8 * 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
24#ifndef LGDT3302_H
25#define LGDT3302_H
26
27#include <linux/dvb/frontend.h>
28
29struct lgdt3302_config
30{
31 /* The demodulator's i2c address */
32 u8 demod_address;
33 u8 pll_address;
34 struct dvb_pll_desc *pll_desc;
35
36 /* Need to set device param for start_dma */
37 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
38};
39
40extern struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
41 struct i2c_adapter* i2c);
42
43#endif /* LGDT3302_H */
44
45/*
46 * Local variables:
47 * c-basic-offset: 8
48 * End:
49 */
diff --git a/drivers/media/dvb/frontends/lgdt3302_priv.h b/drivers/media/dvb/frontends/lgdt3302_priv.h
new file mode 100644
index 000000000000..6193fa7a569d
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302_priv.h
@@ -0,0 +1,72 @@
1/*
2 * $Id: lgdt3302_priv.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
7 *
8 * 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
24#ifndef _LGDT3302_PRIV_
25#define _LGDT3302_PRIV_
26
27/* i2c control register addresses */
28enum I2C_REG {
29 TOP_CONTROL= 0x00,
30 IRQ_MASK= 0x01,
31 IRQ_STATUS= 0x02,
32 VSB_CARRIER_FREQ0= 0x16,
33 VSB_CARRIER_FREQ1= 0x17,
34 VSB_CARRIER_FREQ2= 0x18,
35 VSB_CARRIER_FREQ3= 0x19,
36 CARRIER_MSEQAM1= 0x1a,
37 CARRIER_MSEQAM2= 0x1b,
38 CARRIER_LOCK= 0x1c,
39 TIMING_RECOVERY= 0x1d,
40 AGC_DELAY0= 0x2a,
41 AGC_DELAY1= 0x2b,
42 AGC_DELAY2= 0x2c,
43 AGC_RF_BANDWIDTH0= 0x2d,
44 AGC_RF_BANDWIDTH1= 0x2e,
45 AGC_RF_BANDWIDTH2= 0x2f,
46 AGC_LOOP_BANDWIDTH0= 0x30,
47 AGC_LOOP_BANDWIDTH1= 0x31,
48 AGC_FUNC_CTRL1= 0x32,
49 AGC_FUNC_CTRL2= 0x33,
50 AGC_FUNC_CTRL3= 0x34,
51 AGC_RFIF_ACC0= 0x39,
52 AGC_RFIF_ACC1= 0x3a,
53 AGC_RFIF_ACC2= 0x3b,
54 AGC_STATUS= 0x3f,
55 SYNC_STATUS_VSB= 0x43,
56 EQPH_ERR0= 0x47,
57 EQ_ERR1= 0x48,
58 EQ_ERR2= 0x49,
59 PH_ERR1= 0x4a,
60 PH_ERR2= 0x4b,
61 DEMUX_CONTROL= 0x66,
62 PACKET_ERR_COUNTER1= 0x6a,
63 PACKET_ERR_COUNTER2= 0x6b,
64};
65
66#endif /* _LGDT3302_PRIV_ */
67
68/*
69 * Local variables:
70 * c-basic-offset: 8
71 * End:
72 */
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
new file mode 100644
index 000000000000..4f396ac8de77
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -0,0 +1,800 @@
1/*
2Driver for Samsung S5H1420 QPSK Demodulator
3
4Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <linux/delay.h>
29
30#include "dvb_frontend.h"
31#include "s5h1420.h"
32
33
34
35#define TONE_FREQ 22000
36
37struct s5h1420_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 const struct s5h1420_config* config;
41 struct dvb_frontend frontend;
42
43 u8 postlocked:1;
44 u32 fclk;
45 u32 tunedfreq;
46 fe_code_rate_t fec_inner;
47 u32 symbol_rate;
48};
49
50static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
51static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings);
52
53
54static int debug = 0;
55#define dprintk if (debug) printk
56
57static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
58{
59 u8 buf [] = { reg, data };
60 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
61 int err;
62
63 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
64 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
65 return -EREMOTEIO;
66 }
67
68 return 0;
69}
70
71static u8 s5h1420_readreg (struct s5h1420_state* state, u8 reg)
72{
73 int ret;
74 u8 b0 [] = { reg };
75 u8 b1 [] = { 0 };
76 struct i2c_msg msg1 = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 };
77 struct i2c_msg msg2 = { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 };
78
79 if ((ret = i2c_transfer (state->i2c, &msg1, 1)) != 1)
80 return ret;
81
82 if ((ret = i2c_transfer (state->i2c, &msg2, 1)) != 1)
83 return ret;
84
85 return b1[0];
86}
87
88static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
89{
90 struct s5h1420_state* state = fe->demodulator_priv;
91
92 switch(voltage) {
93 case SEC_VOLTAGE_13:
94 s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
95 break;
96
97 case SEC_VOLTAGE_18:
98 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
99 break;
100
101 case SEC_VOLTAGE_OFF:
102 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
103 break;
104 }
105
106 return 0;
107}
108
109static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
110{
111 struct s5h1420_state* state = fe->demodulator_priv;
112
113 switch(tone) {
114 case SEC_TONE_ON:
115 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
116 break;
117
118 case SEC_TONE_OFF:
119 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
120 break;
121 }
122
123 return 0;
124}
125
126static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
127{
128 struct s5h1420_state* state = fe->demodulator_priv;
129 u8 val;
130 int i;
131 unsigned long timeout;
132 int result = 0;
133
134 /* setup for DISEQC */
135 val = s5h1420_readreg(state, 0x3b);
136 s5h1420_writereg(state, 0x3b, 0x02);
137 msleep(15);
138
139 /* write the DISEQC command bytes */
140 for(i=0; i< cmd->msg_len; i++) {
141 s5h1420_writereg(state, 0x3c + i, cmd->msg[i]);
142 }
143
144 /* kick off transmission */
145 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08);
146
147 /* wait for transmission to complete */
148 timeout = jiffies + ((100*HZ) / 1000);
149 while(time_before(jiffies, timeout)) {
150 if (s5h1420_readreg(state, 0x3b) & 0x08)
151 break;
152
153 msleep(5);
154 }
155 if (time_after(jiffies, timeout))
156 result = -ETIMEDOUT;
157
158 /* restore original settings */
159 s5h1420_writereg(state, 0x3b, val);
160 msleep(15);
161 return result;
162}
163
164static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply)
165{
166 struct s5h1420_state* state = fe->demodulator_priv;
167 u8 val;
168 int i;
169 int length;
170 unsigned long timeout;
171 int result = 0;
172
173 /* setup for DISEQC recieve */
174 val = s5h1420_readreg(state, 0x3b);
175 s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */
176 msleep(15);
177
178 /* wait for reception to complete */
179 timeout = jiffies + ((reply->timeout*HZ) / 1000);
180 while(time_before(jiffies, timeout)) {
181 if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */
182 break;
183
184 msleep(5);
185 }
186 if (time_after(jiffies, timeout)) {
187 result = -ETIMEDOUT;
188 goto exit;
189 }
190
191 /* check error flag - FIXME: not sure what this does - docs do not describe
192 * beyond "error flag for diseqc receive data :( */
193 if (s5h1420_readreg(state, 0x49)) {
194 result = -EIO;
195 goto exit;
196 }
197
198 /* check length */
199 length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
200 if (length > sizeof(reply->msg)) {
201 result = -EOVERFLOW;
202 goto exit;
203 }
204 reply->msg_len = length;
205
206 /* extract data */
207 for(i=0; i< length; i++) {
208 reply->msg[i] = s5h1420_readreg(state, 0x3c + i);
209 }
210
211exit:
212 /* restore original settings */
213 s5h1420_writereg(state, 0x3b, val);
214 msleep(15);
215 return result;
216}
217
218static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
219{
220 struct s5h1420_state* state = fe->demodulator_priv;
221 u8 val;
222 int result = 0;
223 unsigned long timeout;
224
225 /* setup for tone burst */
226 val = s5h1420_readreg(state, 0x3b);
227 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
228
229 /* set value for B position if requested */
230 if (minicmd == SEC_MINI_B) {
231 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
232 }
233 msleep(15);
234
235 /* start transmission */
236 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
237
238 /* wait for transmission to complete */
239 timeout = jiffies + ((20*HZ) / 1000);
240 while(time_before(jiffies, timeout)) {
241 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
242 break;
243
244 msleep(5);
245 }
246 if (time_after(jiffies, timeout))
247 result = -ETIMEDOUT;
248
249 /* restore original settings */
250 s5h1420_writereg(state, 0x3b, val);
251 msleep(15);
252 return result;
253}
254
255static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
256{
257 u8 val;
258 fe_status_t status = 0;
259
260 val = s5h1420_readreg(state, 0x14);
261 if (val & 0x02)
262 status |= FE_HAS_SIGNAL; // FIXME: not sure if this is right
263 if (val & 0x01)
264 status |= FE_HAS_CARRIER; // FIXME: not sure if this is right
265 val = s5h1420_readreg(state, 0x36);
266 if (val & 0x01)
267 status |= FE_HAS_VITERBI;
268 if (val & 0x20)
269 status |= FE_HAS_SYNC;
270 if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC))
271 status |= FE_HAS_LOCK;
272
273 return status;
274}
275
276static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
277{
278 struct s5h1420_state* state = fe->demodulator_priv;
279 u8 val;
280
281 if (status == NULL)
282 return -EINVAL;
283
284 /* determine lock state */
285 *status = s5h1420_get_status_bits(state);
286
287 /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion,
288 wait a bit and check again */
289 if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
290 val = s5h1420_readreg(state, 0x32);
291 if ((val & 0x07) == 0x03) {
292 if (val & 0x08)
293 s5h1420_writereg(state, 0x31, 0x13);
294 else
295 s5h1420_writereg(state, 0x31, 0x1b);
296
297 /* wait a bit then update lock status */
298 mdelay(200);
299 *status = s5h1420_get_status_bits(state);
300 }
301 }
302
303 /* perform post lock setup */
304 if ((*status & FE_HAS_LOCK) && (!state->postlocked)) {
305
306 /* calculate the data rate */
307 u32 tmp = s5h1420_getsymbolrate(state);
308 switch(s5h1420_readreg(state, 0x32) & 0x07) {
309 case 0:
310 tmp = (tmp * 2 * 1) / 2;
311 break;
312
313 case 1:
314 tmp = (tmp * 2 * 2) / 3;
315 break;
316
317 case 2:
318 tmp = (tmp * 2 * 3) / 4;
319 break;
320
321 case 3:
322 tmp = (tmp * 2 * 5) / 6;
323 break;
324
325 case 4:
326 tmp = (tmp * 2 * 6) / 7;
327 break;
328
329 case 5:
330 tmp = (tmp * 2 * 7) / 8;
331 break;
332 }
333 tmp = state->fclk / tmp;
334
335 /* set the MPEG_CLK_INTL for the calculated data rate */
336 if (tmp < 4)
337 val = 0x00;
338 else if (tmp < 8)
339 val = 0x01;
340 else if (tmp < 12)
341 val = 0x02;
342 else if (tmp < 16)
343 val = 0x03;
344 else if (tmp < 24)
345 val = 0x04;
346 else if (tmp < 32)
347 val = 0x05;
348 else
349 val = 0x06;
350 s5h1420_writereg(state, 0x22, val);
351
352 /* DC freeze */
353 s5h1420_writereg(state, 0x1f, s5h1420_readreg(state, 0x1f) | 0x01);
354
355 /* kicker disable + remove DC offset */
356 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) & 0x6f);
357
358 /* post-lock processing has been done! */
359 state->postlocked = 1;
360 }
361
362 return 0;
363}
364
365static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
366{
367 struct s5h1420_state* state = fe->demodulator_priv;
368
369 s5h1420_writereg(state, 0x46, 0x1d);
370 mdelay(25);
371 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
372}
373
374static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
375{
376 struct s5h1420_state* state = fe->demodulator_priv;
377
378 u8 val = 0xff - s5h1420_readreg(state, 0x15);
379
380 return (int) ((val << 8) | val);
381}
382
383static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
384{
385 struct s5h1420_state* state = fe->demodulator_priv;
386
387 s5h1420_writereg(state, 0x46, 0x1f);
388 mdelay(25);
389 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
390}
391
392static void s5h1420_reset(struct s5h1420_state* state)
393{
394 s5h1420_writereg (state, 0x01, 0x08);
395 s5h1420_writereg (state, 0x01, 0x00);
396 udelay(10);
397}
398
399static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
400{
401 u64 val;
402
403 val = (p->u.qpsk.symbol_rate / 1000) * (1<<24);
404 if (p->u.qpsk.symbol_rate <= 21000000) {
405 val *= 2;
406 }
407 do_div(val, (state->fclk / 1000));
408
409 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0x7f);
410 s5h1420_writereg(state, 0x11, val >> 16);
411 s5h1420_writereg(state, 0x12, val >> 8);
412 s5h1420_writereg(state, 0x13, val & 0xff);
413 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x80);
414}
415
416static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
417{
418 u64 val;
419 int sampling = 2;
420
421 if (s5h1420_readreg(state, 0x05) & 0x2)
422 sampling = 1;
423
424 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
425 val = s5h1420_readreg(state, 0x11) << 16;
426 val |= s5h1420_readreg(state, 0x12) << 8;
427 val |= s5h1420_readreg(state, 0x13);
428 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
429
430 val *= (state->fclk / 1000);
431 do_div(val, ((1<<24) * sampling));
432
433 return (u32) (val * 1000);
434}
435
436static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
437{
438 int val;
439
440 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
441 * divide fclk by 1000000 to get the correct value. */
442 val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
443
444 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0xbf);
445 s5h1420_writereg(state, 0x0e, val >> 16);
446 s5h1420_writereg(state, 0x0f, val >> 8);
447 s5h1420_writereg(state, 0x10, val & 0xff);
448 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x40);
449}
450
451static int s5h1420_getfreqoffset(struct s5h1420_state* state)
452{
453 int val;
454
455 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
456 val = s5h1420_readreg(state, 0x0e) << 16;
457 val |= s5h1420_readreg(state, 0x0f) << 8;
458 val |= s5h1420_readreg(state, 0x10);
459 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
460
461 if (val & 0x800000)
462 val |= 0xff000000;
463
464 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
465 * divide fclk by 1000000 to get the correct value. */
466 val = - ((val * (state->fclk/1000000)) / (1<<24));
467
468 return val;
469}
470
471static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
472{
473 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
474 s5h1420_writereg(state, 0x31, 0x00);
475 s5h1420_writereg(state, 0x30, 0x3f);
476 } else {
477 switch(p->u.qpsk.fec_inner) {
478 case FEC_1_2:
479 s5h1420_writereg(state, 0x31, 0x10);
480 s5h1420_writereg(state, 0x30, 0x01);
481 break;
482
483 case FEC_2_3:
484 s5h1420_writereg(state, 0x31, 0x11);
485 s5h1420_writereg(state, 0x30, 0x02);
486 break;
487
488 case FEC_3_4:
489 s5h1420_writereg(state, 0x31, 0x12);
490 s5h1420_writereg(state, 0x30, 0x04);
491 break;
492
493 case FEC_5_6:
494 s5h1420_writereg(state, 0x31, 0x13);
495 s5h1420_writereg(state, 0x30, 0x08);
496 break;
497
498 case FEC_6_7:
499 s5h1420_writereg(state, 0x31, 0x14);
500 s5h1420_writereg(state, 0x30, 0x10);
501 break;
502
503 case FEC_7_8:
504 s5h1420_writereg(state, 0x31, 0x15);
505 s5h1420_writereg(state, 0x30, 0x20);
506 break;
507
508 default:
509 return;
510 }
511 }
512}
513
514static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
515{
516 switch(s5h1420_readreg(state, 0x32) & 0x07) {
517 case 0:
518 return FEC_1_2;
519
520 case 1:
521 return FEC_2_3;
522
523 case 2:
524 return FEC_3_4;
525
526 case 3:
527 return FEC_5_6;
528
529 case 4:
530 return FEC_6_7;
531
532 case 5:
533 return FEC_7_8;
534 }
535
536 return FEC_NONE;
537}
538
539static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
540{
541 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
542 s5h1420_writereg(state, 0x31, 0x00);
543 s5h1420_writereg(state, 0x30, 0x3f);
544 } else {
545 u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
546 tmp |= 0x10;
547
548 if (p->inversion == INVERSION_ON)
549 tmp |= 0x80;
550
551 s5h1420_writereg(state, 0x31, tmp);
552 }
553}
554
555static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
556{
557 if (s5h1420_readreg(state, 0x32) & 0x08)
558 return INVERSION_ON;
559
560 return INVERSION_OFF;
561}
562
563static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
564{
565 struct s5h1420_state* state = fe->demodulator_priv;
566 u32 frequency_delta;
567 struct dvb_frontend_tune_settings fesettings;
568
569 /* check if we should do a fast-tune */
570 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
571 s5h1420_get_tune_settings(fe, &fesettings);
572 frequency_delta = p->frequency - state->tunedfreq;
573 if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) &&
574 (frequency_delta != 0) &&
575 (state->fec_inner == p->u.qpsk.fec_inner) &&
576 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
577
578 s5h1420_setfreqoffset(state, frequency_delta);
579 return 0;
580 }
581
582 /* first of all, software reset */
583 s5h1420_reset(state);
584
585 /* set tuner PLL */
586 if (state->config->pll_set) {
587 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
588 state->config->pll_set(fe, p, &state->tunedfreq);
589 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
590 }
591
592 /* set s5h1420 fclk PLL according to desired symbol rate */
593 if (p->u.qpsk.symbol_rate > 28000000) {
594 state->fclk = 88000000;
595 s5h1420_writereg(state, 0x03, 0x50);
596 s5h1420_writereg(state, 0x04, 0x40);
597 s5h1420_writereg(state, 0x05, 0xae);
598 } else if (p->u.qpsk.symbol_rate > 21000000) {
599 state->fclk = 59000000;
600 s5h1420_writereg(state, 0x03, 0x33);
601 s5h1420_writereg(state, 0x04, 0x40);
602 s5h1420_writereg(state, 0x05, 0xae);
603 } else {
604 state->fclk = 88000000;
605 s5h1420_writereg(state, 0x03, 0x50);
606 s5h1420_writereg(state, 0x04, 0x40);
607 s5h1420_writereg(state, 0x05, 0xac);
608 }
609
610 /* set misc registers */
611 s5h1420_writereg(state, 0x02, 0x00);
612 s5h1420_writereg(state, 0x07, 0xb0);
613 s5h1420_writereg(state, 0x0a, 0x67);
614 s5h1420_writereg(state, 0x0b, 0x78);
615 s5h1420_writereg(state, 0x0c, 0x48);
616 s5h1420_writereg(state, 0x0d, 0x6b);
617 s5h1420_writereg(state, 0x2e, 0x8e);
618 s5h1420_writereg(state, 0x35, 0x33);
619 s5h1420_writereg(state, 0x38, 0x01);
620 s5h1420_writereg(state, 0x39, 0x7d);
621 s5h1420_writereg(state, 0x3a, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
622 s5h1420_writereg(state, 0x3c, 0x00);
623 s5h1420_writereg(state, 0x45, 0x61);
624 s5h1420_writereg(state, 0x46, 0x1d);
625
626 /* start QPSK */
627 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
628
629 /* set the frequency offset to adjust for PLL inaccuracy */
630 s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq);
631
632 /* set the reset of the parameters */
633 s5h1420_setsymbolrate(state, p);
634 s5h1420_setinversion(state, p);
635 s5h1420_setfec(state, p);
636
637 state->fec_inner = p->u.qpsk.fec_inner;
638 state->symbol_rate = p->u.qpsk.symbol_rate;
639 state->postlocked = 0;
640 return 0;
641}
642
643static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
644{
645 struct s5h1420_state* state = fe->demodulator_priv;
646
647 p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state);
648 p->inversion = s5h1420_getinversion(state);
649 p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state);
650 p->u.qpsk.fec_inner = s5h1420_getfec(state);
651
652 return 0;
653}
654
655static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
656{
657 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
658 fesettings->min_delay_ms = 50;
659 fesettings->step_size = 2000;
660 fesettings->max_drift = 8000;
661 } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
662 fesettings->min_delay_ms = 100;
663 fesettings->step_size = 1500;
664 fesettings->max_drift = 9000;
665 } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
666 fesettings->min_delay_ms = 100;
667 fesettings->step_size = 1000;
668 fesettings->max_drift = 8000;
669 } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
670 fesettings->min_delay_ms = 100;
671 fesettings->step_size = 500;
672 fesettings->max_drift = 7000;
673 } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
674 fesettings->min_delay_ms = 200;
675 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
676 fesettings->max_drift = 14 * fesettings->step_size;
677 } else {
678 fesettings->min_delay_ms = 200;
679 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
680 fesettings->max_drift = 18 * fesettings->step_size;
681 }
682
683 return 0;
684}
685
686static int s5h1420_init (struct dvb_frontend* fe)
687{
688 struct s5h1420_state* state = fe->demodulator_priv;
689
690 /* disable power down and do reset */
691 s5h1420_writereg(state, 0x02, 0x10);
692 msleep(10);
693 s5h1420_reset(state);
694
695 /* init PLL */
696 if (state->config->pll_init) {
697 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
698 state->config->pll_init(fe);
699 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
700 }
701
702 return 0;
703}
704
705static int s5h1420_sleep(struct dvb_frontend* fe)
706{
707 struct s5h1420_state* state = fe->demodulator_priv;
708
709 return s5h1420_writereg(state, 0x02, 0x12);
710}
711
712static void s5h1420_release(struct dvb_frontend* fe)
713{
714 struct s5h1420_state* state = fe->demodulator_priv;
715 kfree(state);
716}
717
718static struct dvb_frontend_ops s5h1420_ops;
719
720struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c)
721{
722 struct s5h1420_state* state = NULL;
723 u8 identity;
724
725 /* allocate memory for the internal state */
726 state = kmalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
727 if (state == NULL)
728 goto error;
729
730 /* setup the state */
731 state->config = config;
732 state->i2c = i2c;
733 memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
734 state->postlocked = 0;
735 state->fclk = 88000000;
736 state->tunedfreq = 0;
737 state->fec_inner = FEC_NONE;
738 state->symbol_rate = 0;
739
740 /* check if the demod is there + identify it */
741 identity = s5h1420_readreg(state, 0x00);
742 if (identity != 0x03)
743 goto error;
744
745 /* create dvb_frontend */
746 state->frontend.ops = &state->ops;
747 state->frontend.demodulator_priv = state;
748 return &state->frontend;
749
750error:
751 kfree(state);
752 return NULL;
753}
754
755static struct dvb_frontend_ops s5h1420_ops = {
756
757 .info = {
758 .name = "Samsung S5H1420 DVB-S",
759 .type = FE_QPSK,
760 .frequency_min = 950000,
761 .frequency_max = 2150000,
762 .frequency_stepsize = 125, /* kHz for QPSK frontends */
763 .frequency_tolerance = 29500,
764 .symbol_rate_min = 1000000,
765 .symbol_rate_max = 45000000,
766 /* .symbol_rate_tolerance = ???,*/
767 .caps = FE_CAN_INVERSION_AUTO |
768 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
769 FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
770 FE_CAN_QPSK
771 },
772
773 .release = s5h1420_release,
774
775 .init = s5h1420_init,
776 .sleep = s5h1420_sleep,
777
778 .set_frontend = s5h1420_set_frontend,
779 .get_frontend = s5h1420_get_frontend,
780 .get_tune_settings = s5h1420_get_tune_settings,
781
782 .read_status = s5h1420_read_status,
783 .read_ber = s5h1420_read_ber,
784 .read_signal_strength = s5h1420_read_signal_strength,
785 .read_ucblocks = s5h1420_read_ucblocks,
786
787 .diseqc_send_master_cmd = s5h1420_send_master_cmd,
788 .diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
789 .diseqc_send_burst = s5h1420_send_burst,
790 .set_tone = s5h1420_set_tone,
791 .set_voltage = s5h1420_set_voltage,
792};
793
794module_param(debug, int, 0644);
795
796MODULE_DESCRIPTION("Samsung S5H1420 DVB-S Demodulator driver");
797MODULE_AUTHOR("Andrew de Quincey");
798MODULE_LICENSE("GPL");
799
800EXPORT_SYMBOL(s5h1420_attach);
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
new file mode 100644
index 000000000000..b687fc77ceb3
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -0,0 +1,41 @@
1/*
2 Driver for S5H1420 QPSK Demodulators
3
4 Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
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
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef S5H1420_H
24#define S5H1420_H
25
26#include <linux/dvb/frontend.h>
27
28struct s5h1420_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
36};
37
38extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
39 struct i2c_adapter* i2c);
40
41#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index e681263bf079..928aca052afe 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -617,7 +617,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
617 617
618 /* wait for WGAGC lock */ 618 /* wait for WGAGC lock */
619 starttime = jiffies; 619 starttime = jiffies;
620 timeout = jiffies + (200 * HZ) / 1000; 620 timeout = jiffies + msecs_to_jiffies(2000);
621 while (time_before(jiffies, timeout)) { 621 while (time_before(jiffies, timeout)) {
622 msleep(10); 622 msleep(10);
623 if (stv0297_readreg(state, 0x43) & 0x08) 623 if (stv0297_readreg(state, 0x43) & 0x08)
@@ -629,7 +629,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
629 msleep(20); 629 msleep(20);
630 630
631 /* wait for equaliser partial convergence */ 631 /* wait for equaliser partial convergence */
632 timeout = jiffies + (50 * HZ) / 1000; 632 timeout = jiffies + msecs_to_jiffies(500);
633 while (time_before(jiffies, timeout)) { 633 while (time_before(jiffies, timeout)) {
634 msleep(10); 634 msleep(10);
635 635
@@ -642,7 +642,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
642 } 642 }
643 643
644 /* wait for equaliser full convergence */ 644 /* wait for equaliser full convergence */
645 timeout = jiffies + (delay * HZ) / 1000; 645 timeout = jiffies + msecs_to_jiffies(delay);
646 while (time_before(jiffies, timeout)) { 646 while (time_before(jiffies, timeout)) {
647 msleep(10); 647 msleep(10);
648 648
@@ -659,7 +659,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
659 stv0297_writereg_mask(state, 0x88, 8, 0); 659 stv0297_writereg_mask(state, 0x88, 8, 0);
660 660
661 /* wait for main lock */ 661 /* wait for main lock */
662 timeout = jiffies + (20 * HZ) / 1000; 662 timeout = jiffies + msecs_to_jiffies(20);
663 while (time_before(jiffies, timeout)) { 663 while (time_before(jiffies, timeout)) {
664 msleep(10); 664 msleep(10);
665 665
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 0beb370792ae..ab0c032472cc 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -49,10 +49,8 @@ struct tda1004x_state {
49 /* private demod data */ 49 /* private demod data */
50 u8 initialised; 50 u8 initialised;
51 enum tda1004x_demod demod_type; 51 enum tda1004x_demod demod_type;
52 u8 fw_version;
53}; 52};
54 53
55
56static int debug; 54static int debug;
57#define dprintk(args...) \ 55#define dprintk(args...) \
58 do { \ 56 do { \
@@ -122,6 +120,8 @@ static int debug;
122#define TDA10046H_GPIO_OUT_SEL 0x41 120#define TDA10046H_GPIO_OUT_SEL 0x41
123#define TDA10046H_GPIO_SELECT 0x42 121#define TDA10046H_GPIO_SELECT 0x42
124#define TDA10046H_AGC_CONF 0x43 122#define TDA10046H_AGC_CONF 0x43
123#define TDA10046H_AGC_THR 0x44
124#define TDA10046H_AGC_RENORM 0x45
125#define TDA10046H_AGC_GAINS 0x46 125#define TDA10046H_AGC_GAINS 0x46
126#define TDA10046H_AGC_TUN_MIN 0x47 126#define TDA10046H_AGC_TUN_MIN 0x47
127#define TDA10046H_AGC_TUN_MAX 0x48 127#define TDA10046H_AGC_TUN_MAX 0x48
@@ -274,14 +274,26 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state,
274 switch (bandwidth) { 274 switch (bandwidth) {
275 case BANDWIDTH_6_MHZ: 275 case BANDWIDTH_6_MHZ:
276 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz)); 276 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
277 if (state->config->if_freq == TDA10046_FREQ_045) {
278 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09);
279 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f);
280 }
277 break; 281 break;
278 282
279 case BANDWIDTH_7_MHZ: 283 case BANDWIDTH_7_MHZ:
280 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz)); 284 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
285 if (state->config->if_freq == TDA10046_FREQ_045) {
286 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
287 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79);
288 }
281 break; 289 break;
282 290
283 case BANDWIDTH_8_MHZ: 291 case BANDWIDTH_8_MHZ:
284 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz)); 292 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
293 if (state->config->if_freq == TDA10046_FREQ_045) {
294 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
295 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
296 }
285 break; 297 break;
286 298
287 default: 299 default:
@@ -315,20 +327,35 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
315 memcpy(buf + 1, mem + pos, tx_size); 327 memcpy(buf + 1, mem + pos, tx_size);
316 fw_msg.len = tx_size + 1; 328 fw_msg.len = tx_size + 1;
317 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) { 329 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
318 printk("tda1004x: Error during firmware upload\n"); 330 printk(KERN_ERR "tda1004x: Error during firmware upload\n");
319 return -EIO; 331 return -EIO;
320 } 332 }
321 pos += tx_size; 333 pos += tx_size;
322 334
323 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); 335 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
324 } 336 }
337 // give the DSP a chance to settle 03/10/05 Hac
338 msleep(100);
325 339
326 return 0; 340 return 0;
327} 341}
328 342
329static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion) 343static int tda1004x_check_upload_ok(struct tda1004x_state *state)
330{ 344{
331 u8 data1, data2; 345 u8 data1, data2;
346 unsigned long timeout;
347
348 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
349 timeout = jiffies + 2 * HZ;
350 while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
351 if (time_after(jiffies, timeout)) {
352 printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
353 break;
354 }
355 msleep(1);
356 }
357 } else
358 msleep(100);
332 359
333 // check upload was OK 360 // check upload was OK
334 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP 361 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
@@ -336,9 +363,11 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
336 363
337 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); 364 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
338 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); 365 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
339 if ((data1 != 0x67) || (data2 != dspVersion)) 366 if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
367 printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
340 return -EIO; 368 return -EIO;
341 369 }
370 printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
342 return 0; 371 return 0;
343} 372}
344 373
@@ -349,14 +378,14 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
349 const struct firmware *fw; 378 const struct firmware *fw;
350 379
351 /* don't re-upload unless necessary */ 380 /* don't re-upload unless necessary */
352 if (tda1004x_check_upload_ok(state, 0x2c) == 0) 381 if (tda1004x_check_upload_ok(state) == 0)
353 return 0; 382 return 0;
354 383
355 /* request the firmware, this will block until someone uploads it */ 384 /* request the firmware, this will block until someone uploads it */
356 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); 385 printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
357 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); 386 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
358 if (ret) { 387 if (ret) {
359 printk("tda1004x: no firmware upload (timeout or file not found?)\n"); 388 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
360 return ret; 389 return ret;
361 } 390 }
362 391
@@ -370,95 +399,93 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
370 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ); 399 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
371 400
372 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN); 401 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
402 release_firmware(fw);
373 if (ret) 403 if (ret)
374 return ret; 404 return ret;
375 printk("tda1004x: firmware upload complete\n"); 405 printk(KERN_INFO "tda1004x: firmware upload complete\n");
376 406
377 /* wait for DSP to initialise */ 407 /* wait for DSP to initialise */
378 /* DSPREADY doesn't seem to work on the TDA10045H */ 408 /* DSPREADY doesn't seem to work on the TDA10045H */
379 msleep(100); 409 msleep(100);
380 410
381 return tda1004x_check_upload_ok(state, 0x2c); 411 return tda1004x_check_upload_ok(state);
382} 412}
383 413
384static int tda10046_get_fw_version(struct tda1004x_state *state, 414static void tda10046_init_plls(struct dvb_frontend* fe)
385 const struct firmware *fw)
386{ 415{
387 const unsigned char pattern[] = { 0x67, 0x00, 0x50, 0x62, 0x5e, 0x18, 0x67 }; 416 struct tda1004x_state* state = fe->demodulator_priv;
388 unsigned int i;
389
390 /* area guessed from firmware v20, v21 and v25 */
391 for (i = 0x660; i < 0x700; i++) {
392 if (!memcmp(&fw->data[i], pattern, sizeof(pattern))) {
393 state->fw_version = fw->data[i + sizeof(pattern)];
394 printk(KERN_INFO "tda1004x: using firmware v%02x\n",
395 state->fw_version);
396 return 0;
397 }
398 }
399 417
400 return -EINVAL; 418 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
419 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
420 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
421 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
422 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
423 } else {
424 dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
425 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
426 }
427 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
428 switch (state->config->if_freq) {
429 case TDA10046_FREQ_3617:
430 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
431 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
432 break;
433 case TDA10046_FREQ_3613:
434 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
435 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13);
436 break;
437 case TDA10046_FREQ_045:
438 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
439 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
440 break;
441 case TDA10046_FREQ_052:
442 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
443 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06);
444 break;
445 }
446 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
401} 447}
402 448
403static int tda10046_fwupload(struct dvb_frontend* fe) 449static int tda10046_fwupload(struct dvb_frontend* fe)
404{ 450{
405 struct tda1004x_state* state = fe->demodulator_priv; 451 struct tda1004x_state* state = fe->demodulator_priv;
406 unsigned long timeout;
407 int ret; 452 int ret;
408 const struct firmware *fw; 453 const struct firmware *fw;
409 454
410 /* reset + wake up chip */ 455 /* reset + wake up chip */
411 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); 456 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
412 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); 457 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
413 msleep(100); 458 /* let the clocks recover from sleep */
459 msleep(5);
414 460
415 /* don't re-upload unless necessary */ 461 /* don't re-upload unless necessary */
416 if (tda1004x_check_upload_ok(state, state->fw_version) == 0) 462 if (tda1004x_check_upload_ok(state) == 0)
417 return 0; 463 return 0;
418 464
419 /* request the firmware, this will block until someone uploads it */
420 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
421 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
422 if (ret) {
423 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
424 return ret;
425 }
426
427 if (fw->size < 24478) { /* size of firmware v20, which is the smallest of v20, v21 and v25 */
428 printk("tda1004x: firmware file seems to be too small (%d bytes)\n", fw->size);
429 return -EINVAL;
430 }
431
432 ret = tda10046_get_fw_version(state, fw);
433 if (ret < 0) {
434 printk("tda1004x: unable to find firmware version\n");
435 return ret;
436 }
437
438 /* set parameters */ 465 /* set parameters */
439 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); 466 tda10046_init_plls(fe);
440 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); 467
441 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); 468 if (state->config->request_firmware != NULL) {
442 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); 469 /* request the firmware, this will block until someone uploads it */
443 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); 470 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
444 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST 471 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
445 472 if (ret) {
446 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); 473 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
447 if (ret) 474 return ret;
448 return ret;
449 printk("tda1004x: firmware upload complete\n");
450
451 /* wait for DSP to initialise */
452 timeout = jiffies + HZ;
453 while (!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
454 if (time_after(jiffies, timeout)) {
455 printk("tda1004x: DSP failed to initialised.\n");
456 return -EIO;
457 } 475 }
458 msleep(1); 476 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
477 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
478 release_firmware(fw);
479 if (ret)
480 return ret;
481 } else {
482 /* boot from firmware eeprom */
483 /* Hac Note: we might need to do some GPIO Magic here */
484 printk(KERN_INFO "tda1004x: booting from eeprom\n");
485 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
486 msleep(300);
459 } 487 }
460 488 return tda1004x_check_upload_ok(state);
461 return tda1004x_check_upload_ok(state, state->fw_version);
462} 489}
463 490
464static int tda1004x_encode_fec(int fec) 491static int tda1004x_encode_fec(int fec)
@@ -560,12 +587,10 @@ static int tda10046_init(struct dvb_frontend* fe)
560 587
561 if (tda10046_fwupload(fe)) { 588 if (tda10046_fwupload(fe)) {
562 printk("tda1004x: firmware upload failed\n"); 589 printk("tda1004x: firmware upload failed\n");
563 return -EIO; 590 return -EIO;
564 } 591 }
565 592
566 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); // wake up the chip 593 // Init the tuner PLL
567
568 // Init the PLL
569 if (state->config->pll_init) { 594 if (state->config->pll_init) {
570 tda1004x_enable_tuner_i2c(state); 595 tda1004x_enable_tuner_i2c(state);
571 state->config->pll_init(fe); 596 state->config->pll_init(fe);
@@ -574,32 +599,44 @@ static int tda10046_init(struct dvb_frontend* fe)
574 599
575 // tda setup 600 // tda setup
576 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer 601 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
577 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0x40); 602 tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream
578 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream 603 tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
579 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer 604
580 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 605 tda10046_init_plls(fe);
581 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); // PLL P = N = 0 606 switch (state->config->agc_config) {
582 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99 607 case TDA10046_AGC_DEFAULT:
583 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221 608 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
584 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // } 609 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
585 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0); // AGC setup 610 break;
586 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities 611 case TDA10046_AGC_IFO_AUTO_NEG:
612 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
613 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
614 break;
615 case TDA10046_AGC_IFO_AUTO_POS:
616 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
617 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities
618 break;
619 case TDA10046_AGC_TDA827X:
620 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
621 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
622 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize
623 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
624 break;
625 }
626 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
587 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } 627 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
588 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values 628 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
589 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } 629 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
590 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } 630 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
591 tda1004x_write_mask(state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
592 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1 631 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
593 tda1004x_write_mask(state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm 632 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
594 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config 633 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
595 tda1004x_write_mask(state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config 634 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
596 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN 635 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
636
597 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup 637 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
598 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config 638 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
599 tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select 639 tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select
600 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
601
602 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
603 640
604 state->initialised = 1; 641 state->initialised = 1;
605 return 0; 642 return 0;
@@ -629,9 +666,6 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
629 state->config->pll_set(fe, fe_params); 666 state->config->pll_set(fe, fe_params);
630 tda1004x_disable_tuner_i2c(state); 667 tda1004x_disable_tuner_i2c(state);
631 668
632 if (state->demod_type == TDA1004X_DEMOD_TDA10046)
633 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
634
635 // Hardcoded to use auto as much as possible on the TDA10045 as it 669 // Hardcoded to use auto as much as possible on the TDA10045 as it
636 // is very unreliable if AUTO mode is _not_ used. 670 // is very unreliable if AUTO mode is _not_ used.
637 if (state->demod_type == TDA1004X_DEMOD_TDA10045) { 671 if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
@@ -1089,6 +1123,11 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1089 break; 1123 break;
1090 1124
1091 case TDA1004X_DEMOD_TDA10046: 1125 case TDA1004X_DEMOD_TDA10046:
1126 if (state->config->pll_sleep != NULL) {
1127 tda1004x_enable_tuner_i2c(state);
1128 state->config->pll_sleep(fe);
1129 tda1004x_disable_tuner_i2c(state);
1130 }
1092 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1131 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1093 break; 1132 break;
1094 } 1133 }
@@ -1100,8 +1139,9 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1100static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 1139static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1101{ 1140{
1102 fesettings->min_delay_ms = 800; 1141 fesettings->min_delay_ms = 800;
1103 fesettings->step_size = 166667; 1142 /* Drift compensation makes no sense for DVB-T */
1104 fesettings->max_drift = 166667*2; 1143 fesettings->step_size = 0;
1144 fesettings->max_drift = 0;
1105 return 0; 1145 return 0;
1106} 1146}
1107 1147
@@ -1216,7 +1256,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1216 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); 1256 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1217 state->initialised = 0; 1257 state->initialised = 0;
1218 state->demod_type = TDA1004X_DEMOD_TDA10046; 1258 state->demod_type = TDA1004X_DEMOD_TDA10046;
1219 state->fw_version = 0x20; /* dummy default value */
1220 1259
1221 /* check if the demod is there */ 1260 /* check if the demod is there */
1222 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { 1261 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index c8e1d54ff262..8659c52647ad 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -26,6 +26,25 @@
26#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h> 27#include <linux/firmware.h>
28 28
29enum tda10046_xtal {
30 TDA10046_XTAL_4M,
31 TDA10046_XTAL_16M,
32};
33
34enum tda10046_agc {
35 TDA10046_AGC_DEFAULT, /* original configuration */
36 TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
37 TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
38 TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
39};
40
41enum tda10046_if {
42 TDA10046_FREQ_3617, /* original config, 36,166 MHZ */
43 TDA10046_FREQ_3613, /* 36,13 MHZ */
44 TDA10046_FREQ_045, /* low IF, 4.0, 4.5, or 5.0 MHZ */
45 TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */
46};
47
29struct tda1004x_config 48struct tda1004x_config
30{ 49{
31 /* the demodulator's i2c address */ 50 /* the demodulator's i2c address */
@@ -37,14 +56,22 @@ struct tda1004x_config
37 /* Does the OCLK signal need inverted? */ 56 /* Does the OCLK signal need inverted? */
38 u8 invert_oclk; 57 u8 invert_oclk;
39 58
40 /* value of N_I2C of the CONF_PLL3 register */ 59 /* Xtal frequency, 4 or 16MHz*/
41 u8 n_i2c; 60 enum tda10046_xtal xtal_freq;
61
62 /* IF frequency */
63 enum tda10046_if if_freq;
64
65 /* AGC configuration */
66 enum tda10046_agc agc_config;
42 67
43 /* PLL maintenance */ 68 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe); 69 int (*pll_init)(struct dvb_frontend* fe);
70 void (*pll_sleep)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 71 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46 72
47 /* request firmware for device */ 73 /* request firmware for device */
74 /* set this to NULL if the card has a firmware EEPROM */
48 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 75 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
49}; 76};
50 77
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
index 032d348dafb7..88e125079ca1 100644
--- a/drivers/media/dvb/frontends/tda80xx.c
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -27,7 +27,6 @@
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/threads.h> 28#include <linux/threads.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/irq.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/slab.h> 32#include <linux/slab.h>