Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 193173
b: refs/heads/master
c: f38e66e
h: refs/heads/master
i:
  193171: 0c2d91f
v: v3
  • Loading branch information
Santosh Shilimkar authored and Ben Dooks committed May 19, 2010
1 parent bd57f03 commit aca0e70
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f0ac131a21ed13e8baaa9df6f0420f2c4b45e807
refs/heads/master: f38e66e0077659e5d2ca3858fdb26fc9b1765b9f
146 changes: 114 additions & 32 deletions trunk/drivers/i2c/busses/i2c-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,37 @@
/* I2C controller revisions present on specific hardware */
#define OMAP_I2C_REV_ON_2430 0x36
#define OMAP_I2C_REV_ON_3430 0x3C
#define OMAP_I2C_REV_ON_4430 0x40

/* timeout waiting for the controller to respond */
#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))

#define OMAP_I2C_REV_REG 0x00
#define OMAP_I2C_IE_REG 0x01
#define OMAP_I2C_STAT_REG 0x02
#define OMAP_I2C_IV_REG 0x03
/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
#define OMAP_I2C_WE_REG 0x03
#define OMAP_I2C_SYSS_REG 0x04
#define OMAP_I2C_BUF_REG 0x05
#define OMAP_I2C_CNT_REG 0x06
#define OMAP_I2C_DATA_REG 0x07
#define OMAP_I2C_SYSC_REG 0x08
#define OMAP_I2C_CON_REG 0x09
#define OMAP_I2C_OA_REG 0x0a
#define OMAP_I2C_SA_REG 0x0b
#define OMAP_I2C_PSC_REG 0x0c
#define OMAP_I2C_SCLL_REG 0x0d
#define OMAP_I2C_SCLH_REG 0x0e
#define OMAP_I2C_SYSTEST_REG 0x0f
#define OMAP_I2C_BUFSTAT_REG 0x10
enum {
OMAP_I2C_REV_REG = 0,
OMAP_I2C_IE_REG,
OMAP_I2C_STAT_REG,
OMAP_I2C_IV_REG,
OMAP_I2C_WE_REG,
OMAP_I2C_SYSS_REG,
OMAP_I2C_BUF_REG,
OMAP_I2C_CNT_REG,
OMAP_I2C_DATA_REG,
OMAP_I2C_SYSC_REG,
OMAP_I2C_CON_REG,
OMAP_I2C_OA_REG,
OMAP_I2C_SA_REG,
OMAP_I2C_PSC_REG,
OMAP_I2C_SCLL_REG,
OMAP_I2C_SCLH_REG,
OMAP_I2C_SYSTEST_REG,
OMAP_I2C_BUFSTAT_REG,
OMAP_I2C_REVNB_LO,
OMAP_I2C_REVNB_HI,
OMAP_I2C_IRQSTATUS_RAW,
OMAP_I2C_IRQENABLE_SET,
OMAP_I2C_IRQENABLE_CLR,
};

/* I2C Interrupt Enable Register (OMAP_I2C_IE): */
#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */
Expand Down Expand Up @@ -170,6 +178,7 @@ struct omap_i2c_dev {
u32 speed; /* Speed of bus in Khz */
u16 cmd_err;
u8 *buf;
u8 *regs;
size_t buf_len;
struct i2c_adapter adapter;
u8 fifo_size; /* use as flag and value
Expand All @@ -188,15 +197,64 @@ struct omap_i2c_dev {
u16 westate;
};

const static u8 reg_map[] = {
[OMAP_I2C_REV_REG] = 0x00,
[OMAP_I2C_IE_REG] = 0x01,
[OMAP_I2C_STAT_REG] = 0x02,
[OMAP_I2C_IV_REG] = 0x03,
[OMAP_I2C_WE_REG] = 0x03,
[OMAP_I2C_SYSS_REG] = 0x04,
[OMAP_I2C_BUF_REG] = 0x05,
[OMAP_I2C_CNT_REG] = 0x06,
[OMAP_I2C_DATA_REG] = 0x07,
[OMAP_I2C_SYSC_REG] = 0x08,
[OMAP_I2C_CON_REG] = 0x09,
[OMAP_I2C_OA_REG] = 0x0a,
[OMAP_I2C_SA_REG] = 0x0b,
[OMAP_I2C_PSC_REG] = 0x0c,
[OMAP_I2C_SCLL_REG] = 0x0d,
[OMAP_I2C_SCLH_REG] = 0x0e,
[OMAP_I2C_SYSTEST_REG] = 0x0f,
[OMAP_I2C_BUFSTAT_REG] = 0x10,
};

const static u8 omap4_reg_map[] = {
[OMAP_I2C_REV_REG] = 0x04,
[OMAP_I2C_IE_REG] = 0x2c,
[OMAP_I2C_STAT_REG] = 0x28,
[OMAP_I2C_IV_REG] = 0x34,
[OMAP_I2C_WE_REG] = 0x34,
[OMAP_I2C_SYSS_REG] = 0x90,
[OMAP_I2C_BUF_REG] = 0x94,
[OMAP_I2C_CNT_REG] = 0x98,
[OMAP_I2C_DATA_REG] = 0x9c,
[OMAP_I2C_SYSC_REG] = 0x20,
[OMAP_I2C_CON_REG] = 0xa4,
[OMAP_I2C_OA_REG] = 0xa8,
[OMAP_I2C_SA_REG] = 0xac,
[OMAP_I2C_PSC_REG] = 0xb0,
[OMAP_I2C_SCLL_REG] = 0xb4,
[OMAP_I2C_SCLH_REG] = 0xb8,
[OMAP_I2C_SYSTEST_REG] = 0xbC,
[OMAP_I2C_BUFSTAT_REG] = 0xc0,
[OMAP_I2C_REVNB_LO] = 0x00,
[OMAP_I2C_REVNB_HI] = 0x04,
[OMAP_I2C_IRQSTATUS_RAW] = 0x24,
[OMAP_I2C_IRQENABLE_SET] = 0x2c,
[OMAP_I2C_IRQENABLE_CLR] = 0x30,
};

static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
int reg, u16 val)
{
__raw_writew(val, i2c_dev->base + (reg << i2c_dev->reg_shift));
__raw_writew(val, i2c_dev->base +
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}

static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
{
return __raw_readw(i2c_dev->base + (reg << i2c_dev->reg_shift));
return __raw_readw(i2c_dev->base +
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}

static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
Expand Down Expand Up @@ -265,7 +323,11 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
WARN_ON(dev->idle);

dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
if (dev->rev >= OMAP_I2C_REV_ON_4430)
omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1);
else
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);

if (dev->rev < OMAP_I2C_REV_2) {
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
} else {
Expand Down Expand Up @@ -330,7 +392,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
* REVISIT: Some wkup sources might not be needed.
*/
dev->westate = OMAP_I2C_WE_ALL;
omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
if (dev->rev < OMAP_I2C_REV_ON_4430)
omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
dev->westate);
}
}
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
Expand All @@ -357,7 +421,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
psc = fclk_rate / 12000000;
}

if (cpu_is_omap2430() || cpu_is_omap34xx()) {
if (!(cpu_class_is_omap1() || cpu_is_omap2420())) {

/*
* HSI2C controller internal clk rate should be 19.2 Mhz for
Expand Down Expand Up @@ -747,9 +811,12 @@ omap_i2c_isr(int this_irq, void *dev_id)
if (dev->buf_len) {
*dev->buf++ = w;
dev->buf_len--;
/* Data reg from 2430 is 8 bit wide */
if (!cpu_is_omap2430() &&
!cpu_is_omap34xx()) {
/*
* Data reg in 2430, omap3 and
* omap4 is 8 bit wide
*/
if (cpu_class_is_omap1() ||
cpu_is_omap2420()) {
if (dev->buf_len) {
*dev->buf++ = w >> 8;
dev->buf_len--;
Expand Down Expand Up @@ -787,9 +854,12 @@ omap_i2c_isr(int this_irq, void *dev_id)
if (dev->buf_len) {
w = *dev->buf++;
dev->buf_len--;
/* Data reg from 2430 is 8 bit wide */
if (!cpu_is_omap2430() &&
!cpu_is_omap34xx()) {
/*
* Data reg in 2430, omap3 and
* omap4 is 8 bit wide
*/
if (cpu_class_is_omap1() ||
cpu_is_omap2420()) {
if (dev->buf_len) {
w |= *dev->buf++ << 8;
dev->buf_len--;
Expand Down Expand Up @@ -905,17 +975,24 @@ omap_i2c_probe(struct platform_device *pdev)

if (cpu_is_omap7xx())
dev->reg_shift = 1;
else if (cpu_is_omap44xx())
dev->reg_shift = 0;
else
dev->reg_shift = 2;

if ((r = omap_i2c_get_clocks(dev)) != 0)
goto err_iounmap;

if (cpu_is_omap44xx())
dev->regs = (u8 *) omap4_reg_map;
else
dev->regs = (u8 *) reg_map;

omap_i2c_unidle(dev);

dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;

if (cpu_is_omap2430() || cpu_is_omap34xx()) {
if (!(cpu_class_is_omap1() || cpu_is_omap2420())) {
u16 s;

/* Set up the fifo size - Get total size */
Expand All @@ -927,8 +1004,13 @@ omap_i2c_probe(struct platform_device *pdev)
* size. This is to ensure that we can handle the status on int
* call back latencies.
*/
dev->fifo_size = (dev->fifo_size / 2);
dev->b_hw = 1; /* Enable hardware fixes */
if (dev->rev >= OMAP_I2C_REV_ON_4430) {
dev->fifo_size = 0;
dev->b_hw = 0; /* Disable hardware fixes */
} else {
dev->fifo_size = (dev->fifo_size / 2);
dev->b_hw = 1; /* Enable hardware fixes */
}
}

/* reset ASAP, clearing any IRQs */
Expand Down

0 comments on commit aca0e70

Please sign in to comment.