Exemple #1
0
/*
 * Waiting on Bus Busy
 */
static int i2c_davinci_wait_for_bb(char allow_sleep)
{
	unsigned long timeout;

	timeout = jiffies + DAVINCI_I2C_TIMEOUT;
	while ((i2c_davinci_dev.regs->icstr) & DAVINCI_I2C_ICSTR_BB_MASK) {
		if (time_after(jiffies, timeout)) {
			i2c_warn("timeout waiting for bus ready, send stop bit.");

                        if ( allow_sleep ) {
                            init_completion( &i2c_davinci_dev.cmd_completion );
                        }

                        /* The BB bit can become stuck high is the I2C is reset */
                        /* while the SCL line is low, */
                        /* In a single-master system, we can safely send out a STOP here. */
                        i2c_davinci_dev.regs->icmdr = 
                            DAVINCI_I2C_ICMDR_TRX_MASK |
                            DAVINCI_I2C_ICMDR_IRS_MASK | DAVINCI_I2C_ICMDR_MST_MASK |
                            DAVINCI_I2C_ICMDR_RM_MASK | DAVINCI_I2C_ICMDR_STP_MASK;

                        if ( allow_sleep ) {
                            /* wait for the transaction to complete */
                            (void) wait_for_completion_interruptible_timeout( &i2c_davinci_dev.cmd_completion, 
                                                   DAVINCI_I2C_TIMEOUT );
                        }
                        i2c_davinci_dev.regs->icstr |= DAVINCI_I2C_ICSTR_BB_MASK;
			return -ETIMEDOUT;
		}
		if (allow_sleep)
			schedule_timeout(1);
	}

	return 0;
}
Exemple #2
0
/*
 * Waiting on Bus Busy
 */
static int i2c_davinci_wait_for_bb(char allow_sleep, struct i2c_adapter *adap)
{
	unsigned long timeout;
	struct i2c_davinci_device *dev = i2c_get_adapdata(adap);
	int i;
	static	char to_cnt = 0;

	timeout = jiffies + DAVINCI_I2C_TIMEOUT;
	while ((i2c_davinci_dev.regs->icstr) & DAVINCI_I2C_ICSTR_BB_MASK) {
		if (to_cnt <= 2) {
			if (time_after(jiffies, timeout)) {
				i2c_warn("timeout waiting for bus ready");
				to_cnt ++;
				return -ETIMEDOUT;
			}
		} else if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {

			to_cnt = 0;
			/* Send the NACK to the slave */
			dev->regs->icmdr |= DAVINCI_I2C_ICMDR_NACKMOD_MASK;
			/* Disable I2C */
			disable_i2c_pins();
			
			for (i = 0; i < 10; i++)
				pulse_i2c_clock();

			/* Re-enable I2C */
			enable_i2c_pins();
			i2c_davinci_reset(dev);
			dev->cmd_complete = 0;
			return -ETIMEDOUT;
		}
		if (allow_sleep)
			schedule_timeout(1);
	}

	return 0;
}
Exemple #3
0
/*
 * Interrupt service routine. This gets called whenever an I2C interrupt
 * occurs.
 */
static irqreturn_t
i2c_davinci_isr(int this_irq, void *dev_id, struct pt_regs *reg)
{
	struct i2c_davinci_device *dev = dev_id;
	u32 stat;

	DEB1("i2c_davinci_isr()\n");

	while ((stat = dev->regs->icivr) != 0) {
//                printk( "\t%02x\n", stat );
		switch (stat) {
		case DAVINCI_I2C_ICIVR_INTCODE_AL:
			dev->cmd_err |= DAVINCI_I2C_ICSTR_AL_MASK;
			i2c_davinci_complete_cmd(dev);
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_NACK:
			dev->cmd_err |= DAVINCI_I2C_ICSTR_NACK_MASK;
			i2c_davinci_complete_cmd(dev);
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_RAR:
                        dev->regs->icstr |= DAVINCI_I2C_ICSTR_ARDY_MASK;
                        i2c_davinci_complete_cmd( dev );
                        break;

		case DAVINCI_I2C_ICIVR_INTCODE_RDR:
			if (dev->buf_len) {
				*dev->buf++ = dev->regs->icdrr;
				dev->buf_len--;
				if (dev->buf_len) {
					continue;
				} else {
					dev->regs->icimr &=
					    ~DAVINCI_I2C_ICIMR_ICRRDY_MASK;
				}
			}
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_TDR:
			if (dev->buf_len) {
				dev->regs->icdxr = *dev->buf++;
				dev->buf_len--;
				if (dev->buf_len)
					continue;
				else {
					dev->regs->icimr &=
					    ~DAVINCI_I2C_ICIMR_ICXRDY_MASK;
                                        /* If no stop bit, then we are done ... */
                                        if ( !(dev->regs->icmdr & DAVINCI_I2C_ICMDR_STP_MASK) ) {
                                            i2c_davinci_complete_cmd( dev );
                                        }
				}
			}
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_SCD:
                        dev->regs->icstr |= DAVINCI_I2C_ICSTR_SCD_MASK;
                        i2c_davinci_complete_cmd(dev);
                        break;

		case DAVINCI_I2C_ICIVR_INTCODE_AAS:
			i2c_warn("Address as slave interrupt");
			break;

		default:
                    printk( "Unknown status 0x%04x\n", stat );
			break;
		}		/* switch */
	}			/* while */
	return IRQ_HANDLED;
}
Exemple #4
0
/*
 * Interrupt service routine. This gets called whenever an I2C interrupt
 * occurs.
 */
static irqreturn_t
i2c_davinci_isr(int this_irq, void *dev_id, struct pt_regs *reg)
{
	struct i2c_davinci_device *dev = dev_id;
	u32 stat;

	DEB1("i2c_davinci_isr()");

	while ((stat = dev->regs->icivr) != 0) {
		switch (stat) {
		case DAVINCI_I2C_ICIVR_INTCODE_AL:
			dev->cmd_err |= DAVINCI_I2C_ICSTR_AL_MASK;
			i2c_warn("i2c: AL detected");
			i2c_davinci_complete_cmd(dev);
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_NACK:
			dev->cmd_err |= DAVINCI_I2C_ICSTR_NACK_MASK;
			i2c_warn("i2c: NACK detected");
			i2c_davinci_complete_cmd(dev);
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_RAR:
			dev->regs->icstr |= DAVINCI_I2C_ICSTR_ARDY_MASK;
			i2c_davinci_complete_cmd(dev);
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_RDR:
			if (dev->buf_len) {
				*dev->buf++ = dev->regs->icdrr;
				dev->buf_len--;
				if (dev->buf_len) {
					continue;
				} else {
					dev->regs->icimr &=
					    ~DAVINCI_I2C_ICIMR_ICRRDY_MASK;
				}
			}
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_TDR:
			if (dev->buf_len) {
				dev->regs->icdxr = *dev->buf++;
				dev->buf_len--;
				if (dev->buf_len)
					continue;
				else {
					dev->regs->icimr &=
					    ~DAVINCI_I2C_ICIMR_ICXRDY_MASK;
				}
			}
			break;

		case DAVINCI_I2C_ICIVR_INTCODE_SCD:
                        dev->regs->icstr |= DAVINCI_I2C_ICSTR_SCD_MASK;
                        i2c_davinci_complete_cmd(dev);
                        break;

		case DAVINCI_I2C_ICIVR_INTCODE_AAS:
			i2c_warn("i2c: AAS detected");
			break;

		default:
                        i2c_warn("i2c: unknown status: %d", stat);
			break;
		}		/* switch */
	}			/* while */
	return IRQ_HANDLED;
}
Exemple #5
0
/*
 * Low level master read/write transaction. This function is called
 * from i2c_davinci_xfer.
 */
static int
i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
{
	struct i2c_davinci_device *dev = i2c_get_adapdata(adap);
	u8 zero_byte = 0;
	u32 flag = 0, stat = 0;
	int i;

	DEB1("addr: 0x%04x, len: %d, flags: 0x%x, stop: %d",
	     msg->addr, msg->len, msg->flags, stop);

	/* Introduce a 100musec delay.  Required for Davinci EVM board only */
	if (cpu_is_davinci_dm644x())
		udelay(100);

	/* set the slave address */
	dev->regs->icsar = msg->addr;

	/* Sigh, seems we can't do zero length transactions. Thus, we
	 * can't probe for devices w/o actually sending/receiving at least
	 * a single byte. So we'll set count to 1 for the zero length
	 * transaction case and hope we don't cause grief for some
	 * arbitrary device due to random byte write/read during
	 * probes.
	 */
	if (msg->len == 0) {
		dev->buf = &zero_byte;
		dev->buf_len = 1;
	} else {
		dev->buf = msg->buf;
		dev->buf_len = msg->len;
	}

	dev->regs->iccnt = dev->buf_len;
	dev->cmd_complete = 0;
	dev->cmd_err = 0;

	/* Clear any pending interrupts by reading the IVR */
	stat = dev->regs->icivr;

	/* Take I2C out of reset, configure it as master and set the start bit */
	flag =
	    DAVINCI_I2C_ICMDR_IRS_MASK | DAVINCI_I2C_ICMDR_MST_MASK |
	    DAVINCI_I2C_ICMDR_STT_MASK;

	/* if the slave address is ten bit address, enable XA bit */
	if (msg->flags & I2C_M_TEN)
		flag |= DAVINCI_I2C_ICMDR_XA_MASK;
	if (!(msg->flags & I2C_M_RD))
		flag |= DAVINCI_I2C_ICMDR_TRX_MASK;
	if (stop)
		flag |= DAVINCI_I2C_ICMDR_STP_MASK;

	/* Enable receive and transmit interrupts */
	if (msg->flags & I2C_M_RD)
		dev->regs->icimr |= DAVINCI_I2C_ICIMR_ICRRDY_MASK;
	else
		dev->regs->icimr |= DAVINCI_I2C_ICIMR_ICXRDY_MASK;

	/* write the data into mode register */
	dev->regs->icmdr = flag;

	/* wait for the transaction to complete */
	wait_event_timeout (dev->cmd_wait, dev->cmd_complete, DAVINCI_I2C_TIMEOUT);

	dev->buf_len = 0;

	if (!dev->cmd_complete) {
		i2c_warn("i2c: cmd complete failed: complete = 0x%x, \
			  icstr = 0x%x\n", dev->cmd_complete,
			  dev->regs->icstr);

		if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
			/* Send the NACK to the slave */
			dev->regs->icmdr |= DAVINCI_I2C_ICMDR_NACKMOD_MASK;
			/* Disable I2C */
			disable_i2c_pins();

			/* Send high and low on the SCL line */
			for (i = 0; i < 10; i++)
				pulse_i2c_clock();

			/* Re-enable I2C */
			enable_i2c_pins();
		}


		i2c_davinci_reset(dev);
		dev->cmd_complete = 0;
		return -ETIMEDOUT;
	}
	dev->cmd_complete = 0;

	/* no error */
	if (!dev->cmd_err)
		return msg->len;

	/* We have an error */
	if (dev->cmd_err & DAVINCI_I2C_ICSTR_NACK_MASK) {
		if (msg->flags & I2C_M_IGNORE_NAK)
			return msg->len;
		if (stop)
			dev->regs->icmdr |= DAVINCI_I2C_ICMDR_STP_MASK;
		return -EREMOTEIO;
	}
	if (dev->cmd_err & DAVINCI_I2C_ICSTR_AL_MASK) {
		i2c_davinci_reset(dev);
		return -EIO;
	}
	return msg->len;
}