1aa42cb71SShaveta Leekha /* 2aa42cb71SShaveta Leekha * Copyright 2012 Freescale Semiconductor, Inc. 3aa42cb71SShaveta Leekha * 4*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 5aa42cb71SShaveta Leekha */ 6aa42cb71SShaveta Leekha 7aa42cb71SShaveta Leekha #include "vsc3316_3308.h" 8aa42cb71SShaveta Leekha 9aa42cb71SShaveta Leekha #define REVISION_ID_REG 0x7E 10aa42cb71SShaveta Leekha #define INTERFACE_MODE_REG 0x79 11aa42cb71SShaveta Leekha #define CURRENT_PAGE_REGISTER 0x7F 12aa42cb71SShaveta Leekha #define CONNECTION_CONFIG_PAGE 0x00 13aa42cb71SShaveta Leekha #define INPUT_STATE_REG 0x13 14aa42cb71SShaveta Leekha #define GLOBAL_INPUT_ISE1 0x51 15aa42cb71SShaveta Leekha #define GLOBAL_INPUT_ISE2 0x52 16aa42cb71SShaveta Leekha #define GLOBAL_INPUT_LOS 0x55 17aa42cb71SShaveta Leekha #define GLOBAL_CORE_CNTRL 0x5D 18aa42cb71SShaveta Leekha #define OUTPUT_MODE_PAGE 0x23 19aa42cb71SShaveta Leekha #define CORE_CONTROL_PAGE 0x25 20aa42cb71SShaveta Leekha #define CORE_CONFIG_REG 0x75 21aa42cb71SShaveta Leekha 22aa42cb71SShaveta Leekha int vsc_if_enable(unsigned int vsc_addr) 23aa42cb71SShaveta Leekha { 24aa42cb71SShaveta Leekha u8 data; 25aa42cb71SShaveta Leekha 26aa42cb71SShaveta Leekha debug("VSC:Configuring VSC at I2C address 0x%2x" 27aa42cb71SShaveta Leekha " for 2-wire interface\n", vsc_addr); 28aa42cb71SShaveta Leekha 29aa42cb71SShaveta Leekha /* enable 2-wire Serial InterFace (I2C) */ 30aa42cb71SShaveta Leekha data = 0x02; 31aa42cb71SShaveta Leekha return i2c_write(vsc_addr, INTERFACE_MODE_REG, 1, &data, 1); 32aa42cb71SShaveta Leekha } 33aa42cb71SShaveta Leekha 34aa42cb71SShaveta Leekha int vsc3316_config(unsigned int vsc_addr, const int8_t con_arr[][2], 35aa42cb71SShaveta Leekha unsigned int num_con) 36aa42cb71SShaveta Leekha { 37aa42cb71SShaveta Leekha unsigned int i; 38aa42cb71SShaveta Leekha u8 rev_id = 0; 39aa42cb71SShaveta Leekha int ret; 40aa42cb71SShaveta Leekha 41aa42cb71SShaveta Leekha debug("VSC:Initializing VSC3316 at I2C address 0x%2x" 42aa42cb71SShaveta Leekha " for Tx\n", vsc_addr); 43aa42cb71SShaveta Leekha 44aa42cb71SShaveta Leekha ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1); 45aa42cb71SShaveta Leekha if (ret < 0) { 46aa42cb71SShaveta Leekha printf("VSC:0x%x could not read REV_ID from device.\n", 47aa42cb71SShaveta Leekha vsc_addr); 48aa42cb71SShaveta Leekha return ret; 49aa42cb71SShaveta Leekha } 50aa42cb71SShaveta Leekha 51aa42cb71SShaveta Leekha if (rev_id != 0xab) { 52aa42cb71SShaveta Leekha printf("VSC: device at address 0x%x is not VSC3316/3308.\n", 53aa42cb71SShaveta Leekha vsc_addr); 54aa42cb71SShaveta Leekha return -ENODEV; 55aa42cb71SShaveta Leekha } 56aa42cb71SShaveta Leekha 57aa42cb71SShaveta Leekha ret = vsc_if_enable(vsc_addr); 58aa42cb71SShaveta Leekha if (ret) { 59aa42cb71SShaveta Leekha printf("VSC:0x%x could not configured for 2-wire I/F.\n", 60aa42cb71SShaveta Leekha vsc_addr); 61aa42cb71SShaveta Leekha return ret; 62aa42cb71SShaveta Leekha } 63aa42cb71SShaveta Leekha 64aa42cb71SShaveta Leekha /* config connections - page 0x00 */ 65aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE); 66aa42cb71SShaveta Leekha 67aa42cb71SShaveta Leekha /* Making crosspoint connections, by connecting required 68aa42cb71SShaveta Leekha * input to output */ 69aa42cb71SShaveta Leekha for (i = 0; i < num_con ; i++) 70aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]); 71aa42cb71SShaveta Leekha 72aa42cb71SShaveta Leekha /* input state - page 0x13 */ 73aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG); 74aa42cb71SShaveta Leekha /* Configuring the required input of the switch */ 75aa42cb71SShaveta Leekha for (i = 0; i < num_con ; i++) 76aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, con_arr[i][0], 0x80); 77aa42cb71SShaveta Leekha 78aa42cb71SShaveta Leekha /* Setting Global Input LOS threshold value */ 79aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60); 80aa42cb71SShaveta Leekha 81aa42cb71SShaveta Leekha /* config output mode - page 0x23 */ 82aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE); 83aa42cb71SShaveta Leekha /* Turn ON the Output driver correspond to required output*/ 84aa42cb71SShaveta Leekha for (i = 0; i < num_con ; i++) 85aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, con_arr[i][1], 0); 86aa42cb71SShaveta Leekha 87aa42cb71SShaveta Leekha /* configure global core control register, Turn on Global core power */ 88aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0); 89aa42cb71SShaveta Leekha 90aa42cb71SShaveta Leekha vsc_wp_config(vsc_addr); 91aa42cb71SShaveta Leekha 92aa42cb71SShaveta Leekha return 0; 93aa42cb71SShaveta Leekha } 94aa42cb71SShaveta Leekha 95aa42cb71SShaveta Leekha int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2], 96aa42cb71SShaveta Leekha unsigned int num_con) 97aa42cb71SShaveta Leekha { 98aa42cb71SShaveta Leekha unsigned int i; 99aa42cb71SShaveta Leekha u8 rev_id = 0; 100aa42cb71SShaveta Leekha int ret; 101aa42cb71SShaveta Leekha 102aa42cb71SShaveta Leekha debug("VSC:Initializing VSC3308 at I2C address 0x%x" 103aa42cb71SShaveta Leekha " for Tx\n", vsc_addr); 104aa42cb71SShaveta Leekha 105aa42cb71SShaveta Leekha ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1); 106aa42cb71SShaveta Leekha if (ret < 0) { 107aa42cb71SShaveta Leekha printf("VSC:0x%x could not read REV_ID from device.\n", 108aa42cb71SShaveta Leekha vsc_addr); 109aa42cb71SShaveta Leekha return ret; 110aa42cb71SShaveta Leekha } 111aa42cb71SShaveta Leekha 112aa42cb71SShaveta Leekha if (rev_id != 0xab) { 113aa42cb71SShaveta Leekha printf("VSC: device at address 0x%x is not VSC3316/3308.\n", 114aa42cb71SShaveta Leekha vsc_addr); 115aa42cb71SShaveta Leekha return -ENODEV; 116aa42cb71SShaveta Leekha } 117aa42cb71SShaveta Leekha 118aa42cb71SShaveta Leekha ret = vsc_if_enable(vsc_addr); 119aa42cb71SShaveta Leekha if (ret) { 120aa42cb71SShaveta Leekha printf("VSC:0x%x could not configured for 2-wire I/F.\n", 121aa42cb71SShaveta Leekha vsc_addr); 122aa42cb71SShaveta Leekha return ret; 123aa42cb71SShaveta Leekha } 124aa42cb71SShaveta Leekha 125aa42cb71SShaveta Leekha /* config connections - page 0x00 */ 126aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE); 127aa42cb71SShaveta Leekha 128aa42cb71SShaveta Leekha /* Making crosspoint connections, by connecting required 129aa42cb71SShaveta Leekha * input to output */ 130aa42cb71SShaveta Leekha for (i = 0; i < num_con ; i++) 131aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]); 132aa42cb71SShaveta Leekha 133aa42cb71SShaveta Leekha /*Configure Global Input ISE and gain */ 134aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE1, 0x12); 135aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE2, 0x12); 136aa42cb71SShaveta Leekha 137aa42cb71SShaveta Leekha /* input state - page 0x13 */ 138aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG); 139aa42cb71SShaveta Leekha /* Turning ON the required input of the switch */ 140aa42cb71SShaveta Leekha for (i = 0; i < num_con ; i++) 141aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, con_arr[i][0], 0); 142aa42cb71SShaveta Leekha 143aa42cb71SShaveta Leekha /* Setting Global Input LOS threshold value */ 144aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60); 145aa42cb71SShaveta Leekha 146aa42cb71SShaveta Leekha /* config output mode - page 0x23 */ 147aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE); 148aa42cb71SShaveta Leekha /* Turn ON the Output driver correspond to required output*/ 149aa42cb71SShaveta Leekha for (i = 0; i < num_con ; i++) 150aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, con_arr[i][1], 0); 151aa42cb71SShaveta Leekha 152aa42cb71SShaveta Leekha /* configure global core control register, Turn on Global core power */ 153aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0); 154aa42cb71SShaveta Leekha 155aa42cb71SShaveta Leekha vsc_wp_config(vsc_addr); 156aa42cb71SShaveta Leekha 157aa42cb71SShaveta Leekha return 0; 158aa42cb71SShaveta Leekha } 159aa42cb71SShaveta Leekha 160aa42cb71SShaveta Leekha void vsc_wp_config(unsigned int vsc_addr) 161aa42cb71SShaveta Leekha { 162aa42cb71SShaveta Leekha debug("VSC:Configuring VSC at address:0x%x for WP\n", vsc_addr); 163aa42cb71SShaveta Leekha 164aa42cb71SShaveta Leekha /* For new crosspoint configuration to occur, WP bit of 165aa42cb71SShaveta Leekha * CORE_CONFIG_REG should be set 1 and then reset to 0 */ 166aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x01); 167aa42cb71SShaveta Leekha i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x0); 168aa42cb71SShaveta Leekha } 169