コード例 #1
0
ファイル: octeon_twsi.c プロジェクト: ryanSie/Advantech
/*-----------------------------------------------------------------------
 * 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 */
}
コード例 #2
0
ファイル: cvmx-twsi.c プロジェクト: AlickHill/Lantern
/**
 * 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;
	}