aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/cx24110.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/cx24110.c')
-rw-r--r--drivers/media/dvb/frontends/cx24110.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 8222b88cb486..d4b97989e3ed 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -1,7 +1,7 @@
1/* 1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module 2 cx24110 - Single Chip Satellite Channel Receiver driver module
3 3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on 4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
5 work 5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> 6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7 7
@@ -387,8 +387,9 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
387 387
388static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) 388static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
389{ 389{
390 int rv, bit, i; 390 int rv, bit;
391 struct cx24110_state *state = fe->demodulator_priv; 391 struct cx24110_state *state = fe->demodulator_priv;
392 unsigned long timeout;
392 393
393 if (burst == SEC_MINI_A) 394 if (burst == SEC_MINI_A)
394 bit = 0x00; 395 bit = 0x00;
@@ -398,12 +399,14 @@ static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
398 return -EINVAL; 399 return -EINVAL;
399 400
400 rv = cx24110_readreg(state, 0x77); 401 rv = cx24110_readreg(state, 0x77);
401 cx24110_writereg(state, 0x77, rv|0x04); 402 if (!(rv & 0x04))
403 cx24110_writereg(state, 0x77, rv | 0x04);
402 404
403 rv = cx24110_readreg(state, 0x76); 405 rv = cx24110_readreg(state, 0x76);
404 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit)); 406 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
405 for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; ) 407 timeout = jiffies + msecs_to_jiffies(100);
406 ; /* wait for LNB ready */ 408 while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
409 ; /* wait for LNB ready */
407 410
408 return 0; 411 return 0;
409} 412}
@@ -413,17 +416,22 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
413{ 416{
414 int i, rv; 417 int i, rv;
415 struct cx24110_state *state = fe->demodulator_priv; 418 struct cx24110_state *state = fe->demodulator_priv;
419 unsigned long timeout;
416 420
417 for (i = 0; i < cmd->msg_len; i++) 421 for (i = 0; i < cmd->msg_len; i++)
418 cx24110_writereg(state, 0x79 + i, cmd->msg[i]); 422 cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
419 423
420 rv = cx24110_readreg(state, 0x77); 424 rv = cx24110_readreg(state, 0x77);
421 cx24110_writereg(state, 0x77, rv|0x04); 425 if (rv & 0x04) {
426 cx24110_writereg(state, 0x77, rv & ~0x04);
427 msleep(30); /* reportedly fixes switching problems */
428 }
422 429
423 rv = cx24110_readreg(state, 0x76); 430 rv = cx24110_readreg(state, 0x76);
424 431
425 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); 432 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
426 for (i=500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40);) 433 timeout = jiffies + msecs_to_jiffies(100);
434 while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
427 ; /* wait for LNB ready */ 435 ; /* wait for LNB ready */
428 436
429 return 0; 437 return 0;