Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
[deliverable/linux.git] / drivers / i2c / busses / i2c-imx.c
index db895fb22e652f8b31bc25473fd0f26115b9ff01..aa8bc146718bfc13c562e11322ddf36d9442f2c7 100644 (file)
@@ -183,6 +183,8 @@ struct imx_i2c_struct {
        unsigned int            disable_delay;
        int                     stopped;
        unsigned int            ifdr; /* IMX_I2C_IFDR */
+       unsigned int            cur_clk;
+       unsigned int            bitrate;
        const struct imx_i2c_hwdata     *hwdata;
 };
 
@@ -305,6 +307,48 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
        return 0;
 }
 
+static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
+{
+       struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
+       unsigned int i2c_clk_rate;
+       unsigned int div;
+       int i;
+
+       /* Divider value calculation */
+       i2c_clk_rate = clk_get_rate(i2c_imx->clk);
+       if (i2c_imx->cur_clk == i2c_clk_rate)
+               return;
+       else
+               i2c_imx->cur_clk = i2c_clk_rate;
+
+       div = (i2c_clk_rate + i2c_imx->bitrate - 1) / i2c_imx->bitrate;
+       if (div < i2c_clk_div[0].div)
+               i = 0;
+       else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div)
+               i = i2c_imx->hwdata->ndivs - 1;
+       else
+               for (i = 0; i2c_clk_div[i].div < div; i++);
+
+       /* Store divider value */
+       i2c_imx->ifdr = i2c_clk_div[i].val;
+
+       /*
+        * There dummy delay is calculated.
+        * It should be about one I2C clock period long.
+        * This delay is used in I2C bus disable function
+        * to fix chip hardware bug.
+        */
+       i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
+               + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
+
+#ifdef CONFIG_I2C_DEBUG_BUS
+       dev_dbg(&i2c_imx->adapter.dev, "I2C_CLK=%d, REQ DIV=%d\n",
+               i2c_clk_rate, div);
+       dev_dbg(&i2c_imx->adapter.dev, "IFDR[IC]=0x%x, REAL DIV=%d\n",
+               i2c_clk_div[i].val, i2c_clk_div[i].div);
+#endif
+}
+
 static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 {
        unsigned int temp = 0;
@@ -312,6 +356,8 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 
        dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
+       i2c_imx_set_clk(i2c_imx);
+
        result = clk_prepare_enable(i2c_imx->clk);
        if (result)
                return result;
@@ -367,45 +413,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
        clk_disable_unprepare(i2c_imx->clk);
 }
 
-static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
-                                                       unsigned int rate)
-{
-       struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
-       unsigned int i2c_clk_rate;
-       unsigned int div;
-       int i;
-
-       /* Divider value calculation */
-       i2c_clk_rate = clk_get_rate(i2c_imx->clk);
-       div = (i2c_clk_rate + rate - 1) / rate;
-       if (div < i2c_clk_div[0].div)
-               i = 0;
-       else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div)
-               i = i2c_imx->hwdata->ndivs - 1;
-       else
-               for (i = 0; i2c_clk_div[i].div < div; i++);
-
-       /* Store divider value */
-       i2c_imx->ifdr = i2c_clk_div[i].val;
-
-       /*
-        * There dummy delay is calculated.
-        * It should be about one I2C clock period long.
-        * This delay is used in I2C bus disable function
-        * to fix chip hardware bug.
-        */
-       i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
-               + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
-
-       /* dev_dbg() can't be used, because adapter is not yet registered */
-#ifdef CONFIG_I2C_DEBUG_BUS
-       dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
-               __func__, i2c_clk_rate, div);
-       dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
-               __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
-#endif
-}
-
 static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
 {
        struct imx_i2c_struct *i2c_imx = dev_id;
@@ -458,10 +465,11 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
        return 0;
 }
 
-static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
+static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bool is_lastmsg)
 {
        int i, result;
        unsigned int temp;
+       int block_data = msgs->flags & I2C_M_RECV_LEN;
 
        dev_dbg(&i2c_imx->adapter.dev,
                "<%s> write slave address: addr=0x%x\n",
@@ -481,7 +489,12 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
        /* setup bus to read data */
        temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
        temp &= ~I2CR_MTX;
-       if (msgs->len - 1)
+
+       /*
+        * Reset the I2CR_TXAK flag initially for SMBus block read since the
+        * length is unknown
+        */
+       if ((msgs->len - 1) || block_data)
                temp &= ~I2CR_TXAK;
        imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
        imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); /* dummy read */
@@ -490,19 +503,49 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
 
        /* read data */
        for (i = 0; i < msgs->len; i++) {
+               u8 len = 0;
                result = i2c_imx_trx_complete(i2c_imx);
                if (result)
                        return result;
-               if (i == (msgs->len - 1)) {
-                       /* It must generate STOP before read I2DR to prevent
-                          controller from generating another clock cycle */
+               /*
+                * First byte is the length of remaining packet
+                * in the SMBus block data read. Add it to
+                * msgs->len.
+                */
+               if ((!i) && block_data) {
+                       len = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+                       if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX))
+                               return -EPROTO;
                        dev_dbg(&i2c_imx->adapter.dev,
-                               "<%s> clear MSTA\n", __func__);
-                       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
-                       temp &= ~(I2CR_MSTA | I2CR_MTX);
-                       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
-                       i2c_imx_bus_busy(i2c_imx, 0);
-                       i2c_imx->stopped = 1;
+                               "<%s> read length: 0x%X\n",
+                               __func__, len);
+                       msgs->len += len;
+               }
+               if (i == (msgs->len - 1)) {
+                       if (is_lastmsg) {
+                               /*
+                                * It must generate STOP before read I2DR to prevent
+                                * controller from generating another clock cycle
+                                */
+                               dev_dbg(&i2c_imx->adapter.dev,
+                                       "<%s> clear MSTA\n", __func__);
+                               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+                               temp &= ~(I2CR_MSTA | I2CR_MTX);
+                               imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+                               i2c_imx_bus_busy(i2c_imx, 0);
+                               i2c_imx->stopped = 1;
+                       } else {
+                               /*
+                                * For i2c master receiver repeat restart operation like:
+                                * read -> repeat MSTA -> read/write
+                                * The controller must set MTX before read the last byte in
+                                * the first read operation, otherwise the first read cost
+                                * one extra clock cycle.
+                                */
+                               temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+                               temp |= I2CR_MTX;
+                               writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+                       }
                } else if (i == (msgs->len - 2)) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> set TXAK\n", __func__);
@@ -510,7 +553,10 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
                        temp |= I2CR_TXAK;
                        imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
                }
-               msgs->buf[i] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+               if ((!i) && block_data)
+                       msgs->buf[0] = len;
+               else
+                       msgs->buf[i] =  imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
                dev_dbg(&i2c_imx->adapter.dev,
                        "<%s> read byte: B%d=0x%X\n",
                        __func__, i, msgs->buf[i]);
@@ -523,6 +569,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 {
        unsigned int i, temp;
        int result;
+       bool is_lastmsg = false;
        struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
 
        dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
@@ -534,6 +581,9 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 
        /* read/write data */
        for (i = 0; i < num; i++) {
+               if (i == num - 1)
+                       is_lastmsg = true;
+
                if (i) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> repeated start\n", __func__);
@@ -564,7 +614,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
                        (temp & I2SR_RXAK ? 1 : 0));
 #endif
                if (msgs[i].flags & I2C_M_RD)
-                       result = i2c_imx_read(i2c_imx, &msgs[i]);
+                       result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg);
                else
                        result = i2c_imx_write(i2c_imx, &msgs[i]);
                if (result)
@@ -583,7 +633,8 @@ fail0:
 
 static u32 i2c_imx_func(struct i2c_adapter *adapter)
 {
-       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
+               | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
 }
 
 static struct i2c_algorithm i2c_imx_algo = {
@@ -600,7 +651,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
        struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
        void __iomem *base;
        int irq, ret;
-       u32 bitrate;
 
        dev_dbg(&pdev->dev, "<%s>\n", __func__);
 
@@ -617,10 +667,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
 
        i2c_imx = devm_kzalloc(&pdev->dev, sizeof(struct imx_i2c_struct),
                                GFP_KERNEL);
-       if (!i2c_imx) {
-               dev_err(&pdev->dev, "can't allocate interface\n");
+       if (!i2c_imx)
                return -ENOMEM;
-       }
 
        if (of_id)
                i2c_imx->hwdata = of_id->data;
@@ -664,12 +712,11 @@ static int i2c_imx_probe(struct platform_device *pdev)
        i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
 
        /* Set up clock divider */
-       bitrate = IMX_I2C_BIT_RATE;
+       i2c_imx->bitrate = IMX_I2C_BIT_RATE;
        ret = of_property_read_u32(pdev->dev.of_node,
-                                  "clock-frequency", &bitrate);
+                                  "clock-frequency", &i2c_imx->bitrate);
        if (ret < 0 && pdata && pdata->bitrate)
-               bitrate = pdata->bitrate;
-       i2c_imx_set_clk(i2c_imx, bitrate);
+               i2c_imx->bitrate = pdata->bitrate;
 
        /* Set up chip registers to defaults */
        imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
This page took 0.044926 seconds and 5 git commands to generate.