summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2012-03-15 12:52:32 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2012-03-15 12:52:32 +0000
commite216b9bbd6fda819b53a2c16ff6e2f1e7a64503e (patch)
treed19db06019638d93ee7c96f66e772572ff56046e
parent9efb2889cfc1405f81429f379efd1997f356a89c (diff)
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 <oron.peled@xorcom.com> Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10478 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/xpp/card_fxs.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c
index c9be904..31cfea3 100644
--- a/drivers/dahdi/xpp/card_fxs.c
+++ b/drivers/dahdi/xpp/card_fxs.c
@@ -147,6 +147,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];
@@ -179,28 +180,36 @@ 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;
@@ -738,7 +747,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]);
@@ -778,7 +786,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);
@@ -1701,6 +1708,11 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count,
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);