aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-at91.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-at91.c')
-rw-r--r--drivers/i2c/busses/i2c-at91.c39
1 files changed, 15 insertions, 24 deletions
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 636fd2efad88..ff23d1bdd230 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -381,6 +381,7 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
static int at91_do_twi_transfer(struct at91_twi_dev *dev)
{
int ret;
+ unsigned long time_left;
bool has_unre_flag = dev->pdata->has_unre_flag;
dev_dbg(dev->dev, "transfer: %s %d bytes.\n",
@@ -436,9 +437,9 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
}
}
- ret = wait_for_completion_timeout(&dev->cmd_complete,
- dev->adapter.timeout);
- if (ret == 0) {
+ time_left = wait_for_completion_timeout(&dev->cmd_complete,
+ dev->adapter.timeout);
+ if (time_left == 0) {
dev_err(dev->dev, "controller timed out\n");
at91_init_twi_bus(dev);
ret = -ETIMEDOUT;
@@ -487,30 +488,10 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
if (ret < 0)
goto out;
- /*
- * The hardware can handle at most two messages concatenated by a
- * repeated start via it's internal address feature.
- */
- if (num > 2) {
- dev_err(dev->dev,
- "cannot handle more than two concatenated messages.\n");
- ret = 0;
- goto out;
- } else if (num == 2) {
+ if (num == 2) {
int internal_address = 0;
int i;
- if (msg->flags & I2C_M_RD) {
- dev_err(dev->dev, "first transfer must be write.\n");
- ret = -EINVAL;
- goto out;
- }
- if (msg->len > 3) {
- dev_err(dev->dev, "first message size must be <= 3.\n");
- ret = -EINVAL;
- goto out;
- }
-
/* 1st msg is put into the internal address, start with 2nd */
m_start = &msg[1];
for (i = 0; i < msg->len; ++i) {
@@ -540,6 +521,15 @@ out:
return ret;
}
+/*
+ * The hardware can handle at most two messages concatenated by a
+ * repeated start via it's internal address feature.
+ */
+static struct i2c_adapter_quirks at91_twi_quirks = {
+ .flags = I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | I2C_AQ_COMB_SAME_ADDR,
+ .max_comb_1st_msg_len = 3,
+};
+
static u32 at91_twi_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
@@ -777,6 +767,7 @@ static int at91_twi_probe(struct platform_device *pdev)
dev->adapter.owner = THIS_MODULE;
dev->adapter.class = I2C_CLASS_DEPRECATED;
dev->adapter.algo = &at91_twi_algorithm;
+ dev->adapter.quirks = &at91_twi_quirks;
dev->adapter.dev.parent = dev->dev;
dev->adapter.nr = pdev->id;
dev->adapter.timeout = AT91_I2C_TIMEOUT;