/*----------------------------------------------------------------------- * Probe to see if a chip is present using single byte read. Also good for * checking for the completion of EEPROM writes since the chip stops * responding until the write completes (typically 10mSec). */ int i2c_probe(uchar addr) { uint64_t data; unsigned int bus; #ifdef CONFIG_I2C_MULTI_BUS bus = gd->ogd.current_i2c_bus; #else bus = 0; #endif if (cvmx_twsix_read(bus, addr, 1, &data) < 0) return (1); else return (0); /* probed OK */ }
/** * Do a twsi read from a 7 bit device address using an (optional) internal address. * Up to 8 bytes can be read at a time. * * @param twsi_id which Octeon TWSI bus to use * @param dev_addr Device address (7 bit) * @param internal_addr * Internal address. Can be 0, 1 or 2 bytes in width * @param num_bytes Number of data bytes to read * @param ia_width_bytes * Internal address size in bytes (0, 1, or 2) * @param data Pointer argument where the read data is returned. * * @return read data returned in 'data' argument * Number of bytes read on success * -1 on failure */ int cvmx_twsix_read_ia(int twsi_id, uint8_t dev_addr, uint16_t internal_addr, int num_bytes, int ia_width_bytes, uint64_t *data) { #ifdef CVMX_BUILD_FOR_LINUX_KERNEL # if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) struct i2c_adapter *adapter; u8 data_buf[8]; u8 addr_buf[8]; struct i2c_msg msg[2]; uint64_t r; int i, j; if (ia_width_bytes == 0) return cvmx_twsix_read(twsi_id, dev_addr, num_bytes, data); BUG_ON(ia_width_bytes > 2); BUG_ON(num_bytes > 8 || num_bytes < 1); adapter = __cvmx_twsix_get_adapter(twsi_id); if (adapter == NULL) return -1; for (j = 0, i = ia_width_bytes - 1; i >= 0; i--, j++) addr_buf[j] = (u8)(internal_addr >> (i * 8)); msg[0].addr = dev_addr; msg[0].flags = 0; msg[0].len = ia_width_bytes; msg[0].buf = addr_buf; msg[1].addr = dev_addr; msg[1].flags = I2C_M_RD; msg[1].len = num_bytes; msg[1].buf = data_buf; i = i2c_transfer(adapter, msg, 2); i2c_put_adapter(adapter); if (i == 2) { r = 0; for (i = 0; i < num_bytes; i++) r = (r << 8) | data_buf[i]; *data = r; return num_bytes; } else { return -1; } # else BUG(); /* The I2C driver is not compiled in */ # endif #else cvmx_mio_twsx_sw_twsi_t sw_twsi_val; cvmx_mio_twsx_sw_twsi_ext_t twsi_ext; if (num_bytes < 1 || num_bytes > 8 || !data || ia_width_bytes < 0 || ia_width_bytes > 2) return -1; twsi_ext.u64 = 0; sw_twsi_val.u64 = 0; sw_twsi_val.s.v = 1; sw_twsi_val.s.r = 1; sw_twsi_val.s.sovr = 1; sw_twsi_val.s.size = num_bytes - 1; sw_twsi_val.s.a = dev_addr; if (ia_width_bytes > 0) { sw_twsi_val.s.op = 1; sw_twsi_val.s.ia = (internal_addr >> 3) & 0x1f; sw_twsi_val.s.eop_ia = internal_addr & 0x7; }