i2c: pxa: Add support for pxa910/988 & new configuration features
authorVaibhav Hiremath <vaibhav.hiremath@linaro.org>
Mon, 24 Aug 2015 05:59:36 +0000 (11:29 +0530)
committerWolfram Sang <wsa@the-dreams.de>
Sun, 25 Oct 2015 08:36:43 +0000 (09:36 +0100)
TWSI_ILCR & TWSI_IWCR registers are used to adjust clock rate
of standard & fast mode in pxa910/988; so this patch adds these two new
entries to "struct pxa_reg_layout" and "struct pxa_i2c".

Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
Signed-off-by: Yi Zhang <yizhang@marvell.com>
Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
Tested-by: Robert Jarzmik <robert.jarzmik@free.fr>
[wsa: white space fixes]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
drivers/i2c/busses/i2c-pxa.c

index 645e4b7..0d35195 100644 (file)
@@ -46,12 +46,15 @@ struct pxa_reg_layout {
        u32 icr;
        u32 isr;
        u32 isar;
+       u32 ilcr;
+       u32 iwcr;
 };
 
 enum pxa_i2c_types {
        REGS_PXA2XX,
        REGS_PXA3XX,
        REGS_CE4100,
+       REGS_PXA910,
 };
 
 /*
@@ -79,12 +82,22 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
                .isr =  0x04,
                /* no isar register */
        },
+       [REGS_PXA910] = {
+               .ibmr = 0x00,
+               .idbr = 0x08,
+               .icr =  0x10,
+               .isr =  0x18,
+               .isar = 0x20,
+               .ilcr = 0x28,
+               .iwcr = 0x30,
+       },
 };
 
 static const struct platform_device_id i2c_pxa_id_table[] = {
        { "pxa2xx-i2c",         REGS_PXA2XX },
        { "pxa3xx-pwri2c",      REGS_PXA3XX },
        { "ce4100-i2c",         REGS_CE4100 },
+       { "pxa910-i2c",         REGS_PXA910 },
        { },
 };
 MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
@@ -124,6 +137,23 @@ MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
 #define ISR_SAD                (1 << 9)           /* slave address detected */
 #define ISR_BED                (1 << 10)          /* bus error no ACK/NAK */
 
+/* bit field shift & mask */
+#define ILCR_SLV_SHIFT         0
+#define ILCR_SLV_MASK          (0x1FF << ILCR_SLV_SHIFT)
+#define ILCR_FLV_SHIFT         9
+#define ILCR_FLV_MASK          (0x1FF << ILCR_FLV_SHIFT)
+#define ILCR_HLVL_SHIFT                18
+#define ILCR_HLVL_MASK         (0x1FF << ILCR_HLVL_SHIFT)
+#define ILCR_HLVH_SHIFT                27
+#define ILCR_HLVH_MASK         (0x1F << ILCR_HLVH_SHIFT)
+
+#define IWCR_CNT_SHIFT         0
+#define IWCR_CNT_MASK          (0x1F << IWCR_CNT_SHIFT)
+#define IWCR_HS_CNT1_SHIFT     5
+#define IWCR_HS_CNT1_MASK      (0x1F << IWCR_HS_CNT1_SHIFT)
+#define IWCR_HS_CNT2_SHIFT     10
+#define IWCR_HS_CNT2_MASK      (0x1F << IWCR_HS_CNT2_SHIFT)
+
 struct pxa_i2c {
        spinlock_t              lock;
        wait_queue_head_t       wait;
@@ -150,6 +180,8 @@ struct pxa_i2c {
        void __iomem            *reg_icr;
        void __iomem            *reg_isr;
        void __iomem            *reg_isar;
+       void __iomem            *reg_ilcr;
+       void __iomem            *reg_iwcr;
 
        unsigned long           iobase;
        unsigned long           iosize;
@@ -168,6 +200,8 @@ struct pxa_i2c {
 #define _ICR(i2c)      ((i2c)->reg_icr)
 #define _ISR(i2c)      ((i2c)->reg_isr)
 #define _ISAR(i2c)     ((i2c)->reg_isar)
+#define _ILCR(i2c)     ((i2c)->reg_ilcr)
+#define _IWCR(i2c)     ((i2c)->reg_iwcr)
 
 /*
  * I2C Slave mode address
@@ -1102,7 +1136,7 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
 static const struct of_device_id i2c_pxa_dt_ids[] = {
        { .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
        { .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
-       { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX },
+       { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
        {}
 };
 MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
@@ -1203,6 +1237,11 @@ static int i2c_pxa_probe(struct platform_device *dev)
        if (i2c_type != REGS_CE4100)
                i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
 
+       if (i2c_type == REGS_PXA910) {
+               i2c->reg_ilcr = i2c->reg_base + pxa_reg_layout[i2c_type].ilcr;
+               i2c->reg_iwcr = i2c->reg_base + pxa_reg_layout[i2c_type].iwcr;
+       }
+
        i2c->iobase = res->start;
        i2c->iosize = resource_size(res);