[svn-commits] mogorman: trunk r1787 - /trunk/ztcodec_dte.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Fri Jan 5 16:32:57 MST 2007


Author: mogorman
Date: Fri Jan  5 17:32:56 2007
New Revision: 1787

URL: http://svn.digium.com/view/zaptel?view=rev&rev=1787
Log:
this allows transcoder card to work with newest revision of the card
if you have the older revision do not upgrade or this will break you.
patch provided by john sloan

Modified:
    trunk/ztcodec_dte.c

Modified: trunk/ztcodec_dte.c
URL: http://svn.digium.com/view/zaptel/trunk/ztcodec_dte.c?view=diff&rev=1787&r1=1786&r2=1787
==============================================================================
--- trunk/ztcodec_dte.c (original)
+++ trunk/ztcodec_dte.c Fri Jan  5 17:32:56 2007
@@ -98,7 +98,12 @@
 
 #define PCI_WINDOW_SIZE ((2*  2 * ERING_SIZE * SFRAME_SIZE) + (2 * ERING_SIZE * 4))
 
-
+#define MDIO_SHIFT_CLK		0x10000
+#define MDIO_DATA_WRITE0 	0x00000
+#define MDIO_DATA_WRITE1 	0x20000
+#define MDIO_ENB		0x00000
+#define MDIO_ENB_IN		0x40000
+#define MDIO_DATA_READ		0x80000
 
 #define RCV_CSMENCAPS     1
 #define RCV_RTP           2
@@ -1188,12 +1193,86 @@
 }
 
 
+static int wcdte_read_phy(struct wcdte *wc, int location)
+{
+	int i;
+	long mdio_addr = 0x0048;
+	int read_cmd = (0xf6 << 10) | (1 << 5) | location;
+	int retval = 0;
+
+	/* Establish sync by sending at least 32 logic ones. */
+	for (i = 32; i >= 0; i--) {
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1);
+		wcdte_getctl(wc, mdio_addr);
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK);
+		wcdte_getctl(wc, mdio_addr);
+	}
+	/* Shift the read command bits out. */
+	for (i = 17; i >= 0; i--) {
+		int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval);
+		wcdte_getctl(wc, mdio_addr);
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK);
+		wcdte_getctl(wc, mdio_addr);
+	}
+
+	/* Read the two transition, 16 data, and wire-idle bits. */
+	for (i = 19; i > 0; i--) {
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN);
+		wcdte_getctl(wc, mdio_addr);
+		retval = (retval << 1) | ((wcdte_getctl(wc, mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK);
+		wcdte_getctl(wc, mdio_addr);
+	}
+	retval = (retval>>1) & 0xffff;
+	return retval;
+}
+
+
+void wcdte_write_phy(struct wcdte *wc, int location, int value)
+{
+	int i;
+	int cmd = (0x5002 << 16) | (1 << 23) | (location<<18) | value;
+	long mdio_addr = 0x0048;
+
+	/* Establish sync by sending 32 logic ones. */
+	for (i = 32; i >= 0; i--) {
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1);
+		wcdte_getctl(wc, mdio_addr);
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK);
+		wcdte_getctl(wc, mdio_addr);
+	}
+	/* Shift the command bits out. */
+	for (i = 31; i >= 0; i--) {
+		int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval);
+		wcdte_getctl(wc, mdio_addr);
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK);
+		wcdte_getctl(wc, mdio_addr);
+	}
+	/* Clear out extra bits. */
+	for (i = 2; i > 0; i--) {
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN);
+		wcdte_getctl(wc, mdio_addr);
+		wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK);
+		wcdte_getctl(wc, mdio_addr);
+	}
+	return;
+}
+
+
 static int wcdte_boot_processor(struct wcdte *wc)	
 {
 	int i, j, byteloc, last_byteloc, length, delay_count;
 	unsigned int reg, ret;
 
 #ifndef USE_TEST_HW
+	/* Turn off auto negotiation */
+	wcdte_write_phy(wc, 0, 0x2100);
+	if (debug)
+		printk("wcdte: PHY register 0 = %X", wcdte_read_phy(wc, 0));
+	
 	/* Set reset */
 	wcdte_setctl(wc, 0x00A0, 0x04000000);
 



More information about the svn-commits mailing list