aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Stezenbach <js@linuxtv.org>2005-05-17 00:54:31 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-17 10:59:30 -0400
commit591ad98db3be2cd596ac5e0cfba7b164c3bdfb52 (patch)
tree93d688cd7a405a0fec635e7c4dc3fa3b05f97f08 /drivers
parent7f5e02db4a39c36e68878a14fae1fe7ee6dd6fcf (diff)
[PATCH] dvb: stv0299: fix FE_DISHNETWORK_SEND_LEGACY_CMD
fix the current stv0299 code that handles FE_DISHNETWORK_SEND_LEGACY_CMD. (supports the legacy SW21, SW44, and SW64 switches) Signed-off-by: Johannes Stezenbach <js@linuxtv.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb/frontends/stv0299.c78
1 files changed, 66 insertions, 12 deletions
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 15b40541b62d..a47cd2b32d60 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -70,6 +70,7 @@ struct stv0299_state {
70#define STATUS_UCBLOCKS 1 70#define STATUS_UCBLOCKS 1
71 71
72static int debug; 72static int debug;
73static int debug_legacy_dish_switch;
73#define dprintk(args...) \ 74#define dprintk(args...) \
74 do { \ 75 do { \
75 if (debug) printk(KERN_DEBUG "stv0299: " args); \ 76 if (debug) printk(KERN_DEBUG "stv0299: " args); \
@@ -385,34 +386,84 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
385 }; 386 };
386} 387}
387 388
388static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd) 389static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
389{ 390{
391 return ((curtime.tv_usec < lasttime.tv_usec) ?
392 1000000 - lasttime.tv_usec + curtime.tv_usec :
393 curtime.tv_usec - lasttime.tv_usec);
394}
395
396static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
397{
398 struct timeval lasttime;
399 s32 delta, newdelta;
400
401 waketime->tv_usec += add_usec;
402 if (waketime->tv_usec >= 1000000) {
403 waketime->tv_usec -= 1000000;
404 waketime->tv_sec++;
405 }
406
407 do_gettimeofday (&lasttime);
408 delta = stv0299_calc_usec_delay (lasttime, *waketime);
409 if (delta > 2500) {
410 msleep ((delta - 1500) / 1000);
411 do_gettimeofday (&lasttime);
412 newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
413 delta = (newdelta > delta) ? 0 : newdelta;
414 }
415 if (delta > 0)
416 udelay (delta);
417}
418
419static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
420{
421 struct stv0299_state* state = fe->demodulator_priv;
422 u8 reg0x08;
423 u8 reg0x0c;
424 u8 lv_mask = 0x40;
390 u8 last = 1; 425 u8 last = 1;
391 int i; 426 int i;
427 struct timeval nexttime;
428 struct timeval tv[10];
392 429
393 /* reset voltage at the end 430 reg0x08 = stv0299_readreg (state, 0x08);
394 if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50) 431 reg0x0c = stv0299_readreg (state, 0x0c);
395 cmd |= 0x80; 432 reg0x0c &= 0x0f;
396 else 433 stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
397 cmd &= 0x7F; 434 if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
398 */ 435 lv_mask = 0x10;
399 436
400 cmd = cmd << 1; 437 cmd = cmd << 1;
401 dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd); 438 if (debug_legacy_dish_switch)
439 printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
440
441 do_gettimeofday (&nexttime);
442 if (debug_legacy_dish_switch)
443 memcpy (&tv[0], &nexttime, sizeof (struct timeval));
444 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
402 445
403 stv0299_set_voltage(fe,SEC_VOLTAGE_18); 446 stv0299_sleep_until (&nexttime, 32000);
404 msleep(32);
405 447
406 for (i=0; i<9; i++) { 448 for (i=0; i<9; i++) {
449 if (debug_legacy_dish_switch)
450 do_gettimeofday (&tv[i+1]);
407 if((cmd & 0x01) != last) { 451 if((cmd & 0x01) != last) {
408 stv0299_set_voltage(fe, last ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); 452 /* set voltage to (last ? 13V : 18V) */
453 stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
409 last = (last) ? 0 : 1; 454 last = (last) ? 0 : 1;
410 } 455 }
411 456
412 cmd = cmd >> 1; 457 cmd = cmd >> 1;
413 458
414 if (i != 8) 459 if (i != 8)
415 msleep(8); 460 stv0299_sleep_until (&nexttime, 8000);
461 }
462 if (debug_legacy_dish_switch) {
463 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
464 __FUNCTION__, fe->dvb->num);
465 for (i=1; i < 10; i++)
466 printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i]));
416 } 467 }
417 468
418 return 0; 469 return 0;
@@ -719,6 +770,9 @@ static struct dvb_frontend_ops stv0299_ops = {
719 .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd, 770 .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
720}; 771};
721 772
773module_param(debug_legacy_dish_switch, int, 0444);
774MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches");
775
722module_param(debug, int, 0644); 776module_param(debug, int, 0644);
723MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 777MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
724 778