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.c52
1 files changed, 16 insertions, 36 deletions
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index f84a63c..b723b0b 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -469,6 +469,10 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
msleep(1);
}
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, i2c->regs + S3C2410_IICSTAT);
+ if (!(readl(i2c->regs + S3C2410_IICSTAT) & S3C2410_IICSTAT_BUSBUSY))
+ return 0;
+
return -ETIMEDOUT;
}
@@ -480,8 +484,7 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
struct i2c_msg *msgs, int num)
{
- unsigned long iicstat, timeout;
- int spins = 20;
+ unsigned long timeout;
int ret;
if (i2c->suspended)
@@ -520,21 +523,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
/* ensure the stop has been through the bus */
- dev_dbg(i2c->dev, "waiting for bus idle\n");
-
- /* first, try busy waiting briefly */
- do {
- iicstat = readl(i2c->regs + S3C2410_IICSTAT);
- } while ((iicstat & S3C2410_IICSTAT_START) && --spins);
-
- /* if that timed out sleep */
- if (!spins) {
- msleep(1);
- iicstat = readl(i2c->regs + S3C2410_IICSTAT);
- }
-
- if (iicstat & S3C2410_IICSTAT_START)
- dev_warn(i2c->dev, "timeout waiting for bus idle\n");
+ udelay(10);
out:
return ret;
@@ -661,23 +650,6 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
writel(iiccon, i2c->regs + S3C2410_IICCON);
- if (s3c24xx_i2c_is2440(i2c)) {
- unsigned long sda_delay;
-
- if (pdata->sda_delay) {
- sda_delay = clkin * pdata->sda_delay;
- sda_delay = DIV_ROUND_UP(sda_delay, 1000000);
- sda_delay = DIV_ROUND_UP(sda_delay, 5);
- if (sda_delay > 3)
- sda_delay = 3;
- sda_delay |= S3C2410_IICLC_FILTER_ON;
- } else
- sda_delay = 0;
-
- dev_dbg(i2c->dev, "IICLC=%08lx\n", sda_delay);
- writel(sda_delay, i2c->regs + S3C2440_IICLC);
- }
-
return 0;
}
@@ -694,6 +666,8 @@ static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
int delta_f;
int ret;
+ clk_enable(i2c->clk);
+
delta_f = clk_get_rate(i2c->clk) - i2c->clkrate;
/* if we're post-change and the input clock has slowed down
@@ -713,6 +687,8 @@ static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
dev_info(i2c->dev, "setting freq %d\n", got);
}
+ clk_disable(i2c->clk);
+
return 0;
}
@@ -765,7 +741,7 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
writeb(pdata->slave_addr, i2c->regs + S3C2410_IICADD);
- dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
+ dev_dbg(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
writel(iicon, i2c->regs + S3C2410_IICCON);
@@ -779,9 +755,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
/* todo - check that the i2c lines aren't being dragged anywhere */
- dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
+ dev_dbg(i2c->dev, "bus frequency set to %d KHz\n", freq);
dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
+ dev_dbg(i2c->dev, "S3C2440_IICLC=%08x\n", pdata->sda_delay);
+ writel(pdata->sda_delay, i2c->regs + S3C2440_IICLC);
+
return 0;
}
@@ -823,6 +802,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->dev = &pdev->dev;
i2c->clk = clk_get(&pdev->dev, "i2c");
+
if (IS_ERR(i2c->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
ret = -ENOENT;