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