diff options
Diffstat (limited to 'board/freescale/common/vsc3316_3308.c')
-rw-r--r-- | board/freescale/common/vsc3316_3308.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/board/freescale/common/vsc3316_3308.c b/board/freescale/common/vsc3316_3308.c index 97a25e838e..dd9c37ebe8 100644 --- a/board/freescale/common/vsc3316_3308.c +++ b/board/freescale/common/vsc3316_3308.c @@ -13,7 +13,12 @@ #define INPUT_STATE_REG 0x13 #define GLOBAL_INPUT_ISE1 0x51 #define GLOBAL_INPUT_ISE2 0x52 +#define GLOBAL_INPUT_GAIN 0x53 #define GLOBAL_INPUT_LOS 0x55 +#define GLOBAL_OUTPUT_PE1 0x56 +#define GLOBAL_OUTPUT_PE2 0x57 +#define GLOBAL_OUTPUT_LEVEL 0x58 +#define GLOBAL_OUTPUT_TERMINATION 0x5A #define GLOBAL_CORE_CNTRL 0x5D #define OUTPUT_MODE_PAGE 0x23 #define CORE_CONTROL_PAGE 0x25 @@ -92,6 +97,109 @@ int vsc3316_config(unsigned int vsc_addr, int8_t con_arr[][2], return 0; } +#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR +int vsc3308_config_adjust(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); + + /* Configure Global Input ISE */ + i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE1, 0); + i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE2, 0); + + /* Configure Tx/Rx Global Output PE1 */ + i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_PE1, 0); + + /* Configure Tx/Rx Global Output PE2 */ + i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_PE2, 0); + + /* Configure Tx/Rx Global Input GAIN */ + i2c_reg_write(vsc_addr, GLOBAL_INPUT_GAIN, 0x3F); + + /* Setting Global Input LOS threshold value */ + i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0xE0); + + /* Setting Global output termination */ + i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_TERMINATION, 0); + + /* Configure Tx/Rx Global Output level */ + if (vsc_addr == VSC3308_TX_ADDRESS) + i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_LEVEL, 4); + else + i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_LEVEL, 2); + + /* 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); + /* Turning off all the required input of the switch */ + for (i = 0; i < num_con; i++) + i2c_reg_write(vsc_addr, con_arr[i][0], 1); + + /* only turn on specific Tx/Rx requested by the XFI erratum */ + if (vsc_addr == VSC3308_TX_ADDRESS) { + i2c_reg_write(vsc_addr, 2, 0); + i2c_reg_write(vsc_addr, 3, 0); + } else { + i2c_reg_write(vsc_addr, 0, 0); + i2c_reg_write(vsc_addr, 1, 0); + } + + /* config output mode - page 0x23 */ + i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE); + /* Turn off the Output driver correspond to required output*/ + for (i = 0; i < num_con ; i++) + i2c_reg_write(vsc_addr, con_arr[i][1], 1); + + /* only turn on specific Tx/Rx requested by the XFI erratum */ + if (vsc_addr == VSC3308_TX_ADDRESS) { + i2c_reg_write(vsc_addr, 0, 0); + i2c_reg_write(vsc_addr, 1, 0); + } else { + i2c_reg_write(vsc_addr, 3, 0); + i2c_reg_write(vsc_addr, 4, 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; +} +#endif + int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2], unsigned int num_con) { |