From 39f44d0380658c6f2422553d71aec1475a3eeb6c Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Thu, 15 Mar 2012 17:33:16 +0000 Subject: xpp: FXS: better power-down to lower noise * Now every linefeed control command which is not RING'ing powers-down the SLIC. This reduce audible noise when several channels are ringing. * Simplify code by removing redundant calls to do_chan_power() before linefeed_control() * Manage vbat_h state so we skip do_chan_power() calls when there isn't a state change * Export vbat_h state to /proc/.../fxs_info Signed-off-by: Oron Peled Acked-by: Tzafrir Cohen Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10478 git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.5@10488 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/xpp/card_fxs.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c index 6f192cc..c439f00 100644 --- a/drivers/dahdi/xpp/card_fxs.c +++ b/drivers/dahdi/xpp/card_fxs.c @@ -135,6 +135,7 @@ struct FXS_priv_data { xpp_line_t want_dtmf_mute; /* what dahdi want */ xpp_line_t prev_key_down; /* DTMF down sets the bit */ xpp_line_t neon_blinking; + xpp_line_t vbat_h; /* High voltage */ struct timeval prev_key_time[CHANNELS_PERXPD]; int led_counter[NUM_LEDS][CHANNELS_PERXPD]; int ohttimer[CHANNELS_PERXPD]; @@ -157,26 +158,35 @@ struct FXS_priv_data { #define LED_BLINK_RING (1000/8) /* in ticks */ /*---------------- FXS: Static functions ----------------------------------*/ +static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on) +{ + struct FXS_priv_data *priv; + + BUG_ON(!xbus); + BUG_ON(!xpd); + priv = xpd->priv; + LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on) ? "up" : "down"); + if (on) + BIT_SET(priv->vbat_h, chan); + else + BIT_CLR(priv->vbat_h, chan); + return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, REG_BATTERY, + (on) ? REG_BATTERY_BATSL : 0x00); +} + static int linefeed_control(xbus_t *xbus, xpd_t *xpd, lineno_t chan, enum fxs_state value) { struct FXS_priv_data *priv; + bool want_vbat_h = (value == FXS_LINE_RING) ? 1 : 0; priv = xpd->priv; LINE_DBG(SIGNAL, xpd, chan, "value=0x%02X\n", value); priv->lasttxhook[chan] = value; + if (IS_SET(priv->vbat_h, chan) != want_vbat_h) + do_chan_power(xbus, xpd, chan, want_vbat_h); return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value); } -static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on) -{ - int value = (on) ? REG_BATTERY_BATSL : 0x00; - - BUG_ON(!xbus); - BUG_ON(!xpd); - LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on) ? "up" : "down"); - return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, REG_BATTERY, value); -} - static void vmwi_search(xpd_t *xpd, lineno_t pos, bool on) { struct FXS_priv_data *priv; @@ -654,7 +664,6 @@ static void start_stop_vm_led(xbus_t *xbus, xpd_t *xpd, lineno_t pos) msgs = PHONEDEV(xpd).msg_waiting[pos]; LINE_DBG(SIGNAL, xpd, pos, "%s\n", (msgs) ? "ON" : "OFF"); set_vm_led_mode(xbus, xpd, pos, msgs); - do_chan_power(xbus, xpd, pos, msgs > 0); linefeed_control(xbus, xpd, pos, (msgs > 0) ? FXS_LINE_RING : priv->idletxhookstate[pos]); } @@ -691,7 +700,6 @@ static int send_ring(xpd_t *xpd, lineno_t chan, bool on) LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on)?"on":"off"); priv = xpd->priv; set_vm_led_mode(xbus, xpd, chan, 0); - do_chan_power(xbus, xpd, chan, on); // Power up (for ring) ret = linefeed_control(xbus, xpd, chan, value); if(on) { MARK_BLINK(priv, chan, LED_GREEN, LED_BLINK_RING); @@ -1555,6 +1563,11 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in IS_SET(priv->search_fsk_pattern, i) ); } + len += sprintf(page + len, "\n%-12s", "vbat_h:"); + for_each_line(xpd, i) { + len += sprintf(page + len, "%4d", + IS_SET(priv->vbat_h, i)); + } len += sprintf(page + len, "\n"); for(led = 0; led < NUM_LEDS; led++) { len += sprintf(page + len, "LED #%d", led); -- cgit v1.2.3