예제 #1
0
static int pch_i2c_wait_for_check_xfer(struct i2c_algo_pch_data *adap)
{
	long ret;

	ret = wait_event_timeout(pch_event,
			(adap->pch_event_flag != 0), msecs_to_jiffies(1000));
	if (!ret) {
		pch_err(adap, "%s:wait-event timeout\n", __func__);
		adap->pch_event_flag = 0;
		pch_i2c_stop(adap);
		pch_i2c_init(adap);
		return -ETIMEDOUT;
	}

	if (adap->pch_event_flag & I2C_ERROR_MASK) {
		pch_err(adap, "Lost Arbitration\n");
		adap->pch_event_flag = 0;
		pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT);
		pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT);
		pch_i2c_init(adap);
		return -EAGAIN;
	}

	adap->pch_event_flag = 0;

	if (pch_i2c_getack(adap)) {
		pch_dbg(adap, "Receive NACK for slave address"
			"setting\n");
		return -EIO;
	}

	return 0;
}
예제 #2
0
/**
 * pch_i2c_wait_for_bus_idle() - check the status of bus.
 * @adap:	Pointer to struct i2c_algo_pch_data.
 * @timeout:	waiting time counter (ms).
 */
static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
				     s32 timeout)
{
	void __iomem *p = adap->pch_base_address;
	int schedule = 0;
	unsigned long end = jiffies + msecs_to_jiffies(timeout);

	while (ioread32(p + PCH_I2CSR) & I2CMBB_BIT) {
		if (time_after(jiffies, end)) {
			pch_dbg(adap, "I2CSR = %x\n", ioread32(p + PCH_I2CSR));
			pch_err(adap, "%s: Timeout Error.return%d\n",
					__func__, -ETIME);
			pch_i2c_init(adap);

			return -ETIME;
		}

		if (!schedule)
			/* Retry after some usecs */
			udelay(5);
		else
			/* Wait a bit more without consuming CPU */
			usleep_range(20, 1000);

		schedule = 1;
	}

	return 0;
}
/**
 * pch_i2c_writebytes() - write data to I2C bus in normal mode
 * @i2c_adap:	Pointer to the struct i2c_adapter.
 * @last:	specifies whether last message or not.
 *		In the case of compound mode it will be 1 for last message,
 *		otherwise 0.
 * @first:	specifies whether first message or not.
 *		1 for first message otherwise 0.
 */
static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
			      struct i2c_msg *msgs, u32 last, u32 first)
{
	struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
	u8 *buf;
	u32 length;
	u32 addr;
	u32 addr_2_msb;
	u32 addr_8_lsb;
	s32 wrcount;
	s32 rtn;
	void __iomem *p = adap->pch_base_address;

	length = msgs->len;
	buf = msgs->buf;
	addr = msgs->addr;

	/* enable master tx */
	pch_setbit(adap->pch_base_address, PCH_I2CCTL, I2C_TX_MODE);

	pch_dbg(adap, "I2CCTL = %x msgs->len = %d\n", ioread32(p + PCH_I2CCTL),
		length);

	if (first) {
		if (pch_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -ETIME)
			return -ETIME;
	}

	if (msgs->flags & I2C_M_TEN) {
		addr_2_msb = ((addr & I2C_MSB_2B_MSK) >> 7) & 0x06;
		iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
		if (first)
			pch_i2c_start(adap);

		rtn = pch_i2c_wait_for_xfer_complete(adap);
		if (rtn == 0) {
			if (pch_i2c_getack(adap)) {
				pch_dbg(adap, "Receive NACK for slave address"
					"setting\n");
				return -EIO;
			}
			addr_8_lsb = (addr & I2C_ADDR_MSK);
			iowrite32(addr_8_lsb, p + PCH_I2CDR);
		} else if (rtn == -EIO) { /* Arbitration Lost */
			pch_err(adap, "Lost Arbitration\n");
			pch_clrbit(adap->pch_base_address, PCH_I2CSR,
				   I2CMAL_BIT);
			pch_clrbit(adap->pch_base_address, PCH_I2CSR,
				   I2CMIF_BIT);
			pch_i2c_init(adap);
			return -EAGAIN;
		} else { /* wait-event timeout */
			pch_i2c_stop(adap);
			return -ETIME;
		}
	} else {
예제 #4
0
/**
 * pch_i2c_getack() - to confirm ACK/NACK
 * @adap:	Pointer to struct i2c_algo_pch_data.
 */
static s32 pch_i2c_getack(struct i2c_algo_pch_data *adap)
{
	u32 reg_val;
	void __iomem *p = adap->pch_base_address;
	reg_val = ioread32(p + PCH_I2CSR) & PCH_GETACK;

	if (reg_val != 0) {
		pch_err(adap, "return%d\n", -EPROTO);
		return -EPROTO;
	}

	return 0;
}
/**
 * pch_i2c_wait_for_xfer_complete() - initiates a wait for the tx complete event
 * @adap:	Pointer to struct i2c_algo_pch_data.
 */
static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
{
	long ret;
	ret = wait_event_timeout(pch_event,
			(adap->pch_event_flag != 0), msecs_to_jiffies(1000));

	if (ret == 0) {
		pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
		adap->pch_event_flag = 0;
		return -ETIMEDOUT;
	}

	if (adap->pch_event_flag & I2C_ERROR_MASK) {
		pch_err(adap, "error bits set: %x\n", adap->pch_event_flag);
		adap->pch_event_flag = 0;
		return -EIO;
	}

	adap->pch_event_flag = 0;

	return 0;
}
예제 #6
0
/**
 * pch_i2c_wait_for_bus_idle() - check the status of bus.
 * @adap:	Pointer to struct i2c_algo_pch_data.
 * @timeout:	waiting time counter (us).
 */
static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
				     s32 timeout)
{
	void __iomem *p = adap->pch_base_address;

	/* MAX timeout value is timeout*1000*1000nsec */
	ktime_t ns_val = ktime_add_ns(ktime_get(), timeout*1000*1000);
	do {
		if ((ioread32(p + PCH_I2CSR) & I2CMBB_BIT) == 0)
			break;
		msleep(20);
	} while (ktime_lt(ktime_get(), ns_val));

	pch_dbg(adap, "I2CSR = %x\n", ioread32(p + PCH_I2CSR));

	if (timeout == 0) {
		pch_err(adap, "%s: Timeout Error.return%d\n", __func__, -ETIME);
		return -ETIME;
	}

	return 0;
}