Index: linux/drivers/media/dvb/dvb-core/dvb_frontend.c =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.c,v retrieving revision 1.112 diff -u -r1.112 dvb_frontend.c --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c 1 Jul 2005 23:20:19 -0000 1.112 +++ linux/drivers/media/dvb/dvb-core/dvb_frontend.c 22 Sep 2005 17:15:13 -0000 @@ -577,6 +577,36 @@ fepriv->thread_pid); } +inline s32 dvb_frontend_calc_usec_delay (struct timeval lasttime, struct timeval curtime) +{ + return ((curtime.tv_usec < lasttime.tv_usec) ? + 1000000 - lasttime.tv_usec + curtime.tv_usec : + curtime.tv_usec - lasttime.tv_usec); +} + +void dvb_frontend_sleep_until (struct timeval *waketime, u32 add_usec) +{ + struct timeval lasttime; + s32 delta, newdelta; + + waketime->tv_usec += add_usec; + if (waketime->tv_usec >= 1000000) { + waketime->tv_usec -= 1000000; + waketime->tv_sec++; + } + + do_gettimeofday (&lasttime); + delta = dvb_frontend_calc_usec_delay (lasttime, *waketime); + if (delta > 2500) { + msleep ((delta - 1500) / 1000); + do_gettimeofday (&lasttime); + newdelta = dvb_frontend_calc_usec_delay (lasttime, *waketime); + delta = (newdelta > delta) ? 0 : newdelta; + } + if (delta > 0) + udelay (delta); +} + static int dvb_frontend_start(struct dvb_frontend *fe) { int ret; @@ -728,6 +758,41 @@ err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; + } else if (fe->ops->set_voltage) { + unsigned int cmd = ((unsigned int) parg) << 1; + struct timeval nexttime; + struct timeval tv[10]; + int i; + u8 last = 1; + if (dvb_frontend_debug) + printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd); + do_gettimeofday (&nexttime); + if (dvb_frontend_debug) + memcpy (&tv[0], &nexttime, sizeof (struct timeval)); + fe->ops->set_voltage(fe, SEC_VOLTAGE_18); + dvb_frontend_sleep_until (&nexttime, 32000); + + for (i=0; i<9; i++) { + if (dvb_frontend_debug) + do_gettimeofday (&tv[i+1]); + if((cmd & 0x01) != last) { + /* set voltage to (last ? 13V : 18V) */ + fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); + last = (last) ? 0 : 1; + } + cmd = cmd >> 1; + if (i != 8) + dvb_frontend_sleep_until (&nexttime, 8000); + } + if (dvb_frontend_debug) { + printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", + __FUNCTION__, fe->dvb->num); + for (i=1; i < 10; i++) + printk ("%d: %d\n", i, dvb_frontend_calc_usec_delay (tv[i-1] , tv[i])); + } + err = 0; + fepriv->state = FESTATE_DISEQC; + fepriv->status = 0; } break; Index: linux/drivers/media/dvb/dvb-core/dvb_frontend.h =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.h,v retrieving revision 1.22 diff -u -r1.22 dvb_frontend.h --- linux/drivers/media/dvb/dvb-core/dvb_frontend.h 13 Jun 2005 21:18:11 -0000 1.22 +++ linux/drivers/media/dvb/dvb-core/dvb_frontend.h 22 Sep 2005 17:15:13 -0000 @@ -101,4 +101,7 @@ extern int dvb_unregister_frontend(struct dvb_frontend* fe); +extern void dvb_frontend_sleep_until (struct timeval *waketime, u32 add_usec); +extern inline s32 dvb_frontend_calc_usec_delay (struct timeval lasttime, + struct timeval curtime); #endif Index: linux/drivers/media/dvb/frontends/stv0299.c =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/stv0299.c,v retrieving revision 1.70 diff -u -r1.70 stv0299.c --- linux/drivers/media/dvb/frontends/stv0299.c 4 Sep 2005 15:23:44 -0000 1.70 +++ linux/drivers/media/dvb/frontends/stv0299.c 22 Sep 2005 17:15:14 -0000 @@ -386,36 +386,6 @@ }; } -static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime) -{ - return ((curtime.tv_usec < lasttime.tv_usec) ? - 1000000 - lasttime.tv_usec + curtime.tv_usec : - curtime.tv_usec - lasttime.tv_usec); -} - -static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec) -{ - struct timeval lasttime; - s32 delta, newdelta; - - waketime->tv_usec += add_usec; - if (waketime->tv_usec >= 1000000) { - waketime->tv_usec -= 1000000; - waketime->tv_sec++; - } - - do_gettimeofday (&lasttime); - delta = stv0299_calc_usec_delay (lasttime, *waketime); - if (delta > 2500) { - msleep ((delta - 1500) / 1000); - do_gettimeofday (&lasttime); - newdelta = stv0299_calc_usec_delay (lasttime, *waketime); - delta = (newdelta > delta) ? 0 : newdelta; - } - if (delta > 0) - udelay (delta); -} - static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) { struct stv0299_state* state = fe->demodulator_priv; @@ -443,7 +413,7 @@ memcpy (&tv[0], &nexttime, sizeof (struct timeval)); stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ - stv0299_sleep_until (&nexttime, 32000); + dvb_frontend_sleep_until (&nexttime, 32000); for (i=0; i<9; i++) { if (debug_legacy_dish_switch) @@ -457,13 +427,13 @@ cmd = cmd >> 1; if (i != 8) - stv0299_sleep_until (&nexttime, 8000); + dvb_frontend_sleep_until (&nexttime, 8000); } if (debug_legacy_dish_switch) { printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", __FUNCTION__, fe->dvb->num); for (i=1; i < 10; i++) - printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i])); + printk ("%d: %d\n", i, dvb_frontend_calc_usec_delay (tv[i-1] , tv[i])); } return 0;