i2c: pxa: Add support for pxa910/988 & new configuration features

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>
This commit is contained in:
Vaibhav Hiremath 2015-08-24 11:29:36 +05:30 committed by Wolfram Sang
parent 174f2366b0
commit c5fa6fc79f
1 changed files with 40 additions and 1 deletions

View 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);