Merge branch 'for-2636/i2c/nuc' into next-i2c
[sfrench/cifs-2.6.git] / drivers / i2c / busses / i2c-davinci.c
index 4523364e67221d3930cb3fd5c6ceb65b7fab7d4e..2222c87876b97bc711b6d739fd4a82deef7db330 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/cpufreq.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
-
 #include <mach/i2c.h>
 
 /* ----- global defines ----------------------------------------------- */
 
 #define DAVINCI_I2C_TIMEOUT    (1*HZ)
+#define DAVINCI_I2C_MAX_TRIES  2
 #define I2C_DAVINCI_INTR_ALL    (DAVINCI_I2C_IMR_AAS | \
                                 DAVINCI_I2C_IMR_SCD | \
                                 DAVINCI_I2C_IMR_ARDY | \
 #define DAVINCI_I2C_IVR_NACK   0x02
 #define DAVINCI_I2C_IVR_AL     0x01
 
-#define DAVINCI_I2C_STR_BB     (1 << 12)
-#define DAVINCI_I2C_STR_RSFULL (1 << 11)
-#define DAVINCI_I2C_STR_SCD    (1 << 5)
-#define DAVINCI_I2C_STR_ARDY   (1 << 2)
-#define DAVINCI_I2C_STR_NACK   (1 << 1)
-#define DAVINCI_I2C_STR_AL     (1 << 0)
-
-#define DAVINCI_I2C_MDR_NACK   (1 << 15)
-#define DAVINCI_I2C_MDR_STT    (1 << 13)
-#define DAVINCI_I2C_MDR_STP    (1 << 11)
-#define DAVINCI_I2C_MDR_MST    (1 << 10)
-#define DAVINCI_I2C_MDR_TRX    (1 << 9)
-#define DAVINCI_I2C_MDR_XA     (1 << 8)
-#define DAVINCI_I2C_MDR_RM     (1 << 7)
-#define DAVINCI_I2C_MDR_IRS    (1 << 5)
-
-#define DAVINCI_I2C_IMR_AAS    (1 << 6)
-#define DAVINCI_I2C_IMR_SCD    (1 << 5)
-#define DAVINCI_I2C_IMR_XRDY   (1 << 4)
-#define DAVINCI_I2C_IMR_RRDY   (1 << 3)
-#define DAVINCI_I2C_IMR_ARDY   (1 << 2)
-#define DAVINCI_I2C_IMR_NACK   (1 << 1)
-#define DAVINCI_I2C_IMR_AL     (1 << 0)
-
-#define MOD_REG_BIT(val, mask, set) do { \
-       if (set) { \
-               val |= mask; \
-       } else { \
-               val &= ~mask; \
-       } \
-} while (0)
+#define DAVINCI_I2C_STR_BB     BIT(12)
+#define DAVINCI_I2C_STR_RSFULL BIT(11)
+#define DAVINCI_I2C_STR_SCD    BIT(5)
+#define DAVINCI_I2C_STR_ARDY   BIT(2)
+#define DAVINCI_I2C_STR_NACK   BIT(1)
+#define DAVINCI_I2C_STR_AL     BIT(0)
+
+#define DAVINCI_I2C_MDR_NACK   BIT(15)
+#define DAVINCI_I2C_MDR_STT    BIT(13)
+#define DAVINCI_I2C_MDR_STP    BIT(11)
+#define DAVINCI_I2C_MDR_MST    BIT(10)
+#define DAVINCI_I2C_MDR_TRX    BIT(9)
+#define DAVINCI_I2C_MDR_XA     BIT(8)
+#define DAVINCI_I2C_MDR_RM     BIT(7)
+#define DAVINCI_I2C_MDR_IRS    BIT(5)
+
+#define DAVINCI_I2C_IMR_AAS    BIT(6)
+#define DAVINCI_I2C_IMR_SCD    BIT(5)
+#define DAVINCI_I2C_IMR_XRDY   BIT(4)
+#define DAVINCI_I2C_IMR_RRDY   BIT(3)
+#define DAVINCI_I2C_IMR_ARDY   BIT(2)
+#define DAVINCI_I2C_IMR_NACK   BIT(1)
+#define DAVINCI_I2C_IMR_AL     BIT(0)
 
 struct davinci_i2c_dev {
        struct device           *dev;
@@ -113,8 +107,13 @@ struct davinci_i2c_dev {
        u8                      *buf;
        size_t                  buf_len;
        int                     irq;
+       int                     stop;
        u8                      terminate;
        struct i2c_adapter      adapter;
+#ifdef CONFIG_CPU_FREQ
+       struct completion       xfr_complete;
+       struct notifier_block   freq_transition;
+#endif
 };
 
 /* default platform data to use if not supplied in the platform_device */
@@ -134,12 +133,59 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
        return __raw_readw(i2c_dev->base + reg);
 }
 
-/*
- * This functions configures I2C and brings I2C out of reset.
- * This function is called during I2C init function. This function
- * also gets called if I2C encounters any errors.
+/* Generate a pulse on the i2c clock pin. */
+static void generic_i2c_clock_pulse(unsigned int scl_pin)
+{
+       u16 i;
+
+       if (scl_pin) {
+               /* Send high and low on the SCL line */
+               for (i = 0; i < 9; i++) {
+                       gpio_set_value(scl_pin, 0);
+                       udelay(20);
+                       gpio_set_value(scl_pin, 1);
+                       udelay(20);
+               }
+       }
+}
+
+/* This routine does i2c bus recovery as specified in the
+ * i2c protocol Rev. 03 section 3.16 titled "Bus clear"
  */
-static int i2c_davinci_init(struct davinci_i2c_dev *dev)
+static void i2c_recover_bus(struct davinci_i2c_dev *dev)
+{
+       u32 flag = 0;
+       struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+
+       dev_err(dev->dev, "initiating i2c bus recovery\n");
+       /* Send NACK to the slave */
+       flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
+       flag |=  DAVINCI_I2C_MDR_NACK;
+       /* write the data into mode register */
+       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+       if (pdata)
+               generic_i2c_clock_pulse(pdata->scl_pin);
+       /* Send STOP */
+       flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
+       flag |= DAVINCI_I2C_MDR_STP;
+       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+}
+
+static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
+                                                               int val)
+{
+       u16 w;
+
+       w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
+       if (!val)       /* put I2C into reset */
+               w &= ~DAVINCI_I2C_MDR_IRS;
+       else            /* take I2C out of reset */
+               w |= DAVINCI_I2C_MDR_IRS;
+
+       davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
+}
+
+static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 {
        struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
        u16 psc;
@@ -148,15 +194,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
        u32 clkh;
        u32 clkl;
        u32 input_clock = clk_get_rate(dev->clk);
-       u16 w;
-
-       if (!pdata)
-               pdata = &davinci_i2c_platform_data_default;
-
-       /* put I2C into reset */
-       w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
-       MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
-       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
 
        /* NOTE: I2C Clock divider programming info
         * As per I2C specs the following formulas provide prescaler
@@ -188,12 +225,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
        davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
        davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
 
+       dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
+}
+
+/*
+ * This function configures I2C and brings I2C out of reset.
+ * This function is called during I2C init function. This function
+ * also gets called if I2C encounters any errors.
+ */
+static int i2c_davinci_init(struct davinci_i2c_dev *dev)
+{
+       struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+
+       if (!pdata)
+               pdata = &davinci_i2c_platform_data_default;
+
+       /* put I2C into reset */
+       davinci_i2c_reset_ctrl(dev, 0);
+
+       /* compute clock dividers */
+       i2c_davinci_calc_clk_dividers(dev);
+
        /* Respond at reserved "SMBus Host" slave address" (and zero);
         * we seem to have no option to not respond...
         */
        davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
 
-       dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
        dev_dbg(dev->dev, "PSC  = %d\n",
                davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
        dev_dbg(dev->dev, "CLKL = %d\n",
@@ -204,9 +261,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
                pdata->bus_freq, pdata->bus_delay);
 
        /* Take the I2C module out of reset: */
-       w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
-       MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
-       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
+       davinci_i2c_reset_ctrl(dev, 1);
 
        /* Enable interrupts */
        davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);
@@ -221,14 +276,22 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
                                         char allow_sleep)
 {
        unsigned long timeout;
+       static u16 to_cnt;
 
        timeout = jiffies + dev->adapter.timeout;
        while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
               & DAVINCI_I2C_STR_BB) {
-               if (time_after(jiffies, timeout)) {
-                       dev_warn(dev->dev,
-                                "timeout waiting for bus ready\n");
-                       return -ETIMEDOUT;
+               if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
+                       if (time_after(jiffies, timeout)) {
+                               dev_warn(dev->dev,
+                               "timeout waiting for bus ready\n");
+                               to_cnt++;
+                               return -ETIMEDOUT;
+                       } else {
+                               to_cnt = 0;
+                               i2c_recover_bus(dev);
+                               i2c_davinci_init(dev);
+                       }
                }
                if (allow_sleep)
                        schedule_timeout(1);
@@ -250,9 +313,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
        u16 w;
        int r;
 
-       if (msg->len == 0)
-               return -EINVAL;
-
        if (!pdata)
                pdata = &davinci_i2c_platform_data_default;
        /* Introduce a delay, required for some boards (e.g Davinci EVM) */
@@ -264,6 +324,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 
        dev->buf = msg->buf;
        dev->buf_len = msg->len;
+       dev->stop = stop;
 
        davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len);
 
@@ -281,23 +342,40 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
                flag |= DAVINCI_I2C_MDR_TRX;
        if (stop)
                flag |= DAVINCI_I2C_MDR_STP;
+       if (msg->len == 0) {
+               flag |= DAVINCI_I2C_MDR_RM;
+               flag &= ~DAVINCI_I2C_MDR_STP;
+       }
 
        /* Enable receive or transmit interrupts */
        w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
        if (msg->flags & I2C_M_RD)
-               MOD_REG_BIT(w, DAVINCI_I2C_IMR_RRDY, 1);
+               w |= DAVINCI_I2C_IMR_RRDY;
        else
-               MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 1);
+               w |= DAVINCI_I2C_IMR_XRDY;
        davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w);
 
        dev->terminate = 0;
+
        /* write the data into mode register */
        davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
 
+       /*
+        * First byte should be set here, not after interrupt,
+        * because transmit-data-ready interrupt can come before
+        * NACK-interrupt during sending of previous message and
+        * ICDXR may have wrong data
+        */
+       if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) {
+               davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++);
+               dev->buf_len--;
+       }
+
        r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
                                                      dev->adapter.timeout);
        if (r == 0) {
                dev_err(dev->dev, "controller timed out\n");
+               i2c_recover_bus(dev);
                i2c_davinci_init(dev);
                dev->buf_len = 0;
                return -ETIMEDOUT;
@@ -334,7 +412,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
                        return msg->len;
                if (stop) {
                        w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
-                       MOD_REG_BIT(w, DAVINCI_I2C_MDR_STP, 1);
+                       w |= DAVINCI_I2C_MDR_STP;
                        davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
                }
                return -EREMOTEIO;
@@ -367,12 +445,17 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
                if (ret < 0)
                        return ret;
        }
+
+#ifdef CONFIG_CPU_FREQ
+       complete(&dev->xfr_complete);
+#endif
+
        return num;
 }
 
 static u32 i2c_davinci_func(struct i2c_adapter *adap)
 {
-       return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
 static void terminate_read(struct davinci_i2c_dev *dev)
@@ -431,6 +514,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
                case DAVINCI_I2C_IVR_ARDY:
                        davinci_i2c_write_reg(dev,
                                DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY);
+                       if (((dev->buf_len == 0) && (dev->stop != 0)) ||
+                           (dev->cmd_err & DAVINCI_I2C_STR_NACK)) {
+                               w = davinci_i2c_read_reg(dev,
+                                                        DAVINCI_I2C_MDR_REG);
+                               w |= DAVINCI_I2C_MDR_STP;
+                               davinci_i2c_write_reg(dev,
+                                                     DAVINCI_I2C_MDR_REG, w);
+                       }
                        complete(&dev->cmd_complete);
                        break;
 
@@ -462,7 +553,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
 
                                w = davinci_i2c_read_reg(dev,
                                                         DAVINCI_I2C_IMR_REG);
-                               MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 0);
+                               w &= ~DAVINCI_I2C_IMR_XRDY;
                                davinci_i2c_write_reg(dev,
                                                      DAVINCI_I2C_IMR_REG,
                                                      w);
@@ -491,6 +582,48 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
        return count ? IRQ_HANDLED : IRQ_NONE;
 }
 
+#ifdef CONFIG_CPU_FREQ
+static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
+                                    unsigned long val, void *data)
+{
+       struct davinci_i2c_dev *dev;
+
+       dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
+       if (val == CPUFREQ_PRECHANGE) {
+               wait_for_completion(&dev->xfr_complete);
+               davinci_i2c_reset_ctrl(dev, 0);
+       } else if (val == CPUFREQ_POSTCHANGE) {
+               i2c_davinci_calc_clk_dividers(dev);
+               davinci_i2c_reset_ctrl(dev, 1);
+       }
+
+       return 0;
+}
+
+static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
+{
+       dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition;
+
+       return cpufreq_register_notifier(&dev->freq_transition,
+                                        CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
+{
+       cpufreq_unregister_notifier(&dev->freq_transition,
+                                   CPUFREQ_TRANSITION_NOTIFIER);
+}
+#else
+static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
+{
+       return 0;
+}
+
+static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
+{
+}
+#endif
+
 static struct i2c_algorithm i2c_davinci_algo = {
        .master_xfer    = i2c_davinci_xfer,
        .functionality  = i2c_davinci_func,
@@ -530,6 +663,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
        }
 
        init_completion(&dev->cmd_complete);
+#ifdef CONFIG_CPU_FREQ
+       init_completion(&dev->xfr_complete);
+#endif
        dev->dev = get_device(&pdev->dev);
        dev->irq = irq->start;
        platform_set_drvdata(pdev, dev);
@@ -541,7 +677,12 @@ static int davinci_i2c_probe(struct platform_device *pdev)
        }
        clk_enable(dev->clk);
 
-       dev->base = (void __iomem *)IO_ADDRESS(mem->start);
+       dev->base = ioremap(mem->start, resource_size(mem));
+       if (!dev->base) {
+               r = -EBUSY;
+               goto err_mem_ioremap;
+       }
+
        i2c_davinci_init(dev);
 
        r = request_irq(dev->irq, i2c_davinci_isr, 0, pdev->name, dev);
@@ -550,6 +691,12 @@ static int davinci_i2c_probe(struct platform_device *pdev)
                goto err_unuse_clocks;
        }
 
+       r = i2c_davinci_cpufreq_register(dev);
+       if (r) {
+               dev_err(&pdev->dev, "failed to register cpufreq\n");
+               goto err_free_irq;
+       }
+
        adap = &dev->adapter;
        i2c_set_adapdata(adap, dev);
        adap->owner = THIS_MODULE;
@@ -571,6 +718,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 err_free_irq:
        free_irq(dev->irq, dev);
 err_unuse_clocks:
+       iounmap(dev->base);
+err_mem_ioremap:
        clk_disable(dev->clk);
        clk_put(dev->clk);
        dev->clk = NULL;
@@ -589,6 +738,8 @@ static int davinci_i2c_remove(struct platform_device *pdev)
        struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
        struct resource *mem;
 
+       i2c_davinci_cpufreq_deregister(dev);
+
        platform_set_drvdata(pdev, NULL);
        i2c_del_adapter(&dev->adapter);
        put_device(&pdev->dev);
@@ -599,6 +750,7 @@ static int davinci_i2c_remove(struct platform_device *pdev)
 
        davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0);
        free_irq(IRQ_I2C, dev);
+       iounmap(dev->base);
        kfree(dev);
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -606,6 +758,41 @@ static int davinci_i2c_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int davinci_i2c_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+       /* put I2C into reset */
+       davinci_i2c_reset_ctrl(i2c_dev, 0);
+       clk_disable(i2c_dev->clk);
+
+       return 0;
+}
+
+static int davinci_i2c_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+       clk_enable(i2c_dev->clk);
+       /* take I2C out of reset */
+       davinci_i2c_reset_ctrl(i2c_dev, 1);
+
+       return 0;
+}
+
+static const struct dev_pm_ops davinci_i2c_pm = {
+       .suspend        = davinci_i2c_suspend,
+       .resume         = davinci_i2c_resume,
+};
+
+#define davinci_i2c_pm_ops (&davinci_i2c_pm)
+#else
+#define davinci_i2c_pm_ops NULL
+#endif
+
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:i2c_davinci");
 
@@ -615,6 +802,7 @@ static struct platform_driver davinci_i2c_driver = {
        .driver         = {
                .name   = "i2c_davinci",
                .owner  = THIS_MODULE,
+               .pm     = davinci_i2c_pm_ops,
        },
 };