diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-s3c2410.c')
-rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 48 |
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 | ||
310 | static inline int is_msglast(struct s3c24xx_i2c *i2c) | 347 | static 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 */ |