1*48c6a6b6SBharat Gooty /* 2*48c6a6b6SBharat Gooty * Copyright (c) 2016 - 2021, Broadcom 3*48c6a6b6SBharat Gooty * 4*48c6a6b6SBharat Gooty * SPDX-License-Identifier: BSD-3-Clause 5*48c6a6b6SBharat Gooty */ 6*48c6a6b6SBharat Gooty 7*48c6a6b6SBharat Gooty #include <common/debug.h> 8*48c6a6b6SBharat Gooty #include <drivers/delay_timer.h> 9*48c6a6b6SBharat Gooty #include <i2c.h> 10*48c6a6b6SBharat Gooty #include <i2c_regs.h> 11*48c6a6b6SBharat Gooty #include <lib/mmio.h> 12*48c6a6b6SBharat Gooty 13*48c6a6b6SBharat Gooty #include <platform_def.h> 14*48c6a6b6SBharat Gooty 15*48c6a6b6SBharat Gooty /* Max instances */ 16*48c6a6b6SBharat Gooty #define MAX_I2C 2U 17*48c6a6b6SBharat Gooty 18*48c6a6b6SBharat Gooty /* Transaction error codes defined in Master command register (0x30) */ 19*48c6a6b6SBharat Gooty #define MSTR_STS_XACT_SUCCESS 0U 20*48c6a6b6SBharat Gooty #define MSTR_STS_LOST_ARB 1U 21*48c6a6b6SBharat Gooty #define MSTR_STS_NACK_FIRST_BYTE 2U 22*48c6a6b6SBharat Gooty /* NACK on a byte other than the first byte */ 23*48c6a6b6SBharat Gooty #define MSTR_STS_NACK_NON_FIRST_BYTE 3U 24*48c6a6b6SBharat Gooty 25*48c6a6b6SBharat Gooty #define MSTR_STS_TTIMEOUT_EXCEEDED 4U 26*48c6a6b6SBharat Gooty #define MSTR_STS_TX_TLOW_MEXT_EXCEEDED 5U 27*48c6a6b6SBharat Gooty #define MSTR_STS_RX_TLOW_MEXT_EXCEEDED 6U 28*48c6a6b6SBharat Gooty 29*48c6a6b6SBharat Gooty /* SMBUS protocol values defined in register 0x30 */ 30*48c6a6b6SBharat Gooty #define SMBUS_PROT_QUICK_CMD 0U 31*48c6a6b6SBharat Gooty #define SMBUS_PROT_SEND_BYTE 1U 32*48c6a6b6SBharat Gooty #define SMBUS_PROT_RECV_BYTE 2U 33*48c6a6b6SBharat Gooty #define SMBUS_PROT_WR_BYTE 3U 34*48c6a6b6SBharat Gooty #define SMBUS_PROT_RD_BYTE 4U 35*48c6a6b6SBharat Gooty #define SMBUS_PROT_WR_WORD 5U 36*48c6a6b6SBharat Gooty #define SMBUS_PROT_RD_WORD 6U 37*48c6a6b6SBharat Gooty #define SMBUS_PROT_BLK_WR 7U 38*48c6a6b6SBharat Gooty #define SMBUS_PROT_BLK_RD 8U 39*48c6a6b6SBharat Gooty #define SMBUS_PROT_PROC_CALL 9U 40*48c6a6b6SBharat Gooty #define SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL 10U 41*48c6a6b6SBharat Gooty 42*48c6a6b6SBharat Gooty /* Number can be changed later */ 43*48c6a6b6SBharat Gooty #define BUS_BUSY_COUNT 100000U 44*48c6a6b6SBharat Gooty 45*48c6a6b6SBharat Gooty #define IPROC_I2C_INVALID_ADDR 0xFFU 46*48c6a6b6SBharat Gooty 47*48c6a6b6SBharat Gooty #define I2C_SMBUS_BLOCK_MAX 32U 48*48c6a6b6SBharat Gooty 49*48c6a6b6SBharat Gooty /* 50*48c6a6b6SBharat Gooty * Enum to specify clock speed. The user will provide it during initialization. 51*48c6a6b6SBharat Gooty * If needed, it can be changed dynamically 52*48c6a6b6SBharat Gooty */ 53*48c6a6b6SBharat Gooty typedef enum iproc_smb_clk_freq { 54*48c6a6b6SBharat Gooty IPROC_SMB_SPEED_100KHz = 0, 55*48c6a6b6SBharat Gooty IPROC_SMB_SPEED_400KHz = 1, 56*48c6a6b6SBharat Gooty IPROC_SMB_SPEED_INVALID = 255 57*48c6a6b6SBharat Gooty } smb_clk_freq_t; 58*48c6a6b6SBharat Gooty 59*48c6a6b6SBharat Gooty /* Structure used to pass information to read/write functions. */ 60*48c6a6b6SBharat Gooty struct iproc_xact_info { 61*48c6a6b6SBharat Gooty /* Bus Identifier */ 62*48c6a6b6SBharat Gooty uint32_t bus_id; 63*48c6a6b6SBharat Gooty /* Device Address */ 64*48c6a6b6SBharat Gooty uint8_t devaddr; 65*48c6a6b6SBharat Gooty /* Passed by caller to send SMBus command cod e*/ 66*48c6a6b6SBharat Gooty uint8_t command; 67*48c6a6b6SBharat Gooty /* actual data passed by the caller */ 68*48c6a6b6SBharat Gooty uint8_t *data; 69*48c6a6b6SBharat Gooty /* Size of data buffer passed */ 70*48c6a6b6SBharat Gooty uint32_t size; 71*48c6a6b6SBharat Gooty /* Sent by caller specifying PEC, 10-bit addresses */ 72*48c6a6b6SBharat Gooty uint16_t flags; 73*48c6a6b6SBharat Gooty /* SMBus protocol to use to perform transaction */ 74*48c6a6b6SBharat Gooty uint8_t smb_proto; 75*48c6a6b6SBharat Gooty /* true if command field below is valid. Otherwise, false */ 76*48c6a6b6SBharat Gooty uint32_t cmd_valid; 77*48c6a6b6SBharat Gooty }; 78*48c6a6b6SBharat Gooty 79*48c6a6b6SBharat Gooty static const uintptr_t smbus_base_reg_addr[MAX_I2C] = { 80*48c6a6b6SBharat Gooty SMBUS0_REGS_BASE, 81*48c6a6b6SBharat Gooty SMBUS1_REGS_BASE 82*48c6a6b6SBharat Gooty }; 83*48c6a6b6SBharat Gooty 84*48c6a6b6SBharat Gooty /* Function to read a value from specified register. */ 85*48c6a6b6SBharat Gooty static uint32_t iproc_i2c_reg_read(uint32_t bus_id, unsigned long reg_addr) 86*48c6a6b6SBharat Gooty { 87*48c6a6b6SBharat Gooty uint32_t val; 88*48c6a6b6SBharat Gooty uintptr_t smbus; 89*48c6a6b6SBharat Gooty 90*48c6a6b6SBharat Gooty smbus = smbus_base_reg_addr[bus_id]; 91*48c6a6b6SBharat Gooty 92*48c6a6b6SBharat Gooty val = mmio_read_32(smbus + reg_addr); 93*48c6a6b6SBharat Gooty VERBOSE("i2c %u: reg %p read 0x%x\n", bus_id, 94*48c6a6b6SBharat Gooty (void *)(smbus + reg_addr), val); 95*48c6a6b6SBharat Gooty return val; 96*48c6a6b6SBharat Gooty } 97*48c6a6b6SBharat Gooty 98*48c6a6b6SBharat Gooty /* Function to write a value ('val') in to a specified register. */ 99*48c6a6b6SBharat Gooty static void iproc_i2c_reg_write(uint32_t bus_id, 100*48c6a6b6SBharat Gooty unsigned long reg_addr, 101*48c6a6b6SBharat Gooty uint32_t val) 102*48c6a6b6SBharat Gooty { 103*48c6a6b6SBharat Gooty uintptr_t smbus; 104*48c6a6b6SBharat Gooty 105*48c6a6b6SBharat Gooty smbus = smbus_base_reg_addr[bus_id]; 106*48c6a6b6SBharat Gooty 107*48c6a6b6SBharat Gooty mmio_write_32((smbus + reg_addr), val); 108*48c6a6b6SBharat Gooty VERBOSE("i2c %u: reg %p wrote 0x%x\n", bus_id, 109*48c6a6b6SBharat Gooty (void *)(smbus + reg_addr), val); 110*48c6a6b6SBharat Gooty } 111*48c6a6b6SBharat Gooty 112*48c6a6b6SBharat Gooty /* Function to clear and set bits in a specified register. */ 113*48c6a6b6SBharat Gooty static void iproc_i2c_reg_clearset(uint32_t bus_id, 114*48c6a6b6SBharat Gooty unsigned long reg_addr, 115*48c6a6b6SBharat Gooty uint32_t clear, 116*48c6a6b6SBharat Gooty uint32_t set) 117*48c6a6b6SBharat Gooty { 118*48c6a6b6SBharat Gooty uintptr_t smbus; 119*48c6a6b6SBharat Gooty 120*48c6a6b6SBharat Gooty smbus = smbus_base_reg_addr[bus_id]; 121*48c6a6b6SBharat Gooty 122*48c6a6b6SBharat Gooty mmio_clrsetbits_32((smbus + reg_addr), clear, set); 123*48c6a6b6SBharat Gooty VERBOSE("i2c %u: reg %p clear 0x%x, set 0x%x\n", bus_id, 124*48c6a6b6SBharat Gooty (void *)(smbus + reg_addr), clear, set); 125*48c6a6b6SBharat Gooty } 126*48c6a6b6SBharat Gooty 127*48c6a6b6SBharat Gooty /* Function to dump all SMBUS register */ 128*48c6a6b6SBharat Gooty #ifdef BCM_I2C_DEBUG 129*48c6a6b6SBharat Gooty static int iproc_dump_i2c_regs(uint32_t bus_id) 130*48c6a6b6SBharat Gooty { 131*48c6a6b6SBharat Gooty uint32_t regval; 132*48c6a6b6SBharat Gooty 133*48c6a6b6SBharat Gooty if (bus_id > MAX_I2C) { 134*48c6a6b6SBharat Gooty return -1; 135*48c6a6b6SBharat Gooty } 136*48c6a6b6SBharat Gooty 137*48c6a6b6SBharat Gooty INFO("----------------------------------------------\n"); 138*48c6a6b6SBharat Gooty INFO("%s: Dumping SMBus %u registers...\n", __func__, bus_id); 139*48c6a6b6SBharat Gooty 140*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG); 141*48c6a6b6SBharat Gooty INFO("SMB_CFG_REG=0x%x\n", regval); 142*48c6a6b6SBharat Gooty 143*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_TIMGCFG_REG); 144*48c6a6b6SBharat Gooty INFO("SMB_TIMGCFG_REG=0x%x\n", regval); 145*48c6a6b6SBharat Gooty 146*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_ADDR_REG); 147*48c6a6b6SBharat Gooty INFO("SMB_ADDR_REG=0x%x\n", regval); 148*48c6a6b6SBharat Gooty 149*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_MSTRFIFOCTL_REG); 150*48c6a6b6SBharat Gooty INFO("SMB_MSTRFIFOCTL_REG=0x%x\n", regval); 151*48c6a6b6SBharat Gooty 152*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_SLVFIFOCTL_REG); 153*48c6a6b6SBharat Gooty INFO("SMB_SLVFIFOCTL_REG=0x%x\n", regval); 154*48c6a6b6SBharat Gooty 155*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_BITBANGCTL_REG); 156*48c6a6b6SBharat Gooty INFO("SMB_BITBANGCTL_REG=0x%x\n", regval); 157*48c6a6b6SBharat Gooty 158*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG); 159*48c6a6b6SBharat Gooty INFO("SMB_MSTRCMD_REG=0x%x\n", regval); 160*48c6a6b6SBharat Gooty 161*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_SLVCMD_REG); 162*48c6a6b6SBharat Gooty INFO("SMB_SLVCMD_REG=0x%x\n", regval); 163*48c6a6b6SBharat Gooty 164*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_EVTEN_REG); 165*48c6a6b6SBharat Gooty INFO("SMB_EVTEN_REG=0x%x\n", regval); 166*48c6a6b6SBharat Gooty 167*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_EVTSTS_REG); 168*48c6a6b6SBharat Gooty INFO("SMB_EVTSTS_REG=0x%x\n", regval); 169*48c6a6b6SBharat Gooty 170*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_MSTRDATAWR_REG); 171*48c6a6b6SBharat Gooty INFO("SMB_MSTRDATAWR_REG=0x%x\n", regval); 172*48c6a6b6SBharat Gooty 173*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_MSTRDATARD_REG); 174*48c6a6b6SBharat Gooty INFO("SMB_MSTRDATARD_REG=0x%x\n", regval); 175*48c6a6b6SBharat Gooty 176*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_SLVDATAWR_REG); 177*48c6a6b6SBharat Gooty INFO("SMB_SLVDATAWR_REG=0x%x\n", regval); 178*48c6a6b6SBharat Gooty 179*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_SLVDATARD_REG); 180*48c6a6b6SBharat Gooty INFO("SMB_SLVDATARD_REG=0x%x\n", regval); 181*48c6a6b6SBharat Gooty 182*48c6a6b6SBharat Gooty INFO("----------------------------------------------\n"); 183*48c6a6b6SBharat Gooty return 0; 184*48c6a6b6SBharat Gooty } 185*48c6a6b6SBharat Gooty #endif 186*48c6a6b6SBharat Gooty 187*48c6a6b6SBharat Gooty /* 188*48c6a6b6SBharat Gooty * Function to ensure that the previous transaction was completed before 189*48c6a6b6SBharat Gooty * initiating a new transaction. It can also be used in polling mode to 190*48c6a6b6SBharat Gooty * check status of completion of a command 191*48c6a6b6SBharat Gooty */ 192*48c6a6b6SBharat Gooty static int iproc_i2c_startbusy_wait(uint32_t bus_id) 193*48c6a6b6SBharat Gooty { 194*48c6a6b6SBharat Gooty uint32_t regval; 195*48c6a6b6SBharat Gooty uint32_t retry = 0U; 196*48c6a6b6SBharat Gooty 197*48c6a6b6SBharat Gooty /* 198*48c6a6b6SBharat Gooty * Check if an operation is in progress. During probe it won't be. 199*48c6a6b6SBharat Gooty * Want to make sure that the transaction in progress is completed. 200*48c6a6b6SBharat Gooty */ 201*48c6a6b6SBharat Gooty do { 202*48c6a6b6SBharat Gooty udelay(1U); 203*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG); 204*48c6a6b6SBharat Gooty regval &= SMB_MSTRSTARTBUSYCMD_MASK; 205*48c6a6b6SBharat Gooty if (retry++ > BUS_BUSY_COUNT) { 206*48c6a6b6SBharat Gooty ERROR("%s: START_BUSY bit didn't clear, exiting\n", 207*48c6a6b6SBharat Gooty __func__); 208*48c6a6b6SBharat Gooty return -1; 209*48c6a6b6SBharat Gooty } 210*48c6a6b6SBharat Gooty 211*48c6a6b6SBharat Gooty } while (regval != 0U); 212*48c6a6b6SBharat Gooty 213*48c6a6b6SBharat Gooty return 0; 214*48c6a6b6SBharat Gooty } 215*48c6a6b6SBharat Gooty 216*48c6a6b6SBharat Gooty /* 217*48c6a6b6SBharat Gooty * This function copies data to SMBus's Tx FIFO. Valid for write transactions 218*48c6a6b6SBharat Gooty * info: Data to copy in to Tx FIFO. For read commands, the size should be 219*48c6a6b6SBharat Gooty * set to zero by the caller 220*48c6a6b6SBharat Gooty */ 221*48c6a6b6SBharat Gooty static void iproc_i2c_write_trans_data(struct iproc_xact_info *info) 222*48c6a6b6SBharat Gooty { 223*48c6a6b6SBharat Gooty uint32_t regval; 224*48c6a6b6SBharat Gooty uint8_t devaddr; 225*48c6a6b6SBharat Gooty uint32_t i; 226*48c6a6b6SBharat Gooty uint32_t num_data_bytes = 0U; 227*48c6a6b6SBharat Gooty 228*48c6a6b6SBharat Gooty #ifdef BCM_I2C_DEBUG 229*48c6a6b6SBharat Gooty INFO("%s:dev_addr=0x%x,cmd_valid=%d, cmd=0x%x, size=%u proto=%d\n", 230*48c6a6b6SBharat Gooty __func__, info->devaddr, info->cmd_valid, info->command, 231*48c6a6b6SBharat Gooty info->size, info->smb_proto); 232*48c6a6b6SBharat Gooty #endif 233*48c6a6b6SBharat Gooty /* Shift devaddr by 1 bit since SMBus uses the low bit[0] for R/W_n */ 234*48c6a6b6SBharat Gooty devaddr = (info->devaddr << 1); 235*48c6a6b6SBharat Gooty 236*48c6a6b6SBharat Gooty /* 237*48c6a6b6SBharat Gooty * Depending on the SMBus protocol, we need to write additional 238*48c6a6b6SBharat Gooty * transaction data in to Tx FIFO. Refer to section 5.5 of SMBus spec 239*48c6a6b6SBharat Gooty * for sequence for a transaction 240*48c6a6b6SBharat Gooty */ 241*48c6a6b6SBharat Gooty switch (info->smb_proto) { 242*48c6a6b6SBharat Gooty case SMBUS_PROT_RECV_BYTE: 243*48c6a6b6SBharat Gooty /* No additional data to be written */ 244*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 245*48c6a6b6SBharat Gooty devaddr | 0x1U | SMB_MSTRWRSTS_MASK); 246*48c6a6b6SBharat Gooty break; 247*48c6a6b6SBharat Gooty case SMBUS_PROT_SEND_BYTE: 248*48c6a6b6SBharat Gooty num_data_bytes = info->size; 249*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 250*48c6a6b6SBharat Gooty devaddr); 251*48c6a6b6SBharat Gooty break; 252*48c6a6b6SBharat Gooty case SMBUS_PROT_RD_BYTE: 253*48c6a6b6SBharat Gooty case SMBUS_PROT_RD_WORD: 254*48c6a6b6SBharat Gooty case SMBUS_PROT_BLK_RD: 255*48c6a6b6SBharat Gooty /* Write slave address with R/W~ set (bit #0) */ 256*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 257*48c6a6b6SBharat Gooty devaddr | 0x1U); 258*48c6a6b6SBharat Gooty break; 259*48c6a6b6SBharat Gooty case SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL: 260*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 261*48c6a6b6SBharat Gooty devaddr | 0x1U | SMB_MSTRWRSTS_MASK); 262*48c6a6b6SBharat Gooty break; 263*48c6a6b6SBharat Gooty case SMBUS_PROT_WR_BYTE: 264*48c6a6b6SBharat Gooty case SMBUS_PROT_WR_WORD: 265*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 266*48c6a6b6SBharat Gooty devaddr); 267*48c6a6b6SBharat Gooty /* 268*48c6a6b6SBharat Gooty * No additional bytes to be written. Data portion is written 269*48c6a6b6SBharat Gooty * in the 'for' loop below 270*48c6a6b6SBharat Gooty */ 271*48c6a6b6SBharat Gooty num_data_bytes = info->size; 272*48c6a6b6SBharat Gooty break; 273*48c6a6b6SBharat Gooty case SMBUS_PROT_BLK_WR: 274*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 275*48c6a6b6SBharat Gooty devaddr); 276*48c6a6b6SBharat Gooty /* 3rd byte is byte count */ 277*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 278*48c6a6b6SBharat Gooty info->size); 279*48c6a6b6SBharat Gooty num_data_bytes = info->size; 280*48c6a6b6SBharat Gooty break; 281*48c6a6b6SBharat Gooty default: 282*48c6a6b6SBharat Gooty return; 283*48c6a6b6SBharat Gooty } 284*48c6a6b6SBharat Gooty 285*48c6a6b6SBharat Gooty /* If the protocol needs command code, copy it */ 286*48c6a6b6SBharat Gooty if (info->cmd_valid) { 287*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 288*48c6a6b6SBharat Gooty info->command); 289*48c6a6b6SBharat Gooty } 290*48c6a6b6SBharat Gooty 291*48c6a6b6SBharat Gooty /* 292*48c6a6b6SBharat Gooty * Copy actual data from caller. In general, for reads, 293*48c6a6b6SBharat Gooty * no data is copied. 294*48c6a6b6SBharat Gooty */ 295*48c6a6b6SBharat Gooty for (i = 0U; num_data_bytes; --num_data_bytes, i++) { 296*48c6a6b6SBharat Gooty /* For the last byte, set MASTER_WR_STATUS bit */ 297*48c6a6b6SBharat Gooty regval = (num_data_bytes == 1U) ? 298*48c6a6b6SBharat Gooty info->data[i] | SMB_MSTRWRSTS_MASK : info->data[i]; 299*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG, 300*48c6a6b6SBharat Gooty regval); 301*48c6a6b6SBharat Gooty } 302*48c6a6b6SBharat Gooty } 303*48c6a6b6SBharat Gooty 304*48c6a6b6SBharat Gooty /* 305*48c6a6b6SBharat Gooty * This function writes to the master command register and 306*48c6a6b6SBharat Gooty * then polls for completion 307*48c6a6b6SBharat Gooty */ 308*48c6a6b6SBharat Gooty static int iproc_i2c_write_master_command(uint32_t mastercmd, 309*48c6a6b6SBharat Gooty struct iproc_xact_info *info) 310*48c6a6b6SBharat Gooty { 311*48c6a6b6SBharat Gooty uint32_t retry = 0U; 312*48c6a6b6SBharat Gooty uint32_t regval; 313*48c6a6b6SBharat Gooty 314*48c6a6b6SBharat Gooty iproc_i2c_reg_write(info->bus_id, SMB_MSTRCMD_REG, mastercmd); 315*48c6a6b6SBharat Gooty 316*48c6a6b6SBharat Gooty /* Check for Master Busy status */ 317*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRCMD_REG); 318*48c6a6b6SBharat Gooty while ((regval & SMB_MSTRSTARTBUSYCMD_MASK) != 0U) { 319*48c6a6b6SBharat Gooty udelay(1U); 320*48c6a6b6SBharat Gooty if (retry++ > BUS_BUSY_COUNT) { 321*48c6a6b6SBharat Gooty ERROR("%s: START_BUSY bit didn't clear, exiting\n", 322*48c6a6b6SBharat Gooty __func__); 323*48c6a6b6SBharat Gooty return -1; 324*48c6a6b6SBharat Gooty } 325*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRCMD_REG); 326*48c6a6b6SBharat Gooty } 327*48c6a6b6SBharat Gooty 328*48c6a6b6SBharat Gooty /* If start_busy bit cleared, check if there are any errors */ 329*48c6a6b6SBharat Gooty if (!(regval & SMB_MSTRSTARTBUSYCMD_MASK)) { 330*48c6a6b6SBharat Gooty /* start_busy bit cleared, check master_status field now */ 331*48c6a6b6SBharat Gooty regval &= SMB_MSTRSTS_MASK; 332*48c6a6b6SBharat Gooty regval >>= SMB_MSTRSTS_SHIFT; 333*48c6a6b6SBharat Gooty if (regval != MSTR_STS_XACT_SUCCESS) { 334*48c6a6b6SBharat Gooty /* Error We can flush Tx FIFO here */ 335*48c6a6b6SBharat Gooty ERROR("%s: ERROR: %u exiting\n", __func__, regval); 336*48c6a6b6SBharat Gooty return -1; 337*48c6a6b6SBharat Gooty } 338*48c6a6b6SBharat Gooty } 339*48c6a6b6SBharat Gooty return 0; 340*48c6a6b6SBharat Gooty 341*48c6a6b6SBharat Gooty } 342*48c6a6b6SBharat Gooty /* Function to initiate data send and verify completion status */ 343*48c6a6b6SBharat Gooty static int iproc_i2c_data_send(struct iproc_xact_info *info) 344*48c6a6b6SBharat Gooty { 345*48c6a6b6SBharat Gooty int rc; 346*48c6a6b6SBharat Gooty uint32_t mastercmd; 347*48c6a6b6SBharat Gooty 348*48c6a6b6SBharat Gooty /* Make sure the previous transaction completed */ 349*48c6a6b6SBharat Gooty rc = iproc_i2c_startbusy_wait(info->bus_id); 350*48c6a6b6SBharat Gooty 351*48c6a6b6SBharat Gooty if (rc < 0) { 352*48c6a6b6SBharat Gooty WARN("%s: Send: bus is busy, exiting\n", __func__); 353*48c6a6b6SBharat Gooty return rc; 354*48c6a6b6SBharat Gooty } 355*48c6a6b6SBharat Gooty /* Write transaction bytes to Tx FIFO */ 356*48c6a6b6SBharat Gooty iproc_i2c_write_trans_data(info); 357*48c6a6b6SBharat Gooty 358*48c6a6b6SBharat Gooty /* 359*48c6a6b6SBharat Gooty * Program master command register (0x30) with protocol type and set 360*48c6a6b6SBharat Gooty * start_busy_command bit to initiate the write transaction 361*48c6a6b6SBharat Gooty */ 362*48c6a6b6SBharat Gooty mastercmd = (info->smb_proto << SMB_MSTRSMBUSPROTO_SHIFT) | 363*48c6a6b6SBharat Gooty SMB_MSTRSTARTBUSYCMD_MASK; 364*48c6a6b6SBharat Gooty 365*48c6a6b6SBharat Gooty if (iproc_i2c_write_master_command(mastercmd, info)) { 366*48c6a6b6SBharat Gooty return -1; 367*48c6a6b6SBharat Gooty } 368*48c6a6b6SBharat Gooty 369*48c6a6b6SBharat Gooty return 0; 370*48c6a6b6SBharat Gooty } 371*48c6a6b6SBharat Gooty 372*48c6a6b6SBharat Gooty /* 373*48c6a6b6SBharat Gooty * Function to initiate data receive, verify completion status, 374*48c6a6b6SBharat Gooty * and read from SMBUS Read FIFO 375*48c6a6b6SBharat Gooty */ 376*48c6a6b6SBharat Gooty static int iproc_i2c_data_recv(struct iproc_xact_info *info, 377*48c6a6b6SBharat Gooty uint32_t *num_bytes_read) 378*48c6a6b6SBharat Gooty { 379*48c6a6b6SBharat Gooty int rc; 380*48c6a6b6SBharat Gooty uint32_t mastercmd; 381*48c6a6b6SBharat Gooty uint32_t regval; 382*48c6a6b6SBharat Gooty 383*48c6a6b6SBharat Gooty /* Make sure the previous transaction completed */ 384*48c6a6b6SBharat Gooty rc = iproc_i2c_startbusy_wait(info->bus_id); 385*48c6a6b6SBharat Gooty 386*48c6a6b6SBharat Gooty if (rc < 0) { 387*48c6a6b6SBharat Gooty WARN("%s: Receive: Bus is busy, exiting\n", __func__); 388*48c6a6b6SBharat Gooty return rc; 389*48c6a6b6SBharat Gooty } 390*48c6a6b6SBharat Gooty 391*48c6a6b6SBharat Gooty /* Program all transaction bytes into master Tx FIFO */ 392*48c6a6b6SBharat Gooty iproc_i2c_write_trans_data(info); 393*48c6a6b6SBharat Gooty 394*48c6a6b6SBharat Gooty /* 395*48c6a6b6SBharat Gooty * Program master command register (0x30) with protocol type and set 396*48c6a6b6SBharat Gooty * start_busy_command bit to initiate the write transaction 397*48c6a6b6SBharat Gooty */ 398*48c6a6b6SBharat Gooty mastercmd = (info->smb_proto << SMB_MSTRSMBUSPROTO_SHIFT) | 399*48c6a6b6SBharat Gooty SMB_MSTRSTARTBUSYCMD_MASK | info->size; 400*48c6a6b6SBharat Gooty 401*48c6a6b6SBharat Gooty if (iproc_i2c_write_master_command(mastercmd, info)) { 402*48c6a6b6SBharat Gooty return -1; 403*48c6a6b6SBharat Gooty } 404*48c6a6b6SBharat Gooty 405*48c6a6b6SBharat Gooty /* Read received byte(s), after TX out address etc */ 406*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRDATARD_REG); 407*48c6a6b6SBharat Gooty 408*48c6a6b6SBharat Gooty /* For block read, protocol (hw) returns byte count,as the first byte */ 409*48c6a6b6SBharat Gooty if (info->smb_proto == SMBUS_PROT_BLK_RD) { 410*48c6a6b6SBharat Gooty uint32_t i; 411*48c6a6b6SBharat Gooty 412*48c6a6b6SBharat Gooty *num_bytes_read = regval & SMB_MSTRRDDATA_MASK; 413*48c6a6b6SBharat Gooty /* 414*48c6a6b6SBharat Gooty * Limit to reading a max of 32 bytes only; just a safeguard. 415*48c6a6b6SBharat Gooty * If # bytes read is a number > 32, check transaction set up, 416*48c6a6b6SBharat Gooty * and contact hw engg. 417*48c6a6b6SBharat Gooty * Assumption: PEC is disabled 418*48c6a6b6SBharat Gooty */ 419*48c6a6b6SBharat Gooty for (i = 0U; (i < *num_bytes_read) && 420*48c6a6b6SBharat Gooty (i < I2C_SMBUS_BLOCK_MAX); i++) { 421*48c6a6b6SBharat Gooty /* Read Rx FIFO for data bytes */ 422*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(info->bus_id, 423*48c6a6b6SBharat Gooty SMB_MSTRDATARD_REG); 424*48c6a6b6SBharat Gooty info->data[i] = regval & SMB_MSTRRDDATA_MASK; 425*48c6a6b6SBharat Gooty } 426*48c6a6b6SBharat Gooty } else { 427*48c6a6b6SBharat Gooty /* 1 Byte data */ 428*48c6a6b6SBharat Gooty *info->data = regval & SMB_MSTRRDDATA_MASK; 429*48c6a6b6SBharat Gooty *num_bytes_read = 1U; 430*48c6a6b6SBharat Gooty } 431*48c6a6b6SBharat Gooty 432*48c6a6b6SBharat Gooty return 0; 433*48c6a6b6SBharat Gooty } 434*48c6a6b6SBharat Gooty 435*48c6a6b6SBharat Gooty /* 436*48c6a6b6SBharat Gooty * This function set clock frequency for SMBus block. As per hardware 437*48c6a6b6SBharat Gooty * engineering, the clock frequency can be changed dynamically. 438*48c6a6b6SBharat Gooty */ 439*48c6a6b6SBharat Gooty static int iproc_i2c_set_clk_freq(uint32_t bus_id, smb_clk_freq_t freq) 440*48c6a6b6SBharat Gooty { 441*48c6a6b6SBharat Gooty uint32_t val; 442*48c6a6b6SBharat Gooty 443*48c6a6b6SBharat Gooty switch (freq) { 444*48c6a6b6SBharat Gooty case IPROC_SMB_SPEED_100KHz: 445*48c6a6b6SBharat Gooty val = 0U; 446*48c6a6b6SBharat Gooty break; 447*48c6a6b6SBharat Gooty case IPROC_SMB_SPEED_400KHz: 448*48c6a6b6SBharat Gooty val = 1U; 449*48c6a6b6SBharat Gooty break; 450*48c6a6b6SBharat Gooty default: 451*48c6a6b6SBharat Gooty return -1; 452*48c6a6b6SBharat Gooty } 453*48c6a6b6SBharat Gooty 454*48c6a6b6SBharat Gooty iproc_i2c_reg_clearset(bus_id, SMB_TIMGCFG_REG, 455*48c6a6b6SBharat Gooty SMB_TIMGCFG_MODE400_MASK, 456*48c6a6b6SBharat Gooty val << SMB_TIMGCFG_MODE400_SHIFT); 457*48c6a6b6SBharat Gooty 458*48c6a6b6SBharat Gooty return 0; 459*48c6a6b6SBharat Gooty } 460*48c6a6b6SBharat Gooty 461*48c6a6b6SBharat Gooty /* Helper function to fill the iproc_xact_info structure */ 462*48c6a6b6SBharat Gooty static void iproc_i2c_fill_info(struct iproc_xact_info *info, uint32_t bus_id, 463*48c6a6b6SBharat Gooty uint8_t devaddr, uint8_t cmd, uint8_t *value, 464*48c6a6b6SBharat Gooty uint8_t smb_proto, uint32_t cmd_valid) 465*48c6a6b6SBharat Gooty { 466*48c6a6b6SBharat Gooty info->bus_id = bus_id; 467*48c6a6b6SBharat Gooty info->devaddr = devaddr; 468*48c6a6b6SBharat Gooty info->command = (uint8_t)cmd; 469*48c6a6b6SBharat Gooty info->smb_proto = smb_proto; 470*48c6a6b6SBharat Gooty info->data = value; 471*48c6a6b6SBharat Gooty info->size = 1U; 472*48c6a6b6SBharat Gooty info->flags = 0U; 473*48c6a6b6SBharat Gooty info->cmd_valid = cmd_valid; 474*48c6a6b6SBharat Gooty } 475*48c6a6b6SBharat Gooty 476*48c6a6b6SBharat Gooty /* This function initializes the SMBUS */ 477*48c6a6b6SBharat Gooty static void iproc_i2c_init(uint32_t bus_id, int speed) 478*48c6a6b6SBharat Gooty { 479*48c6a6b6SBharat Gooty uint32_t regval; 480*48c6a6b6SBharat Gooty 481*48c6a6b6SBharat Gooty #ifdef BCM_I2C_DEBUG 482*48c6a6b6SBharat Gooty INFO("%s: Enter Init\n", __func__); 483*48c6a6b6SBharat Gooty #endif 484*48c6a6b6SBharat Gooty 485*48c6a6b6SBharat Gooty /* Put controller in reset */ 486*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG); 487*48c6a6b6SBharat Gooty regval |= BIT(SMB_CFG_RST_SHIFT); 488*48c6a6b6SBharat Gooty regval &= ~(BIT(SMB_CFG_SMBEN_SHIFT)); 489*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval); 490*48c6a6b6SBharat Gooty 491*48c6a6b6SBharat Gooty /* Wait 100 usec per spec */ 492*48c6a6b6SBharat Gooty udelay(100U); 493*48c6a6b6SBharat Gooty 494*48c6a6b6SBharat Gooty /* Bring controller out of reset */ 495*48c6a6b6SBharat Gooty regval &= ~(BIT(SMB_CFG_RST_SHIFT)); 496*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval); 497*48c6a6b6SBharat Gooty 498*48c6a6b6SBharat Gooty /* 499*48c6a6b6SBharat Gooty * Flush Tx, Rx FIFOs. Note we are setting the Rx FIFO threshold to 0. 500*48c6a6b6SBharat Gooty * May be OK since we are setting RX_EVENT and RX_FIFO_FULL interrupts 501*48c6a6b6SBharat Gooty */ 502*48c6a6b6SBharat Gooty regval = SMB_MSTRRXFIFOFLSH_MASK | SMB_MSTRTXFIFOFLSH_MASK; 503*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_MSTRFIFOCTL_REG, regval); 504*48c6a6b6SBharat Gooty 505*48c6a6b6SBharat Gooty /* 506*48c6a6b6SBharat Gooty * Enable SMbus block. Note, we are setting MASTER_RETRY_COUNT to zero 507*48c6a6b6SBharat Gooty * since there will be only one master 508*48c6a6b6SBharat Gooty */ 509*48c6a6b6SBharat Gooty 510*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG); 511*48c6a6b6SBharat Gooty regval |= SMB_CFG_SMBEN_MASK; 512*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval); 513*48c6a6b6SBharat Gooty /* Wait a minimum of 50 Usec, as per SMB hw doc. But we wait longer */ 514*48c6a6b6SBharat Gooty mdelay(10U); 515*48c6a6b6SBharat Gooty 516*48c6a6b6SBharat Gooty /* If error then set default speed */ 517*48c6a6b6SBharat Gooty if (i2c_set_bus_speed(bus_id, speed)) { 518*48c6a6b6SBharat Gooty i2c_set_bus_speed(bus_id, I2C_SPEED_DEFAULT); 519*48c6a6b6SBharat Gooty } 520*48c6a6b6SBharat Gooty 521*48c6a6b6SBharat Gooty /* Disable intrs */ 522*48c6a6b6SBharat Gooty regval = 0x0U; 523*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_EVTEN_REG, regval); 524*48c6a6b6SBharat Gooty 525*48c6a6b6SBharat Gooty /* Clear intrs (W1TC) */ 526*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_EVTSTS_REG); 527*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_EVTSTS_REG, regval); 528*48c6a6b6SBharat Gooty 529*48c6a6b6SBharat Gooty #ifdef BCM_I2C_DEBUG 530*48c6a6b6SBharat Gooty iproc_dump_i2c_regs(bus_id); 531*48c6a6b6SBharat Gooty 532*48c6a6b6SBharat Gooty INFO("%s: Exit Init Successfully\n", __func__); 533*48c6a6b6SBharat Gooty #endif 534*48c6a6b6SBharat Gooty } 535*48c6a6b6SBharat Gooty 536*48c6a6b6SBharat Gooty /* 537*48c6a6b6SBharat Gooty * Function Name: i2c_init 538*48c6a6b6SBharat Gooty * 539*48c6a6b6SBharat Gooty * Description: 540*48c6a6b6SBharat Gooty * This function initializes the SMBUS. 541*48c6a6b6SBharat Gooty * 542*48c6a6b6SBharat Gooty * Parameters: 543*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 544*48c6a6b6SBharat Gooty * speed - I2C bus speed in Hz 545*48c6a6b6SBharat Gooty * 546*48c6a6b6SBharat Gooty * Return: 547*48c6a6b6SBharat Gooty * 0 on success, or -1 on failure. 548*48c6a6b6SBharat Gooty */ 549*48c6a6b6SBharat Gooty int i2c_init(uint32_t bus_id, int speed) 550*48c6a6b6SBharat Gooty { 551*48c6a6b6SBharat Gooty if (bus_id > MAX_I2C) { 552*48c6a6b6SBharat Gooty WARN("%s: Invalid Bus %u\n", __func__, bus_id); 553*48c6a6b6SBharat Gooty return -1; 554*48c6a6b6SBharat Gooty } 555*48c6a6b6SBharat Gooty 556*48c6a6b6SBharat Gooty iproc_i2c_init(bus_id, speed); 557*48c6a6b6SBharat Gooty return 0U; 558*48c6a6b6SBharat Gooty } 559*48c6a6b6SBharat Gooty 560*48c6a6b6SBharat Gooty /* 561*48c6a6b6SBharat Gooty * Function Name: i2c_probe 562*48c6a6b6SBharat Gooty * 563*48c6a6b6SBharat Gooty * Description: 564*48c6a6b6SBharat Gooty * This function probes the I2C bus for the existence of the specified 565*48c6a6b6SBharat Gooty * device. 566*48c6a6b6SBharat Gooty * 567*48c6a6b6SBharat Gooty * Parameters: 568*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 569*48c6a6b6SBharat Gooty * devaddr - Device Address 570*48c6a6b6SBharat Gooty * 571*48c6a6b6SBharat Gooty * Return: 572*48c6a6b6SBharat Gooty * 0 on success, or -1 on failure. 573*48c6a6b6SBharat Gooty */ 574*48c6a6b6SBharat Gooty int i2c_probe(uint32_t bus_id, uint8_t devaddr) 575*48c6a6b6SBharat Gooty { 576*48c6a6b6SBharat Gooty uint32_t regval; 577*48c6a6b6SBharat Gooty int rc; 578*48c6a6b6SBharat Gooty 579*48c6a6b6SBharat Gooty /* 580*48c6a6b6SBharat Gooty * i2c_init() Initializes internal regs, disable intrs (and then clear intrs), 581*48c6a6b6SBharat Gooty * set fifo thresholds, etc. 582*48c6a6b6SBharat Gooty * Shift devaddr by 1 bit since SMBus uses the low bit[0] for R/W_n 583*48c6a6b6SBharat Gooty */ 584*48c6a6b6SBharat Gooty regval = (devaddr << 1U); 585*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_MSTRDATAWR_REG, regval); 586*48c6a6b6SBharat Gooty 587*48c6a6b6SBharat Gooty regval = ((SMBUS_PROT_QUICK_CMD << SMB_MSTRSMBUSPROTO_SHIFT) | 588*48c6a6b6SBharat Gooty SMB_MSTRSTARTBUSYCMD_MASK); 589*48c6a6b6SBharat Gooty iproc_i2c_reg_write(bus_id, SMB_MSTRCMD_REG, regval); 590*48c6a6b6SBharat Gooty 591*48c6a6b6SBharat Gooty rc = iproc_i2c_startbusy_wait(bus_id); 592*48c6a6b6SBharat Gooty 593*48c6a6b6SBharat Gooty if (rc < 0) { 594*48c6a6b6SBharat Gooty WARN("%s: Probe: bus is busy, exiting\n", __func__); 595*48c6a6b6SBharat Gooty return rc; 596*48c6a6b6SBharat Gooty } 597*48c6a6b6SBharat Gooty 598*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG); 599*48c6a6b6SBharat Gooty if (((regval & SMB_MSTRSTS_MASK) >> SMB_MSTRSTS_SHIFT) == 0) 600*48c6a6b6SBharat Gooty VERBOSE("i2c device address: 0x%x\n", devaddr); 601*48c6a6b6SBharat Gooty else 602*48c6a6b6SBharat Gooty return -1; 603*48c6a6b6SBharat Gooty 604*48c6a6b6SBharat Gooty #ifdef BCM_I2C_DEBUG 605*48c6a6b6SBharat Gooty iproc_dump_i2c_regs(bus_id); 606*48c6a6b6SBharat Gooty #endif 607*48c6a6b6SBharat Gooty return 0; 608*48c6a6b6SBharat Gooty } 609*48c6a6b6SBharat Gooty 610*48c6a6b6SBharat Gooty /* 611*48c6a6b6SBharat Gooty * Function Name: i2c_recv_byte 612*48c6a6b6SBharat Gooty * 613*48c6a6b6SBharat Gooty * Description: 614*48c6a6b6SBharat Gooty * This function reads I2C data from a device without specifying 615*48c6a6b6SBharat Gooty * a command regsiter. 616*48c6a6b6SBharat Gooty * 617*48c6a6b6SBharat Gooty * Parameters: 618*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 619*48c6a6b6SBharat Gooty * devaddr - Device Address 620*48c6a6b6SBharat Gooty * value - Data Read 621*48c6a6b6SBharat Gooty * 622*48c6a6b6SBharat Gooty * Return: 623*48c6a6b6SBharat Gooty * 0 on success, or -1 on failure. 624*48c6a6b6SBharat Gooty */ 625*48c6a6b6SBharat Gooty int i2c_recv_byte(uint32_t bus_id, uint8_t devaddr, uint8_t *value) 626*48c6a6b6SBharat Gooty { 627*48c6a6b6SBharat Gooty int rc; 628*48c6a6b6SBharat Gooty struct iproc_xact_info info; 629*48c6a6b6SBharat Gooty uint32_t num_bytes_read = 0; 630*48c6a6b6SBharat Gooty 631*48c6a6b6SBharat Gooty iproc_i2c_fill_info(&info, bus_id, devaddr, 0U, value, 632*48c6a6b6SBharat Gooty SMBUS_PROT_RECV_BYTE, 0U); 633*48c6a6b6SBharat Gooty 634*48c6a6b6SBharat Gooty /* Refer to i2c_smbus_read_byte for params passed. */ 635*48c6a6b6SBharat Gooty rc = iproc_i2c_data_recv(&info, &num_bytes_read); 636*48c6a6b6SBharat Gooty 637*48c6a6b6SBharat Gooty if (rc < 0) { 638*48c6a6b6SBharat Gooty printf("%s: %s error accessing device 0x%x\n", 639*48c6a6b6SBharat Gooty __func__, "Read", devaddr); 640*48c6a6b6SBharat Gooty } 641*48c6a6b6SBharat Gooty 642*48c6a6b6SBharat Gooty return rc; 643*48c6a6b6SBharat Gooty } 644*48c6a6b6SBharat Gooty 645*48c6a6b6SBharat Gooty /* 646*48c6a6b6SBharat Gooty * Function Name: i2c_send_byte 647*48c6a6b6SBharat Gooty * 648*48c6a6b6SBharat Gooty * Description: 649*48c6a6b6SBharat Gooty * This function send I2C data to a device without specifying 650*48c6a6b6SBharat Gooty * a command regsiter. 651*48c6a6b6SBharat Gooty * 652*48c6a6b6SBharat Gooty * Parameters: 653*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 654*48c6a6b6SBharat Gooty * devaddr - Device Address 655*48c6a6b6SBharat Gooty * value - Data Send 656*48c6a6b6SBharat Gooty * 657*48c6a6b6SBharat Gooty * Return: 658*48c6a6b6SBharat Gooty * 0 on success, or -1 on failure. 659*48c6a6b6SBharat Gooty */ 660*48c6a6b6SBharat Gooty int i2c_send_byte(uint32_t bus_id, uint8_t devaddr, uint8_t value) 661*48c6a6b6SBharat Gooty { 662*48c6a6b6SBharat Gooty int rc; 663*48c6a6b6SBharat Gooty struct iproc_xact_info info; 664*48c6a6b6SBharat Gooty 665*48c6a6b6SBharat Gooty iproc_i2c_fill_info(&info, bus_id, devaddr, 0U, &value, 666*48c6a6b6SBharat Gooty SMBUS_PROT_SEND_BYTE, 0U); 667*48c6a6b6SBharat Gooty 668*48c6a6b6SBharat Gooty /* Refer to i2c_smbus_write_byte params passed. */ 669*48c6a6b6SBharat Gooty rc = iproc_i2c_data_send(&info); 670*48c6a6b6SBharat Gooty 671*48c6a6b6SBharat Gooty if (rc < 0) { 672*48c6a6b6SBharat Gooty ERROR("%s: %s error accessing device 0x%x\n", 673*48c6a6b6SBharat Gooty __func__, "Write", devaddr); 674*48c6a6b6SBharat Gooty } 675*48c6a6b6SBharat Gooty 676*48c6a6b6SBharat Gooty return rc; 677*48c6a6b6SBharat Gooty } 678*48c6a6b6SBharat Gooty 679*48c6a6b6SBharat Gooty /* Helper function to read a single byte */ 680*48c6a6b6SBharat Gooty static int i2c_read_byte(uint32_t bus_id, 681*48c6a6b6SBharat Gooty uint8_t devaddr, 682*48c6a6b6SBharat Gooty uint8_t regoffset, 683*48c6a6b6SBharat Gooty uint8_t *value) 684*48c6a6b6SBharat Gooty { 685*48c6a6b6SBharat Gooty int rc; 686*48c6a6b6SBharat Gooty struct iproc_xact_info info; 687*48c6a6b6SBharat Gooty uint32_t num_bytes_read = 0U; 688*48c6a6b6SBharat Gooty 689*48c6a6b6SBharat Gooty iproc_i2c_fill_info(&info, bus_id, devaddr, regoffset, value, 690*48c6a6b6SBharat Gooty SMBUS_PROT_RD_BYTE, 1U); 691*48c6a6b6SBharat Gooty 692*48c6a6b6SBharat Gooty /* Refer to i2c_smbus_read_byte for params passed. */ 693*48c6a6b6SBharat Gooty rc = iproc_i2c_data_recv(&info, &num_bytes_read); 694*48c6a6b6SBharat Gooty 695*48c6a6b6SBharat Gooty if (rc < 0) { 696*48c6a6b6SBharat Gooty ERROR("%s: %s error accessing device 0x%x\n", 697*48c6a6b6SBharat Gooty __func__, "Read", devaddr); 698*48c6a6b6SBharat Gooty } 699*48c6a6b6SBharat Gooty return rc; 700*48c6a6b6SBharat Gooty } 701*48c6a6b6SBharat Gooty 702*48c6a6b6SBharat Gooty /* 703*48c6a6b6SBharat Gooty * Function Name: i2c_read 704*48c6a6b6SBharat Gooty * 705*48c6a6b6SBharat Gooty * Description: 706*48c6a6b6SBharat Gooty * This function reads I2C data from a device with a designated 707*48c6a6b6SBharat Gooty * command register 708*48c6a6b6SBharat Gooty * 709*48c6a6b6SBharat Gooty * Parameters: 710*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 711*48c6a6b6SBharat Gooty * devaddr - Device Address 712*48c6a6b6SBharat Gooty * addr - Register Offset 713*48c6a6b6SBharat Gooty * alen - Address Length, 1 for byte, 2 for word (not supported) 714*48c6a6b6SBharat Gooty * buffer - Data Buffer 715*48c6a6b6SBharat Gooty * len - Data Length in bytes 716*48c6a6b6SBharat Gooty * 717*48c6a6b6SBharat Gooty * Return: 718*48c6a6b6SBharat Gooty * 0 on success, or -1 on failure. 719*48c6a6b6SBharat Gooty */ 720*48c6a6b6SBharat Gooty int i2c_read(uint32_t bus_id, 721*48c6a6b6SBharat Gooty uint8_t devaddr, 722*48c6a6b6SBharat Gooty uint32_t addr, 723*48c6a6b6SBharat Gooty int alen, 724*48c6a6b6SBharat Gooty uint8_t *buffer, 725*48c6a6b6SBharat Gooty int len) 726*48c6a6b6SBharat Gooty { 727*48c6a6b6SBharat Gooty uint32_t i; 728*48c6a6b6SBharat Gooty 729*48c6a6b6SBharat Gooty if (alen > 1) { 730*48c6a6b6SBharat Gooty WARN("I2C read: addr len %d not supported\n", alen); 731*48c6a6b6SBharat Gooty return -1; 732*48c6a6b6SBharat Gooty } 733*48c6a6b6SBharat Gooty 734*48c6a6b6SBharat Gooty if (addr + len > 256) { 735*48c6a6b6SBharat Gooty WARN("I2C read: address out of range\n"); 736*48c6a6b6SBharat Gooty return -1; 737*48c6a6b6SBharat Gooty } 738*48c6a6b6SBharat Gooty 739*48c6a6b6SBharat Gooty for (i = 0U; i < len; i++) { 740*48c6a6b6SBharat Gooty if (i2c_read_byte(bus_id, devaddr, addr + i, &buffer[i])) { 741*48c6a6b6SBharat Gooty ERROR("I2C read: I/O error\n"); 742*48c6a6b6SBharat Gooty iproc_i2c_init(bus_id, i2c_get_bus_speed(bus_id)); 743*48c6a6b6SBharat Gooty return -1; 744*48c6a6b6SBharat Gooty } 745*48c6a6b6SBharat Gooty } 746*48c6a6b6SBharat Gooty 747*48c6a6b6SBharat Gooty return 0; 748*48c6a6b6SBharat Gooty } 749*48c6a6b6SBharat Gooty 750*48c6a6b6SBharat Gooty /* Helper function to write a single byte */ 751*48c6a6b6SBharat Gooty static int i2c_write_byte(uint32_t bus_id, 752*48c6a6b6SBharat Gooty uint8_t devaddr, 753*48c6a6b6SBharat Gooty uint8_t regoffset, 754*48c6a6b6SBharat Gooty uint8_t value) 755*48c6a6b6SBharat Gooty { 756*48c6a6b6SBharat Gooty int rc; 757*48c6a6b6SBharat Gooty struct iproc_xact_info info; 758*48c6a6b6SBharat Gooty 759*48c6a6b6SBharat Gooty iproc_i2c_fill_info(&info, bus_id, devaddr, regoffset, &value, 760*48c6a6b6SBharat Gooty SMBUS_PROT_WR_BYTE, 1U); 761*48c6a6b6SBharat Gooty 762*48c6a6b6SBharat Gooty /* Refer to i2c_smbus_write_byte params passed. */ 763*48c6a6b6SBharat Gooty rc = iproc_i2c_data_send(&info); 764*48c6a6b6SBharat Gooty 765*48c6a6b6SBharat Gooty if (rc < 0) { 766*48c6a6b6SBharat Gooty ERROR("%s: %s error accessing device 0x%x\n", 767*48c6a6b6SBharat Gooty __func__, "Write", devaddr); 768*48c6a6b6SBharat Gooty return -1; 769*48c6a6b6SBharat Gooty } 770*48c6a6b6SBharat Gooty 771*48c6a6b6SBharat Gooty return 0; 772*48c6a6b6SBharat Gooty } 773*48c6a6b6SBharat Gooty 774*48c6a6b6SBharat Gooty /* 775*48c6a6b6SBharat Gooty * Function Name: i2c_write 776*48c6a6b6SBharat Gooty * 777*48c6a6b6SBharat Gooty * Description: 778*48c6a6b6SBharat Gooty * This function write I2C data to a device with a designated 779*48c6a6b6SBharat Gooty * command register 780*48c6a6b6SBharat Gooty * 781*48c6a6b6SBharat Gooty * Parameters: 782*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 783*48c6a6b6SBharat Gooty * devaddr - Device Address 784*48c6a6b6SBharat Gooty * addr - Register Offset 785*48c6a6b6SBharat Gooty * alen - Address Length, 1 for byte, 2 for word (not supported) 786*48c6a6b6SBharat Gooty * buffer - Data Buffer 787*48c6a6b6SBharat Gooty * len - Data Length in bytes 788*48c6a6b6SBharat Gooty * 789*48c6a6b6SBharat Gooty * Return: 790*48c6a6b6SBharat Gooty * 0 on success, or -1 on failure. 791*48c6a6b6SBharat Gooty */ 792*48c6a6b6SBharat Gooty int i2c_write(uint32_t bus_id, 793*48c6a6b6SBharat Gooty uint8_t devaddr, 794*48c6a6b6SBharat Gooty uint32_t addr, 795*48c6a6b6SBharat Gooty int alen, 796*48c6a6b6SBharat Gooty uint8_t *buffer, 797*48c6a6b6SBharat Gooty int len) 798*48c6a6b6SBharat Gooty { 799*48c6a6b6SBharat Gooty uint32_t i; 800*48c6a6b6SBharat Gooty 801*48c6a6b6SBharat Gooty if (alen > 1) { 802*48c6a6b6SBharat Gooty WARN("I2C write: addr len %d not supported\n", alen); 803*48c6a6b6SBharat Gooty return -1; 804*48c6a6b6SBharat Gooty } 805*48c6a6b6SBharat Gooty 806*48c6a6b6SBharat Gooty if (addr + len > 256U) { 807*48c6a6b6SBharat Gooty WARN("I2C write: address out of range\n"); 808*48c6a6b6SBharat Gooty return -1; 809*48c6a6b6SBharat Gooty } 810*48c6a6b6SBharat Gooty 811*48c6a6b6SBharat Gooty for (i = 0U; i < len; i++) { 812*48c6a6b6SBharat Gooty if (i2c_write_byte(bus_id, devaddr, addr + i, buffer[i])) { 813*48c6a6b6SBharat Gooty ERROR("I2C write: I/O error\n"); 814*48c6a6b6SBharat Gooty iproc_i2c_init(bus_id, i2c_get_bus_speed(bus_id)); 815*48c6a6b6SBharat Gooty return -1; 816*48c6a6b6SBharat Gooty } 817*48c6a6b6SBharat Gooty } 818*48c6a6b6SBharat Gooty return 0; 819*48c6a6b6SBharat Gooty } 820*48c6a6b6SBharat Gooty 821*48c6a6b6SBharat Gooty /* 822*48c6a6b6SBharat Gooty * Function Name: i2c_set_bus_speed 823*48c6a6b6SBharat Gooty * 824*48c6a6b6SBharat Gooty * Description: 825*48c6a6b6SBharat Gooty * This function configures the SMBUS speed 826*48c6a6b6SBharat Gooty * 827*48c6a6b6SBharat Gooty * Parameters: 828*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 829*48c6a6b6SBharat Gooty * speed - I2C bus speed in Hz 830*48c6a6b6SBharat Gooty * 831*48c6a6b6SBharat Gooty * Return: 832*48c6a6b6SBharat Gooty * 0 on success, or -1 on failure. 833*48c6a6b6SBharat Gooty */ 834*48c6a6b6SBharat Gooty int i2c_set_bus_speed(uint32_t bus_id, uint32_t speed) 835*48c6a6b6SBharat Gooty { 836*48c6a6b6SBharat Gooty switch (speed) { 837*48c6a6b6SBharat Gooty case I2C_SPEED_100KHz: 838*48c6a6b6SBharat Gooty iproc_i2c_set_clk_freq(bus_id, IPROC_SMB_SPEED_100KHz); 839*48c6a6b6SBharat Gooty break; 840*48c6a6b6SBharat Gooty 841*48c6a6b6SBharat Gooty case I2C_SPEED_400KHz: 842*48c6a6b6SBharat Gooty iproc_i2c_set_clk_freq(bus_id, IPROC_SMB_SPEED_400KHz); 843*48c6a6b6SBharat Gooty break; 844*48c6a6b6SBharat Gooty 845*48c6a6b6SBharat Gooty default: 846*48c6a6b6SBharat Gooty return -1; 847*48c6a6b6SBharat Gooty } 848*48c6a6b6SBharat Gooty return 0; 849*48c6a6b6SBharat Gooty } 850*48c6a6b6SBharat Gooty 851*48c6a6b6SBharat Gooty /* 852*48c6a6b6SBharat Gooty * Function Name: i2c_get_bus_speed 853*48c6a6b6SBharat Gooty * 854*48c6a6b6SBharat Gooty * Description: 855*48c6a6b6SBharat Gooty * This function returns the SMBUS speed. 856*48c6a6b6SBharat Gooty * 857*48c6a6b6SBharat Gooty * Parameters: 858*48c6a6b6SBharat Gooty * bus_id - I2C bus ID 859*48c6a6b6SBharat Gooty * 860*48c6a6b6SBharat Gooty * Return: 861*48c6a6b6SBharat Gooty * Bus speed in Hz, 0 on failure 862*48c6a6b6SBharat Gooty */ 863*48c6a6b6SBharat Gooty uint32_t i2c_get_bus_speed(uint32_t bus_id) 864*48c6a6b6SBharat Gooty { 865*48c6a6b6SBharat Gooty uint32_t regval; 866*48c6a6b6SBharat Gooty uint32_t retval = 0U; 867*48c6a6b6SBharat Gooty 868*48c6a6b6SBharat Gooty regval = iproc_i2c_reg_read(bus_id, SMB_TIMGCFG_REG); 869*48c6a6b6SBharat Gooty regval &= SMB_TIMGCFG_MODE400_MASK; 870*48c6a6b6SBharat Gooty regval >>= SMB_TIMGCFG_MODE400_SHIFT; 871*48c6a6b6SBharat Gooty 872*48c6a6b6SBharat Gooty switch (regval) { 873*48c6a6b6SBharat Gooty case IPROC_SMB_SPEED_100KHz: 874*48c6a6b6SBharat Gooty retval = I2C_SPEED_100KHz; 875*48c6a6b6SBharat Gooty break; 876*48c6a6b6SBharat Gooty 877*48c6a6b6SBharat Gooty case IPROC_SMB_SPEED_400KHz: 878*48c6a6b6SBharat Gooty retval = I2C_SPEED_400KHz; 879*48c6a6b6SBharat Gooty break; 880*48c6a6b6SBharat Gooty 881*48c6a6b6SBharat Gooty default: 882*48c6a6b6SBharat Gooty break; 883*48c6a6b6SBharat Gooty } 884*48c6a6b6SBharat Gooty return retval; 885*48c6a6b6SBharat Gooty } 886*48c6a6b6SBharat Gooty 887