aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-s3c2410.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-s3c2410.c')
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index f6b880ba1932..6e8ee92ab553 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -42,9 +42,46 @@
42 42
43#include <asm/irq.h> 43#include <asm/irq.h>
44 44
45#include <plat/regs-iic.h>
46#include <linux/platform_data/i2c-s3c2410.h> 45#include <linux/platform_data/i2c-s3c2410.h>
47 46
47/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */
48
49#define S3C2410_IICCON 0x00
50#define S3C2410_IICSTAT 0x04
51#define S3C2410_IICADD 0x08
52#define S3C2410_IICDS 0x0C
53#define S3C2440_IICLC 0x10
54
55#define S3C2410_IICCON_ACKEN (1 << 7)
56#define S3C2410_IICCON_TXDIV_16 (0 << 6)
57#define S3C2410_IICCON_TXDIV_512 (1 << 6)
58#define S3C2410_IICCON_IRQEN (1 << 5)
59#define S3C2410_IICCON_IRQPEND (1 << 4)
60#define S3C2410_IICCON_SCALE(x) ((x) & 0xf)
61#define S3C2410_IICCON_SCALEMASK (0xf)
62
63#define S3C2410_IICSTAT_MASTER_RX (2 << 6)
64#define S3C2410_IICSTAT_MASTER_TX (3 << 6)
65#define S3C2410_IICSTAT_SLAVE_RX (0 << 6)
66#define S3C2410_IICSTAT_SLAVE_TX (1 << 6)
67#define S3C2410_IICSTAT_MODEMASK (3 << 6)
68
69#define S3C2410_IICSTAT_START (1 << 5)
70#define S3C2410_IICSTAT_BUSBUSY (1 << 5)
71#define S3C2410_IICSTAT_TXRXEN (1 << 4)
72#define S3C2410_IICSTAT_ARBITR (1 << 3)
73#define S3C2410_IICSTAT_ASSLAVE (1 << 2)
74#define S3C2410_IICSTAT_ADDR0 (1 << 1)
75#define S3C2410_IICSTAT_LASTBIT (1 << 0)
76
77#define S3C2410_IICLC_SDA_DELAY0 (0 << 0)
78#define S3C2410_IICLC_SDA_DELAY5 (1 << 0)
79#define S3C2410_IICLC_SDA_DELAY10 (2 << 0)
80#define S3C2410_IICLC_SDA_DELAY15 (3 << 0)
81#define S3C2410_IICLC_SDA_DELAY_MASK (3 << 0)
82
83#define S3C2410_IICLC_FILTER_ON (1 << 2)
84
48/* Treat S3C2410 as baseline hardware, anything else is supported via quirks */ 85/* Treat S3C2410 as baseline hardware, anything else is supported via quirks */
49#define QUIRK_S3C2440 (1 << 0) 86#define QUIRK_S3C2440 (1 << 0)
50#define QUIRK_HDMIPHY (1 << 1) 87#define QUIRK_HDMIPHY (1 << 1)
@@ -309,6 +346,12 @@ static inline int is_lastmsg(struct s3c24xx_i2c *i2c)
309 346
310static inline int is_msglast(struct s3c24xx_i2c *i2c) 347static inline int is_msglast(struct s3c24xx_i2c *i2c)
311{ 348{
349 /* msg->len is always 1 for the first byte of smbus block read.
350 * Actual length will be read from slave. More bytes will be
351 * read according to the length then. */
352 if (i2c->msg->flags & I2C_M_RECV_LEN && i2c->msg->len == 1)
353 return 0;
354
312 return i2c->msg_ptr == i2c->msg->len-1; 355 return i2c->msg_ptr == i2c->msg->len-1;
313} 356}
314 357
@@ -448,6 +491,9 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
448 byte = readb(i2c->regs + S3C2410_IICDS); 491 byte = readb(i2c->regs + S3C2410_IICDS);
449 i2c->msg->buf[i2c->msg_ptr++] = byte; 492 i2c->msg->buf[i2c->msg_ptr++] = byte;
450 493
494 /* Add actual length to read for smbus block read */
495 if (i2c->msg->flags & I2C_M_RECV_LEN && i2c->msg->len == 1)
496 i2c->msg->len += byte;
451 prepare_read: 497 prepare_read:
452 if (is_msglast(i2c)) { 498 if (is_msglast(i2c)) {
453 /* last byte of buffer */ 499 /* last byte of buffer */