aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-tegra.c')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index b4ab39b741eb..4d9319665e32 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -35,8 +35,10 @@
35#define BYTES_PER_FIFO_WORD 4 35#define BYTES_PER_FIFO_WORD 4
36 36
37#define I2C_CNFG 0x000 37#define I2C_CNFG 0x000
38#define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12
38#define I2C_CNFG_PACKET_MODE_EN (1<<10) 39#define I2C_CNFG_PACKET_MODE_EN (1<<10)
39#define I2C_CNFG_NEW_MASTER_FSM (1<<11) 40#define I2C_CNFG_NEW_MASTER_FSM (1<<11)
41#define I2C_STATUS 0x01C
40#define I2C_SL_CNFG 0x020 42#define I2C_SL_CNFG 0x020
41#define I2C_SL_CNFG_NEWSL (1<<2) 43#define I2C_SL_CNFG_NEWSL (1<<2)
42#define I2C_SL_ADDR1 0x02c 44#define I2C_SL_ADDR1 0x02c
@@ -77,6 +79,7 @@
77#define I2C_ERR_NONE 0x00 79#define I2C_ERR_NONE 0x00
78#define I2C_ERR_NO_ACK 0x01 80#define I2C_ERR_NO_ACK 0x01
79#define I2C_ERR_ARBITRATION_LOST 0x02 81#define I2C_ERR_ARBITRATION_LOST 0x02
82#define I2C_ERR_UNKNOWN_INTERRUPT 0x04
80 83
81#define PACKET_HEADER0_HEADER_SIZE_SHIFT 28 84#define PACKET_HEADER0_HEADER_SIZE_SHIFT 28
82#define PACKET_HEADER0_PACKET_ID_SHIFT 16 85#define PACKET_HEADER0_PACKET_ID_SHIFT 16
@@ -121,6 +124,7 @@ struct tegra_i2c_dev {
121 void __iomem *base; 124 void __iomem *base;
122 int cont_id; 125 int cont_id;
123 int irq; 126 int irq;
127 bool irq_disabled;
124 int is_dvc; 128 int is_dvc;
125 struct completion msg_complete; 129 struct completion msg_complete;
126 int msg_err; 130 int msg_err;
@@ -325,11 +329,17 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
325 if (i2c_dev->is_dvc) 329 if (i2c_dev->is_dvc)
326 tegra_dvc_init(i2c_dev); 330 tegra_dvc_init(i2c_dev);
327 331
328 val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN; 332 val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
333 (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
329 i2c_writel(i2c_dev, val, I2C_CNFG); 334 i2c_writel(i2c_dev, val, I2C_CNFG);
330 i2c_writel(i2c_dev, 0, I2C_INT_MASK); 335 i2c_writel(i2c_dev, 0, I2C_INT_MASK);
331 clk_set_rate(i2c_dev->clk, i2c_dev->bus_clk_rate * 8); 336 clk_set_rate(i2c_dev->clk, i2c_dev->bus_clk_rate * 8);
332 337
338 if (!i2c_dev->is_dvc) {
339 u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
340 i2c_writel(i2c_dev, sl_cfg | I2C_SL_CNFG_NEWSL, I2C_SL_CNFG);
341 }
342
333 val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT | 343 val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
334 0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT; 344 0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT;
335 i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL); 345 i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
@@ -338,6 +348,12 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
338 err = -ETIMEDOUT; 348 err = -ETIMEDOUT;
339 349
340 clk_disable(i2c_dev->clk); 350 clk_disable(i2c_dev->clk);
351
352 if (i2c_dev->irq_disabled) {
353 i2c_dev->irq_disabled = 0;
354 enable_irq(i2c_dev->irq);
355 }
356
341 return err; 357 return err;
342} 358}
343 359
@@ -350,8 +366,19 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
350 status = i2c_readl(i2c_dev, I2C_INT_STATUS); 366 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
351 367
352 if (status == 0) { 368 if (status == 0) {
353 dev_warn(i2c_dev->dev, "interrupt with no status\n"); 369 dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n",
354 return IRQ_NONE; 370 i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
371 i2c_readl(i2c_dev, I2C_STATUS),
372 i2c_readl(i2c_dev, I2C_CNFG));
373 i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
374
375 if (!i2c_dev->irq_disabled) {
376 disable_irq_nosync(i2c_dev->irq);
377 i2c_dev->irq_disabled = 1;
378 }
379
380 complete(&i2c_dev->msg_complete);
381 goto err;
355 } 382 }
356 383
357 if (unlikely(status & status_err)) { 384 if (unlikely(status & status_err)) {
@@ -391,6 +418,8 @@ err:
391 I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ | 418 I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |
392 I2C_INT_RX_FIFO_DATA_REQ); 419 I2C_INT_RX_FIFO_DATA_REQ);
393 i2c_writel(i2c_dev, status, I2C_INT_STATUS); 420 i2c_writel(i2c_dev, status, I2C_INT_STATUS);
421 if (i2c_dev->is_dvc)
422 dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
394 return IRQ_HANDLED; 423 return IRQ_HANDLED;
395} 424}
396 425
@@ -424,12 +453,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
424 453
425 packet_header = msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT; 454 packet_header = msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
426 packet_header |= I2C_HEADER_IE_ENABLE; 455 packet_header |= I2C_HEADER_IE_ENABLE;
456 if (!stop)
457 packet_header |= I2C_HEADER_REPEAT_START;
427 if (msg->flags & I2C_M_TEN) 458 if (msg->flags & I2C_M_TEN)
428 packet_header |= I2C_HEADER_10BIT_ADDR; 459 packet_header |= I2C_HEADER_10BIT_ADDR;
429 if (msg->flags & I2C_M_IGNORE_NAK) 460 if (msg->flags & I2C_M_IGNORE_NAK)
430 packet_header |= I2C_HEADER_CONT_ON_NAK; 461 packet_header |= I2C_HEADER_CONT_ON_NAK;
431 if (msg->flags & I2C_M_NOSTART)
432 packet_header |= I2C_HEADER_REPEAT_START;
433 if (msg->flags & I2C_M_RD) 462 if (msg->flags & I2C_M_RD)
434 packet_header |= I2C_HEADER_READ; 463 packet_header |= I2C_HEADER_READ;
435 i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); 464 i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);