board/freescale/common: VSC3316/VSC3308 initialization code
authorShaveta Leekha <shaveta@freescale.com>
Mon, 8 Oct 2012 07:44:17 +0000 (07:44 +0000)
committerAndy Fleming <afleming@freescale.com>
Mon, 22 Oct 2012 19:31:21 +0000 (14:31 -0500)
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>
Signed-off-by: Andy Fleming <afleming@freescale.com>
board/freescale/common/Makefile
board/freescale/common/vsc3316_3308.c [new file with mode: 0644]
board/freescale/common/vsc3316_3308.h [new file with mode: 0644]
doc/README.VSC3316-3308 [new file with mode: 0644]

index 54cb098a9159d54ef51f54202bf14541388dbbc1..36f7c4f30f4965e20bad362753c908fcfce90945 100644 (file)
@@ -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 (file)
index 0000000..7868565
--- /dev/null
@@ -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 (file)
index 0000000..effd66d
--- /dev/null
@@ -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 (file)
index 0000000..925663b
--- /dev/null
@@ -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.