[dahdi-commits] dahdi/linux.git branch "master" updated.

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Tue Oct 1 07:26:39 CDT 2013


branch "master" has been updated
       via  2bd36a3307ec9f20e9538de08f8d2eec1f9828a9 (commit)
       via  600dd03e307e6fbec7dcbc9ac1df7ae35b2a48b6 (commit)
       via  3d1d87e5269ba551fbb2178515f76e765ed03b14 (commit)
      from  745118acb9205e502c145963f7c7afb7f4da10b3 (commit)

Summary of changes:
 drivers/dahdi/xpp/card_fxs.c     |  295 +++++++++++++++++++++++++++++---------
 drivers/dahdi/xpp/init_card_1_30 |   22 ++-
 2 files changed, 247 insertions(+), 70 deletions(-)


- Log -----------------------------------------------------------------
commit 2bd36a3307ec9f20e9538de08f8d2eec1f9828a9
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon Sep 23 11:51:18 2013 +0200

    xpp: ring/mwi settings: add to FXS init script
    
    init_card_1_30 (FXS modules init script) can now use the new sysfs
    interface to set ring settings.
    
    Currently it only overwrite a single register
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/init_card_1_30 b/drivers/dahdi/xpp/init_card_1_30
index d64a50e..e0e3485 100755
--- a/drivers/dahdi/xpp/init_card_1_30
+++ b/drivers/dahdi/xpp/init_card_1_30
@@ -59,6 +59,7 @@ my %settings;
 $settings{debug} = 0;
 $settings{fxs_skip_calib} = 0;
 my $chipregs;
+my $ring_registers;
 
 sub logit {
 	print STDERR "$unit_id: @_\n";
@@ -104,6 +105,10 @@ if (-t STDERR) {
 		logit "OLD DRIVER: does not use /sys chipregs. Falling back to /proc"
 			if -f $chipregs;
 	}
+	$ring_registers = sprintf "/sys/bus/xpds/devices/%02d:%1d:0/fxs_ring_registers",
+		$ENV{XBUS_NUMBER}, $ENV{UNIT_NUMBER};
+	logit "OLD DRIVER: missing '$ring_registers' -- fallback to hard-coded defaults"
+		unless -f $ring_registers;
 }
 
 sub set_output() {
@@ -147,6 +152,16 @@ sub write_to_slic_file($) {
 	
 }
 
+sub write_to_ring_register($) {
+	my $write_str = shift;
+
+	open(SLICS,">$ring_registers") or
+		die("Failed writing to ring_registers file $ring_registers");
+	print SLICS $write_str;
+	close(SLICS) or die "Failed writing '$write_str' to '$ring_registers': $!";
+	main::mysleep(0.001);
+}
+
 sub read_reg($$$) {
 	my $read_slic = shift;
 	my $read_reg = shift;
@@ -442,6 +457,10 @@ sub check_slics() {
 	return @slics;
 }
 
+sub overwrite_ring_registers() {
+	write_to_ring_register("NEON 0x33 0x12");
+}
+
 package main;
 
 main::debug "Starting '$0'";
@@ -470,6 +489,7 @@ while(<DATA>) {
 	print "$_\n";
 }
 close REG;
+FXS::overwrite_ring_registers();
 
 main::debug "Ending '$0'";
 close STDERR;

commit 600dd03e307e6fbec7dcbc9ac1df7ae35b2a48b6
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon Sep 23 11:27:28 2013 +0200

    xpp: FXS: ring/mwi settings: a sysfs interface
    
    A new SysFS interface for FXS modules (XPDs):
    * In /sys/bus/xpds/devices/<ll>:<m>:<n>/fxs_ring_registers
    * Reading show current register values for NEON/TRAPEZ/NORMAL
    * Modify the table via writing: "<column> <reg> <byte> [<byte>]"
    * Example:
    	echo "NEON 0x33 0x12" > \
    		'/sys/bus/xpds/devices/00:0:0/fxs_ring_registers'
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c
index c4790ca..ce36640 100644
--- a/drivers/dahdi/xpp/card_fxs.c
+++ b/drivers/dahdi/xpp/card_fxs.c
@@ -673,8 +673,8 @@ struct byte_pair {
 };
 
 struct ring_reg_params {
-	int is_indirect;
-	int regno;
+	const int is_indirect;
+	const int regno;
 	struct byte_pair values[1 + RING_TYPE_NORMAL - RING_TYPE_NEON];
 };
 
@@ -686,7 +686,7 @@ struct ring_reg_params {
 		}, \
 	}
 
-static const struct ring_reg_params ring_parameters[] = {
+static struct ring_reg_params ring_parameters[] = {
 	/*        INDIR REG     NEON            TRAPEZ          NORMAL */
 	REG_ENTRY(1,	0x16,	0xE8, 0x03,	0xC8, 0x00,	0x00, 0x00),
 	REG_ENTRY(1,	0x15,	0xEF, 0x7B,	0xAB, 0x5E,	0x77, 0x01),
@@ -1861,9 +1861,134 @@ static const struct file_operations proc_xpd_metering_ops = {
 #endif
 #endif
 
+static DEVICE_ATTR_READER(fxs_ring_registers_show, dev, buf)
+{
+	xpd_t *xpd;
+	struct FXS_priv_data *priv;
+	unsigned long flags;
+	const struct ring_reg_params *p;
+	const struct byte_pair *v;
+	enum ring_types rtype;
+	int len = 0;
+	int i;
+
+	BUG_ON(!dev);
+	xpd = dev_to_xpd(dev);
+	if (!xpd)
+		return -ENODEV;
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	spin_lock_irqsave(&xpd->lock, flags);
+	len += sprintf(buf + len, "#   Reg#: D/I\tNEON     \tTRAPEZ   \tNORMAL   \n");
+	for (i = 0; i < ARRAY_SIZE(ring_parameters); i++) {
+		p = &ring_parameters[i];
+		len += sprintf(buf + len, "[%d] 0x%02X: %c",
+			i, p->regno, (p->is_indirect) ? 'I' : 'D');
+		for (rtype = RING_TYPE_NEON; rtype <= RING_TYPE_NORMAL; rtype++) {
+			v = &(p->values[rtype]);
+			if (p->is_indirect)
+				len += sprintf(buf + len, "\t0x%02X 0x%02X",
+					v->h_val, v->l_val);
+			else
+				len += sprintf(buf + len, "\t0x%02X ----",
+					v->l_val);
+		}
+		len += sprintf(buf + len, "\n");
+	}
+	spin_unlock_irqrestore(&xpd->lock, flags);
+	return len;
+}
+
+static DEVICE_ATTR_WRITER(fxs_ring_registers_store, dev, buf, count)
+{
+	xpd_t *xpd;
+	struct FXS_priv_data *priv;
+	unsigned long flags;
+	char rtype_name[MAX_PROC_WRITE];
+	enum ring_types rtype;
+	struct ring_reg_params *params;
+	struct byte_pair *v;
+	int regno;
+	int h_val;
+	int l_val;
+	int ret;
+	int i;
+
+	BUG_ON(!dev);
+	xpd = dev_to_xpd(dev);
+	if (!xpd)
+		return -ENODEV;
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	ret = sscanf(buf, "%10s %X %X %X\n",
+		rtype_name, &regno, &h_val, &l_val);
+	if (ret < 3 || ret > 4) {
+		XPD_ERR(xpd, "Bad input: '%s'\n", buf);
+		XPD_ERR(xpd, "# Correct input\n");
+		XPD_ERR(xpd, "{NEON|TRAPEZ|NORMAL} <regno> <byte> [<byte>]\n");
+		goto invalid_input;
+	}
+	if (strcasecmp("NEON", rtype_name) == 0)
+		rtype = RING_TYPE_NEON;
+	else if (strcasecmp("TRAPEZ", rtype_name) == 0)
+		rtype = RING_TYPE_TRAPEZ;
+	else if (strcasecmp("NORMAL", rtype_name) == 0)
+		rtype = RING_TYPE_NORMAL;
+	else {
+		XPD_ERR(xpd, "Unknown ring type '%s' (NEON/TRAPEZ/NORMAL)\n",
+			rtype_name);
+		goto invalid_input;
+	}
+	params = NULL;
+	for (i = 0; i < ARRAY_SIZE(ring_parameters); i++) {
+		if (ring_parameters[i].regno == regno) {
+			params = &ring_parameters[i];
+			break;
+		}
+	}
+	if (!params) {
+		XPD_ERR(xpd, "Bad register 0x%X\n", regno);
+		goto invalid_input;
+	}
+	if (params->is_indirect) {
+		if (ret != 4) {
+			XPD_ERR(xpd,
+				"Missing low-byte (0x%X is indirect register)\n",
+				regno);
+			goto invalid_input;
+		}
+		XPD_INFO(xpd, "%s Indirect 0x%X <=== 0x%X 0x%X\n",
+			rtype_name, regno, h_val, l_val);
+	} else {
+		if (ret != 3) {
+			XPD_ERR(xpd,
+				"Should give exactly one value (0x%X is direct register)\n",
+				regno);
+			goto invalid_input;
+		}
+		l_val = h_val;
+		h_val = 0;
+		XPD_INFO(xpd, "%s Direct 0x%X <=== 0x%X\n",
+			rtype_name, regno, h_val);
+	}
+	spin_lock_irqsave(&xpd->lock, flags);
+	v = &(params->values[rtype]);
+	v->h_val = h_val;
+	v->l_val = l_val;
+	spin_unlock_irqrestore(&xpd->lock, flags);
+	return count;
+invalid_input:
+	return -EINVAL;
+}
+
+static DEVICE_ATTR(fxs_ring_registers, S_IRUGO | S_IWUSR,
+	fxs_ring_registers_show,
+	fxs_ring_registers_store);
+
 static int fxs_xpd_probe(struct device *dev)
 {
 	xpd_t *xpd;
+	int ret;
 
 	xpd = dev_to_xpd(dev);
 	/* Is it our device? */
@@ -1873,7 +1998,15 @@ static int fxs_xpd_probe(struct device *dev)
 		return -EINVAL;
 	}
 	XPD_DBG(DEVICES, xpd, "SYSFS\n");
+	ret = device_create_file(dev, &dev_attr_fxs_ring_registers);
+	if (ret) {
+		XPD_ERR(xpd, "%s: device_create_file(fxs_ring_registers) failed: %d\n",
+			__func__, ret);
+		goto fail_fxs_ring_registers;
+	}
 	return 0;
+fail_fxs_ring_registers:
+	return ret;
 }
 
 static int fxs_xpd_remove(struct device *dev)
@@ -1882,6 +2015,7 @@ static int fxs_xpd_remove(struct device *dev)
 
 	xpd = dev_to_xpd(dev);
 	XPD_DBG(DEVICES, xpd, "SYSFS\n");
+	device_remove_file(dev, &dev_attr_fxs_ring_registers);
 	return 0;
 }
 

commit 3d1d87e5269ba551fbb2178515f76e765ed03b14
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon Sep 16 17:32:37 2013 +0200

    xpp: refactor FXS ring settings
    
    xpp: refactor the FXS module ring settings into separate data structure:
    
    * Update High VBAT initialization in init_card_1_30:
      - Take the value used in set_vm_led_mode() (0x34)
      - Now we don't need to set it over and over again in set_vm_led_mode()
    * Create a unified ring_parameters[] array for all ring registers:
      - Columns for 3 ring types (NEON, TRAPEZ, NORMAL)
      - Used by new send_ring_parameters() function
    * Now the set_vm_led_mode() simply calls send_ring_parameters()
    * This cleanup would allow us to change ring parameters at runtime (by
      updating the values in these tables).
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c
index 921a3c2..c4790ca 100644
--- a/drivers/dahdi/xpp/card_fxs.c
+++ b/drivers/dahdi/xpp/card_fxs.c
@@ -654,6 +654,95 @@ static void __do_mute_dtmf(xpd_t *xpd, int pos, bool muteit)
 	CALL_PHONE_METHOD(card_pcm_recompute, xpd, priv->search_fsk_pattern);
 }
 
+struct ring_reg_param {
+	int is_indirect;
+	int regno;
+	uint8_t h_val;
+	uint8_t l_val;
+};
+
+enum ring_types {
+	RING_TYPE_NEON = 0,
+	RING_TYPE_TRAPEZ,
+	RING_TYPE_NORMAL,
+};
+
+struct byte_pair {
+	uint8_t h_val;
+	uint8_t l_val;
+};
+
+struct ring_reg_params {
+	int is_indirect;
+	int regno;
+	struct byte_pair values[1 + RING_TYPE_NORMAL - RING_TYPE_NEON];
+};
+
+#define	REG_ENTRY(di, reg, vh1, vl1, vh2, vl2, vh3, vl3) \
+	{ (di), (reg), .values = { \
+		[RING_TYPE_NEON]	= { .h_val = (vh1), .l_val = (vl1) }, \
+		[RING_TYPE_TRAPEZ]	= { .h_val = (vh2), .l_val = (vl2) }, \
+		[RING_TYPE_NORMAL]	= { .h_val = (vh3), .l_val = (vl3) }, \
+		}, \
+	}
+
+static const struct ring_reg_params ring_parameters[] = {
+	/*        INDIR REG     NEON            TRAPEZ          NORMAL */
+	REG_ENTRY(1,	0x16,	0xE8, 0x03,	0xC8, 0x00,	0x00, 0x00),
+	REG_ENTRY(1,	0x15,	0xEF, 0x7B,	0xAB, 0x5E,	0x77, 0x01),
+	REG_ENTRY(1,	0x14,	0x9F, 0x00,	0x8C, 0x01,	0xFD, 0x7E),
+
+	REG_ENTRY(0,	0x22,	0x00, 0x19,	0x00, 0x01,	0x00, 0x00),
+
+	REG_ENTRY(0,	0x30,	0x00, 0xE0,	0x00, 0x00,	0x00, 0x00),
+	REG_ENTRY(0,	0x31,	0x00, 0x01,	0x00, 0x00,	0x00, 0x00),
+	REG_ENTRY(0,	0x32,	0x00, 0xF0,	0x00, 0x00,	0x00, 0x00),
+	REG_ENTRY(0,	0x33,	0x00, 0x05,	0x00, 0x00,	0x00, 0x00),
+
+	REG_ENTRY(1,	0x1D,	0x00, 0x46,	0x00, 0x36,	0x00, 0x36),
+};
+
+static int send_ring_parameters(xbus_t *xbus, xpd_t *xpd, int pos,
+		enum ring_types rtype)
+{
+	const struct ring_reg_params *p;
+	const struct byte_pair *v;
+	int ret = 0;
+	int i;
+
+	if (rtype < RING_TYPE_NEON || rtype > RING_TYPE_NORMAL)
+		return -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(ring_parameters); i++) {
+		p = &ring_parameters[i];
+		v = &(p->values[rtype]);
+		if (p->is_indirect) {
+			LINE_DBG(REGS, xpd, pos,
+					"[%d] 0x%02X: I 0x%02X 0x%02X\n",
+					i, p->regno, v->h_val, v->l_val);
+			ret = SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
+				p->regno, v->h_val, v->l_val);
+			if (ret < 0) {
+				LINE_ERR(xpd, pos,
+					"Failed: 0x%02X: I 0x%02X, 0x%02X\n",
+					p->regno, v->h_val, v->l_val);
+				break;
+			}
+		} else {
+			LINE_DBG(REGS, xpd, pos, "[%d] 0x%02X: D 0x%02X\n",
+				i, p->regno, v->l_val);
+			ret = SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
+				p->regno, v->l_val);
+			if (ret < 0) {
+				LINE_ERR(xpd, pos,
+					"Failed: 0x%02X: D 0x%02X\n",
+					p->regno, v->l_val);
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
 static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
 			   unsigned int msg_waiting)
 {
@@ -667,81 +756,15 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
 		/* A write to register 0x40 will now turn on/off the VM led */
 		LINE_DBG(SIGNAL, xpd, pos, "NEON\n");
 		BIT_SET(priv->neon_blinking, pos);
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16,
-					  0xE8, 0x03);
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15,
-					  0xEF, 0x7B);
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14,
-					  0x9F, 0x00);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x22, 0x19);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x30, 0xE0);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x31, 0x01);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x32, 0xF0);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x33, 0x05);
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x1D,
-					  0x00, 0x46);
+		ret = send_ring_parameters(xbus, xpd, pos, RING_TYPE_NEON);
 	} else if (ring_trapez) {
 		LINE_DBG(SIGNAL, xpd, pos, "RINGER: Trapez ring\n");
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16,
-					  0xC8, 0x00);
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15,
-					  0xAB, 0x5E);
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14,
-					  0x8C, 0x01);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x22, 0x01);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x4A, 0x34);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x30, 0x00);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x31, 0x00);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x32, 0x00);
-		ret +=
-		    SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x33, 0x00);
-		ret +=
-		    SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x1D,
-					  0x00, 0x36);
+		ret = send_ring_parameters(xbus, xpd, pos, RING_TYPE_TRAPEZ);
 	} else {
 		/* A write to register 0x40 will now turn on/off the ringer */
 		LINE_DBG(SIGNAL, xpd, pos, "RINGER\n");
 		BIT_CLR(priv->neon_blinking, pos);
-
-		ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x16, 0x00, 0x00);
-		ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x15, 0x77, 0x01);
-		ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x14, 0xFD, 0x7E);
-
-		ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x22, 0x00);
-		ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x30, 0x00);
-		ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x31, 0x00);
-		ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x32, 0x00);
-		ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x33, 0x00);
-		/* High Vbat~ -82V[Dc] */
-		ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x4A, 0x34);
-		ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
-			0x1D, 0x00, 0x36);
+		ret = send_ring_parameters(xbus, xpd, pos, RING_TYPE_NORMAL);
 	}
 	return (ret ? -EPROTO : 0);
 }
diff --git a/drivers/dahdi/xpp/init_card_1_30 b/drivers/dahdi/xpp/init_card_1_30
index 2d6fd13..d64a50e 100755
--- a/drivers/dahdi/xpp/init_card_1_30
+++ b/drivers/dahdi/xpp/init_card_1_30
@@ -298,7 +298,7 @@ sub init_early_direct_regs() {
 	return write_to_slic_file("#
 *	WD	08	00	# Audio Path Loopback Control
 *	WD	6C	01
-*	WD	4A	3F	# High Battery Voltage
+*	WD	4A	34	# High Battery Voltage
 *	WD	4B	$lbv	# Low Battery Voltage
 *	WD	49	$vcm	# Common Mode Voltage (VCM)
 *	WD	40	00	# Line Feed Control

-----------------------------------------------------------------------


-- 
dahdi/linux.git



More information about the dahdi-commits mailing list