diff options
author | Malcolm Priestley <tvboxspy@gmail.com> | 2011-02-06 10:29:51 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:32:21 -0400 |
commit | 2b74334d12914eb10b8dac90300c3799a2115569 (patch) | |
tree | 7640778bbc5ce7d0b212b7c183c9ee93c1e8db2a | |
parent | 92374e886c7518387e6816dedfe60fc7bdfa8fdd (diff) |
[media] dvb_pll: DVB-S incorrect tune settings for dw2102/dm1105/cx88/opera1
This tuner PLL has missing initialisation settings resulting in
haphazard tuning. The PLL LPF was set to just 22000 symbol rate.
Basically, the module is a Sharp BS2F7HZ0194 (STV0299+IX2410)
I have had problems implementing the PLL in a new driver and
did not want to break the IX2410 out of the PLL.
This applies to DW2102, DM1105, CX88 and OPERA1 drivers.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.c | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 4d4d0bb5920..62a65efdf8d 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -64,6 +64,7 @@ struct dvb_pll_desc { | |||
64 | void (*set)(struct dvb_frontend *fe, u8 *buf, | 64 | void (*set)(struct dvb_frontend *fe, u8 *buf, |
65 | const struct dvb_frontend_parameters *params); | 65 | const struct dvb_frontend_parameters *params); |
66 | u8 *initdata; | 66 | u8 *initdata; |
67 | u8 *initdata2; | ||
67 | u8 *sleepdata; | 68 | u8 *sleepdata; |
68 | int count; | 69 | int count; |
69 | struct { | 70 | struct { |
@@ -321,26 +322,73 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { | |||
321 | static void opera1_bw(struct dvb_frontend *fe, u8 *buf, | 322 | static void opera1_bw(struct dvb_frontend *fe, u8 *buf, |
322 | const struct dvb_frontend_parameters *params) | 323 | const struct dvb_frontend_parameters *params) |
323 | { | 324 | { |
324 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) | 325 | struct dvb_pll_priv *priv = fe->tuner_priv; |
325 | buf[2] |= 0x08; | 326 | u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000; |
327 | struct i2c_msg msg = { | ||
328 | .addr = priv->pll_i2c_address, | ||
329 | .flags = 0, | ||
330 | .buf = buf, | ||
331 | .len = 4 | ||
332 | }; | ||
333 | int result; | ||
334 | u8 lpf; | ||
335 | |||
336 | if (fe->ops.i2c_gate_ctrl) | ||
337 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
338 | |||
339 | result = i2c_transfer(priv->i2c, &msg, 1); | ||
340 | if (result != 1) | ||
341 | printk(KERN_ERR "%s: i2c_transfer failed:%d", | ||
342 | __func__, result); | ||
343 | |||
344 | if (b_w <= 10000) | ||
345 | lpf = 0xc; | ||
346 | else if (b_w <= 12000) | ||
347 | lpf = 0x2; | ||
348 | else if (b_w <= 14000) | ||
349 | lpf = 0xa; | ||
350 | else if (b_w <= 16000) | ||
351 | lpf = 0x6; | ||
352 | else if (b_w <= 18000) | ||
353 | lpf = 0xe; | ||
354 | else if (b_w <= 20000) | ||
355 | lpf = 0x1; | ||
356 | else if (b_w <= 22000) | ||
357 | lpf = 0x9; | ||
358 | else if (b_w <= 24000) | ||
359 | lpf = 0x5; | ||
360 | else if (b_w <= 26000) | ||
361 | lpf = 0xd; | ||
362 | else if (b_w <= 28000) | ||
363 | lpf = 0x3; | ||
364 | else | ||
365 | lpf = 0xb; | ||
366 | buf[2] ^= 0x1c; /* Flip bits 3-5 */ | ||
367 | /* Set lpf */ | ||
368 | buf[2] |= ((lpf >> 2) & 0x3) << 3; | ||
369 | buf[3] |= (lpf & 0x3) << 2; | ||
370 | |||
371 | return; | ||
326 | } | 372 | } |
327 | 373 | ||
328 | static struct dvb_pll_desc dvb_pll_opera1 = { | 374 | static struct dvb_pll_desc dvb_pll_opera1 = { |
329 | .name = "Opera Tuner", | 375 | .name = "Opera Tuner", |
330 | .min = 900000, | 376 | .min = 900000, |
331 | .max = 2250000, | 377 | .max = 2250000, |
378 | .initdata = (u8[]){ 4, 0x08, 0xe5, 0xe1, 0x00 }, | ||
379 | .initdata2 = (u8[]){ 4, 0x08, 0xe5, 0xe5, 0x00 }, | ||
332 | .iffreq= 0, | 380 | .iffreq= 0, |
333 | .set = opera1_bw, | 381 | .set = opera1_bw, |
334 | .count = 8, | 382 | .count = 8, |
335 | .entries = { | 383 | .entries = { |
336 | { 1064000, 500, 0xe5, 0xc6 }, | 384 | { 1064000, 500, 0xf9, 0xc2 }, |
337 | { 1169000, 500, 0xe5, 0xe6 }, | 385 | { 1169000, 500, 0xf9, 0xe2 }, |
338 | { 1299000, 500, 0xe5, 0x24 }, | 386 | { 1299000, 500, 0xf9, 0x20 }, |
339 | { 1444000, 500, 0xe5, 0x44 }, | 387 | { 1444000, 500, 0xf9, 0x40 }, |
340 | { 1606000, 500, 0xe5, 0x64 }, | 388 | { 1606000, 500, 0xf9, 0x60 }, |
341 | { 1777000, 500, 0xe5, 0x84 }, | 389 | { 1777000, 500, 0xf9, 0x80 }, |
342 | { 1941000, 500, 0xe5, 0xa4 }, | 390 | { 1941000, 500, 0xf9, 0xa0 }, |
343 | { 2250000, 500, 0xe5, 0xc4 }, | 391 | { 2250000, 500, 0xf9, 0xc0 }, |
344 | } | 392 | } |
345 | }; | 393 | }; |
346 | 394 | ||
@@ -648,8 +696,17 @@ static int dvb_pll_init(struct dvb_frontend *fe) | |||
648 | int result; | 696 | int result; |
649 | if (fe->ops.i2c_gate_ctrl) | 697 | if (fe->ops.i2c_gate_ctrl) |
650 | fe->ops.i2c_gate_ctrl(fe, 1); | 698 | fe->ops.i2c_gate_ctrl(fe, 1); |
651 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | 699 | result = i2c_transfer(priv->i2c, &msg, 1); |
700 | if (result != 1) | ||
652 | return result; | 701 | return result; |
702 | if (priv->pll_desc->initdata2) { | ||
703 | msg.buf = priv->pll_desc->initdata2 + 1; | ||
704 | msg.len = priv->pll_desc->initdata2[0]; | ||
705 | if (fe->ops.i2c_gate_ctrl) | ||
706 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
707 | result = i2c_transfer(priv->i2c, &msg, 1); | ||
708 | if (result != 1) | ||
709 | return result; | ||
653 | } | 710 | } |
654 | return 0; | 711 | return 0; |
655 | } | 712 | } |