[PATCH] I2C: EXYNOS5: Set up the TX FIFO and RX FIFO for HSI2C
Yuvaraj Kumar C D
yuvaraj.cd at gmail.com
Wed Apr 10 06:30:20 EDT 2013
This patch, set up TX FIFO and RX FIFO of HSI2C controller based
on i2c message length.If we configure TX and RX FIFO for a default
value,the ALMOST_EMPTY and ALMOST_FULL will rise the interrupts
unnecessary.
Signed-off-by: Yuvaraj Kumar C D <yuvaraj.cd at samsung.com>
---
drivers/i2c/busses/i2c-exynos5.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index a38c616..b25c717 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -77,9 +77,9 @@
/* I2C_FIFO_CTL Register bits */
#define HSI2C_RXFIFO_EN (1u << 0)
#define HSI2C_TXFIFO_EN (1u << 1)
-#define HSI2C_TXFIFO_TRIGGER_LEVEL (0x30 << 16)
-#define HSI2C_RXFIFO_TRIGGER_LEVEL (0x30 << 4)
-
+#define HSI2C_FIFO_MAX (0x40)
+#define HSI2C_RXFIFO_TRIGGER_LEVEL(x) ((x) << 4)
+#define HSI2C_TXFIFO_TRIGGER_LEVEL(x) ((x) << 16)
/* I2C_TRAILING_CTL Register bits */
#define HSI2C_TRAILING_COUNT (0xf)
@@ -400,10 +400,9 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
goto stop;
}
- /* 0x30 is the default trigger level for TX FIFO */
- len = 48 - fifo_level;
-
- if (len > i2c->msg->len)
+ if (i2c->msg->len > HSI2C_FIFO_MAX)
+ len = HSI2C_FIFO_MAX;
+ else
len = i2c->msg->len;
i2c->msg_len += len;
@@ -492,10 +491,11 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
u32 i2c_auto_conf = 0;
u32 fifo_ctl;
+ unsigned short len = (i2c->msg->len > HSI2C_FIFO_MAX) ?
+ HSI2C_FIFO_MAX : i2c->msg->len;
exynos5_i2c_en_timeout(i2c);
- fifo_ctl = HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN |
- HSI2C_TXFIFO_TRIGGER_LEVEL | HSI2C_RXFIFO_TRIGGER_LEVEL;
+ fifo_ctl = HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN;
writel(fifo_ctl, i2c->regs + HSI2C_FIFO_CTL);
i2c_ctl = readl(i2c->regs + HSI2C_CTL);
@@ -506,11 +506,13 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
i2c_auto_conf |= HSI2C_READ_WRITE;
+ fifo_ctl |= HSI2C_RXFIFO_TRIGGER_LEVEL(len);
int_en |= (HSI2C_INT_RX_ALMOSTFULL_EN |
HSI2C_INT_TRAILING_EN);
} else {
i2c_ctl |= HSI2C_TXCHON;
+ fifo_ctl |= HSI2C_TXFIFO_TRIGGER_LEVEL(len);
int_en |= HSI2C_INT_TX_ALMOSTEMPTY_EN;
}
@@ -519,6 +521,7 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
writel(HSI2C_SLV_ADDR_MAS(i2c->msg->addr), i2c->regs + HSI2C_ADDR);
+ writel(fifo_ctl, i2c->regs + HSI2C_FIFO_CTL);
writel(i2c_ctl, i2c->regs + HSI2C_CTL);
/* In auto mode the length of xfer cannot be 0 */
--
1.7.9.5
More information about the linux-arm-kernel
mailing list