Patchwork [U-Boot,14/28] board/freescale/common: VSC3316/VSC3308 initialization code

login
register
mail settings
Submitter York Sun
Date Oct. 8, 2012, 5:44 p.m.
Message ID <1349718271-26503-14-git-send-email-yorksun@freescale.com>
Download mbox | patch
Permalink /patch/190084/
State Accepted, archived
Delegated to: Andy Fleming
Headers show

Comments

York Sun - Oct. 8, 2012, 5:44 p.m.
From: Shaveta Leekha <shaveta@freescale.com>

Add code for configuring VSC3316/3308 crosspoint switches
Add README to understand the APIs

   - VSC 3316/3308 is a low-power, low-cost asynchronous crosspoint switch
     capable of data rates upto 11.5Gbps. VSC3316 has 16 input and 16
     output ports whereas VSC3308 has 8 input and 8 output ports.
     Programming of these devices are performed by two-wire or four-wire
     serial interface.

Signed-off-by: Shaveta Leekha <shaveta@freescale.com>
---
 board/freescale/common/Makefile       |    1 +
 board/freescale/common/vsc3316_3308.c |  184 +++++++++++++++++++++++++++++++++
 board/freescale/common/vsc3316_3308.h |   34 ++++++
 doc/README.VSC3316-3308               |   43 ++++++++
 4 files changed, 262 insertions(+)
 create mode 100644 board/freescale/common/vsc3316_3308.c
 create mode 100644 board/freescale/common/vsc3316_3308.h
 create mode 100644 doc/README.VSC3316-3308

Patch

diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index 54cb098..36f7c4f 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -53,6 +53,7 @@  COBJS-$(CONFIG_P2020DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P3041DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P4080DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P5020DS)		+= ics307_clk.o
+COBJS-$(CONFIG_VSC_CROSSBAR)    += vsc3316_3308.o
 
 # deal with common files for P-series corenet based devices
 SUBLIB-$(CONFIG_P2041RDB)	+= p_corenet/libp_corenet.o
diff --git a/board/freescale/common/vsc3316_3308.c b/board/freescale/common/vsc3316_3308.c
new file mode 100644
index 0000000..7868565
--- /dev/null
+++ b/board/freescale/common/vsc3316_3308.c
@@ -0,0 +1,184 @@ 
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "vsc3316_3308.h"
+
+#define REVISION_ID_REG		0x7E
+#define INTERFACE_MODE_REG		0x79
+#define CURRENT_PAGE_REGISTER		0x7F
+#define CONNECTION_CONFIG_PAGE		0x00
+#define INPUT_STATE_REG		0x13
+#define GLOBAL_INPUT_ISE1		0x51
+#define GLOBAL_INPUT_ISE2		0x52
+#define GLOBAL_INPUT_LOS		0x55
+#define GLOBAL_CORE_CNTRL		0x5D
+#define OUTPUT_MODE_PAGE		0x23
+#define CORE_CONTROL_PAGE		0x25
+#define CORE_CONFIG_REG		0x75
+
+int vsc_if_enable(unsigned int vsc_addr)
+{
+	u8 data;
+
+	debug("VSC:Configuring VSC at I2C address 0x%2x"
+			" for 2-wire interface\n", vsc_addr);
+
+	/* enable 2-wire Serial InterFace (I2C) */
+	data = 0x02;
+	return i2c_write(vsc_addr, INTERFACE_MODE_REG, 1, &data, 1);
+}
+
+int vsc3316_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+		unsigned int num_con)
+{
+	unsigned int i;
+	u8 rev_id = 0;
+	int ret;
+
+	debug("VSC:Initializing VSC3316 at I2C address 0x%2x"
+		" for Tx\n", vsc_addr);
+
+	ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
+	if (ret < 0) {
+		printf("VSC:0x%x could not read REV_ID from device.\n",
+			vsc_addr);
+		return ret;
+	}
+
+	if (rev_id != 0xab) {
+		printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
+			vsc_addr);
+		return -ENODEV;
+	}
+
+	ret = vsc_if_enable(vsc_addr);
+	if (ret) {
+		printf("VSC:0x%x could not configured for 2-wire I/F.\n",
+			vsc_addr);
+		return ret;
+	}
+
+	/* config connections - page 0x00 */
+	i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
+
+	/* Making crosspoint connections, by connecting required
+	 * input to output */
+	for (i = 0; i < num_con ; i++)
+		i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]);
+
+	/* input state - page 0x13 */
+	i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
+	/* Configuring the required input of the switch */
+	for (i = 0; i < num_con ; i++)
+		i2c_reg_write(vsc_addr, con_arr[i][0], 0x80);
+
+	/* Setting Global Input LOS threshold value */
+	i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60);
+
+	/* config output mode - page 0x23 */
+	i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
+	/* Turn ON the Output driver correspond to required output*/
+	for (i = 0; i < num_con ; i++)
+		i2c_reg_write(vsc_addr,  con_arr[i][1], 0);
+
+	/* configure global core control register, Turn on Global core power */
+	i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
+
+	vsc_wp_config(vsc_addr);
+
+	return 0;
+}
+
+int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+		unsigned int num_con)
+{
+	unsigned int i;
+	u8 rev_id = 0;
+	int ret;
+
+	debug("VSC:Initializing VSC3308 at I2C address 0x%x"
+		" for Tx\n", vsc_addr);
+
+	ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
+	if (ret < 0) {
+		printf("VSC:0x%x could not read REV_ID from device.\n",
+			vsc_addr);
+		return ret;
+	}
+
+	if (rev_id != 0xab) {
+		printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
+			vsc_addr);
+		return -ENODEV;
+	}
+
+	ret = vsc_if_enable(vsc_addr);
+	if (ret) {
+		printf("VSC:0x%x could not configured for 2-wire I/F.\n",
+			vsc_addr);
+		return ret;
+	}
+
+	/* config connections - page 0x00 */
+	i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
+
+	/* Making crosspoint connections, by connecting required
+	 * input to output */
+	for (i = 0; i < num_con ; i++)
+		i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]);
+
+	/*Configure Global Input ISE and gain */
+	i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE1, 0x12);
+	i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE2, 0x12);
+
+	/* input state - page 0x13 */
+	i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
+	/* Turning ON the required input of the switch */
+	for (i = 0; i < num_con ; i++)
+		i2c_reg_write(vsc_addr, con_arr[i][0], 0);
+
+	/* Setting Global Input LOS threshold value */
+	i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60);
+
+	/* config output mode - page 0x23 */
+	i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
+	/* Turn ON the Output driver correspond to required output*/
+	for (i = 0; i < num_con ; i++)
+		i2c_reg_write(vsc_addr,  con_arr[i][1], 0);
+
+	/* configure global core control register, Turn on Global core power */
+	i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
+
+	vsc_wp_config(vsc_addr);
+
+	return 0;
+}
+
+void vsc_wp_config(unsigned int vsc_addr)
+{
+	debug("VSC:Configuring VSC at address:0x%x for WP\n", vsc_addr);
+
+	/* For new crosspoint configuration to occur, WP bit of
+	 * CORE_CONFIG_REG should be set 1 and then reset to 0 */
+	i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x01);
+	i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x0);
+}
diff --git a/board/freescale/common/vsc3316_3308.h b/board/freescale/common/vsc3316_3308.h
new file mode 100644
index 0000000..effd66d
--- /dev/null
+++ b/board/freescale/common/vsc3316_3308.h
@@ -0,0 +1,34 @@ 
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __VSC_CROSSBAR_H_
+#define __VSC_CROSSBAR_H	1_
+
+#include <common.h>
+#include <i2c.h>
+#include <errno.h>
+
+int vsc_if_enable(unsigned int vsc_addr);
+int vsc3316_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+		unsigned int num_con);
+int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
+		unsigned int num_con);
+void vsc_wp_config(unsigned int vsc_addr);
+
+#endif	/* __VSC_CROSSBAR_H_ */
diff --git a/doc/README.VSC3316-3308 b/doc/README.VSC3316-3308
new file mode 100644
index 0000000..925663b
--- /dev/null
+++ b/doc/README.VSC3316-3308
@@ -0,0 +1,43 @@ 
+This file contains API information of the initialization code written for
+Vitesse cross-point devices, VSC3316 and VSC3308 for board B4860QDS
+
+Author: Shaveta Leekha <shaveta@freescale.com>
+
+About Device:
+=============
+VSC 3316/3308 is a low-power, low-cost asynchronous crosspoint switch capable of data rates upto 11.5Gbps.
+
+VSC3316 has 16 input and 16 output ports whereas VSC3308 has 8 input and 8 output ports. Programming of these devices are performed by two-wire or four-wire serial interface.
+
+Initialization:
+===============
+On reset, VSC devices are in low-power state with all inputs, outputs and connections in an off state.
+First thing required is to program it to interface with either two-wire or four-wire interface.
+In our case the interface is two-wire I2C serial interface. So the value in Interface mode register at address 79.h to be written is 0x02 for two-wire interface. Also for crosspoint connections to be activated, 01.h value need to be written in 75.h (core configuration register).
+
+API Overview:
+=============
+
+	vsc_if_enable(u8 vsc_addr):
+	--------------------------
+		This API programs VSC to interface with either two-wire or four-wire interface. In our case the interface is two-wire I2C serial interface. So the value in Interface mode register at address 79.h to be written is 0x02 for two-wire interface.
+	Parameters:
+		vsc_addr - Address of the VSC device on board.
+
+
+	vsc3316_config(u8 vsc_addr, int con_arr[][2], u8 num_con):
+	---------------------------------------------------------
+	This API configures the VSC3316 device for required connections. Connection through the VSC device requires the inputs and outputs to be properly configured.
+	Connection registers are on page 00. It Configures the selected input and output correctly and join them to make a connection. It also program Input state register, Global input ISE, Global input LOS, Global core control, Output mode register and core control registers etc.
+	vsc3308_config(u8 vsc_addr, int con_arr[][2], u8 num_con) does the essential configurations for VSC3308.
+
+	Parameters:
+		vsc_addr - Address of the VSC device on board.
+		con_arr - connection array
+		num_con - number of connections to be configured
+
+	vsc_wp_config(u8 vsc_addr):
+	--------------------------
+		For crosspoint connections to be activated, 01.h value need to be written in 75.h (core configuration register), which is done by this API.
+	Parameters:
+		vsc_addr - Address of the VSC device on board.