Re: [PATCH] i2c designware add support of I2C standard mode

2014-09-27 Thread atull
On Sat, 20 Sep 2014, Wolfram Sang wrote:

> On Wed, Aug 20, 2014 at 04:29:08PM +0200, Romain Baeriswyl wrote:
> > From: Romain Baeriswyl 
> > 
> > Some legacy devices support ony I2C standard mode at 100kHz.
> > This patch allows to select the standard mode through the DTS
> > with the use of the existing clock-frequency parameter.
> > 
> > When clock-frequency parameter is not set, the fast mode is selected.
> > Only when the parameter is set at 10, the standard mode is selected.
> > 
> > Signed-off-by: Romain Baeriswyl 
> > Reviewed-by: Christian Ruppert 
> 
> Applied to for-next, thanks to all involved!
> 
> 

I don't see this in 
git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
Is this in i2c/i2c/for-next?

Alan
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/3] ARM: dts: hix5hd2: add i2c node

2014-09-27 Thread Zhangfei Gao
Signed-off-by: Zhangfei Gao 
---
 arch/arm/boot/dts/hisi-x5hd2.dtsi |   60 +
 1 file changed, 60 insertions(+)

diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi 
b/arch/arm/boot/dts/hisi-x5hd2.dtsi
index d3d99fb..17d0637 100644
--- a/arch/arm/boot/dts/hisi-x5hd2.dtsi
+++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi
@@ -476,5 +476,65 @@
 interrupts = <0 70 4>;
 clocks = <&clock HIX5HD2_SATA_CLK>;
};
+
+   i2c0: i2c@b1 {
+   compatible = "hisilicon,hix5hd2-i2c";
+   reg = <0xb1 0x1000>;
+   interrupts = <0 38 4>;
+   clocks = <&clock HIX5HD2_I2C0_RST>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
+   i2c1: i2c@b11000 {
+   compatible = "hisilicon,hix5hd2-i2c";
+   reg = <0xb11000 0x1000>;
+   interrupts = <0 39 4>;
+   clocks = <&clock HIX5HD2_I2C1_RST>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
+   i2c2: i2c@b12000 {
+   compatible = "hisilicon,hix5hd2-i2c";
+   reg = <0xb12000 0x1000>;
+   interrupts = <0 40 4>;
+   clocks = <&clock HIX5HD2_I2C2_RST>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
+   i2c3: i2c@b13000 {
+   compatible = "hisilicon,hix5hd2-i2c";
+   reg = <0xb13000 0x1000>;
+   interrupts = <0 41 4>;
+   clocks = <&clock HIX5HD2_I2C3_RST>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
+   i2c4: i2c@b16000 {
+   compatible = "hisilicon,hix5hd2-i2c";
+   reg = <0xb16000 0x1000>;
+   interrupts = <0 43 4>;
+   clocks = <&clock HIX5HD2_I2C4_RST>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
+
+   i2c5: i2c@b17000 {
+   compatible = "hisilicon,hix5hd2-i2c";
+   reg = <0xb17000 0x1000>;
+   interrupts = <0 44 4>;
+   clocks = <&clock HIX5HD2_I2C5_RST>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+   };
};
 };
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/3] i2c: hix5hd2: add i2c controller driver

2014-09-27 Thread Zhangfei Gao
From: Wei Yan 

I2C drivers for hix5hd2 soc series, including following chipset
Hi3716CV200, Hi3719CV100, Hi3718CV100, Hi3719MV100, Hi3718MV100.

Signed-off-by: Wei Yan 
Signed-off-by: Zhangfei Gao 
---
 drivers/i2c/busses/Kconfig   |   10 +
 drivers/i2c/busses/Makefile  |1 +
 drivers/i2c/busses/i2c-hix5hd2.c |  554 ++
 3 files changed, 565 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-hix5hd2.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2ac87fa..ba0f43c 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -77,6 +77,16 @@ config I2C_AMD8111
  This driver can also be built as a module.  If so, the module
  will be called i2c-amd8111.
 
+config I2C_HIX5HD2
+   tristate "Hix5hd2 high-speed I2C driver"
+   depends on ARCH_HIX5HD2
+   help
+ Say Y here to include support for high-speed I2C controller in the
+ Hisilicon based hix5hd2 SoCs.
+
+ This driver can also be built as a module.  If so, the module
+ will be called i2c-hix5hd2.
+
 config I2C_I801
tristate "Intel 82801 (ICH/PCH)"
depends on PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 49bf07e..9739938 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_I2C_EG20T)   += i2c-eg20t.o
 obj-$(CONFIG_I2C_EXYNOS5)  += i2c-exynos5.o
 obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
 obj-$(CONFIG_I2C_HIGHLANDER)   += i2c-highlander.o
+obj-$(CONFIG_I2C_HIX5HD2)  += i2c-hix5hd2.o
 obj-$(CONFIG_I2C_IBM_IIC)  += i2c-ibm_iic.o
 obj-$(CONFIG_I2C_IMX)  += i2c-imx.o
 obj-$(CONFIG_I2C_IOP3XX)   += i2c-iop3xx.o
diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c
new file mode 100644
index 000..4b18bde
--- /dev/null
+++ b/drivers/i2c/busses/i2c-hix5hd2.c
@@ -0,0 +1,554 @@
+/*
+ * Copyright (c) 2014 Linaro Ltd.
+ * Copyright (c) 2014 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Now only support 7 bit address.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Register Map */
+#define HIX5I2C_CTRL   0x00
+#define HIX5I2C_COM0x04
+#define HIX5I2C_ICR0x08
+#define HIX5I2C_SR 0x0c
+#define HIX5I2C_SCL_H  0x10
+#define HIX5I2C_SCL_L  0x14
+#define HIX5I2C_TXR0x18
+#define HIX5I2C_RXR0x1c
+
+/* I2C_CTRL_REG */
+#define I2C_ENABLE BIT(8)
+#define I2C_UNMASK_TOTAL   BIT(7)
+#define I2C_UNMASK_START   BIT(6)
+#define I2C_UNMASK_END BIT(5)
+#define I2C_UNMASK_SENDBIT(4)
+#define I2C_UNMASK_RECEIVE BIT(3)
+#define I2C_UNMASK_ACK BIT(2)
+#define I2C_UNMASK_ARBITRATE   BIT(1)
+#define I2C_UNMASK_OVERBIT(0)
+#define I2C_UNMASK_ALL (I2C_UNMASK_ACK | I2C_UNMASK_OVER)
+
+/* I2C_COM_REG */
+#define I2C_NO_ACK BIT(4)
+#define I2C_START  BIT(3)
+#define I2C_READ   BIT(2)
+#define I2C_WRITE  BIT(1)
+#define I2C_STOP   BIT(0)
+
+/* I2C_ICR_REG */
+#define I2C_CLEAR_STARTBIT(6)
+#define I2C_CLEAR_END  BIT(5)
+#define I2C_CLEAR_SEND BIT(4)
+#define I2C_CLEAR_RECEIVE  BIT(3)
+#define I2C_CLEAR_ACK  BIT(2)
+#define I2C_CLEAR_ARBITRATEBIT(1)
+#define I2C_CLEAR_OVER BIT(0)
+#define I2C_CLEAR_ALL  (I2C_CLEAR_START | I2C_CLEAR_END | \
+   I2C_CLEAR_SEND | I2C_CLEAR_RECEIVE | \
+   I2C_CLEAR_ACK | I2C_CLEAR_ARBITRATE | \
+   I2C_CLEAR_OVER)
+
+/* I2C_SR_REG */
+#define I2C_BUSY   BIT(7)
+#define I2C_START_INTR BIT(6)
+#define I2C_END_INTR   BIT(5)
+#define I2C_SEND_INTR  BIT(4)
+#define I2C_RECEIVE_INTR   BIT(3)
+#define I2C_ACK_INTR   BIT(2)
+#define I2C_ARBITRATE_INTR BIT(1)
+#define I2C_OVER_INTR  BIT(0)
+
+#define HIX5I2C_MAX_FREQ   40  /* 400k */
+#define HIX5I2C_READ_OPERATION 0x01
+
+enum hix5hd2_i2c_state {
+   HIX5I2C_STAT_RW_ERR = -1,
+   HIX5I2C_STAT_INIT,
+   HIX5I2C_STAT_RW,
+   HIX5I2C_STAT_SND_STOP,
+   HIX5I2C_STAT_RW_SUCCESS,
+};
+
+struct hix5hd2_i2c_priv {
+   struct i2c_adapter adap;
+   struct i2c_msg *msg;
+   struct completion msg_complete;
+   unsigned int msg_idx;
+   unsigned int msg_len;
+   int stop;
+   void __iomem *regs;
+   struct clk *clk;
+   struct device *dev;
+   spinlock_t lock;/* IRQ synchronization */
+   int err;
+   u

[PATCH v2 1/3] i2c: hix5hd2: add devicetree documentation

2014-09-27 Thread Zhangfei Gao
From: Wei Yan 

Signed-off-by: Wei Yan 
Signed-off-by: Zhangfei Gao 
---
 .../devicetree/bindings/i2c/i2c-hix5hd2.txt|   31 
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-hix5hd2.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-hix5hd2.txt 
b/Documentation/devicetree/bindings/i2c/i2c-hix5hd2.txt
new file mode 100644
index 000..981a069
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-hix5hd2.txt
@@ -0,0 +1,31 @@
+I2C for Hisilicon hix5hd2 chipset platforms (3716,3719,3798...)
+
+Required properties:
+- compatible: Must be "hisilicon,hix5hd2-i2c"
+  Specifically, the following versions of the chipset are supported:
+ Hi3716CV200 (support six I2C module)
+ Hi3719CV100 (support six I2C module)
+ Hi3718CV100 (support six I2C module)
+ Hi3719MV100 (support two I2C module)
+ Hi3718MV100 (support two I2C module)
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- interrupts: interrupt number to the cpu.
+- #address-cells = <1>;
+- #size-cells = <0>;
+- clocks: phandles to input clocks.
+
+Optional properties:
+- clock-frequency: Desired I2C bus frequency in Hz, otherwise defaults to 
10
+- Child nodes conforming to i2c bus binding
+
+Examples:
+I2C0@f8b1 {
+   compatible = "hisilicon,hix5hd2-i2c";
+   reg = <0xf8b1 0x1000>;
+   interrupts = <0 38 4>;
+   clocks = <&clock HIX5HD2_I2C0_RST>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   status = "disabled";
+}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/3] i2c: hix5hd2: add i2c controller driver

2014-09-27 Thread Zhangfei Gao
v2: 
Modify according to Wolfram's comments 
including change vector name, coding style, return value etc.

Wei Yan (2):
  i2c: hix5hd2: add devicetree documentation
  i2c: hix5hd2: add i2c controller driver

Zhangfei Gao (1):
  ARM: dts: hix5hd2: add i2c node

 .../devicetree/bindings/i2c/i2c-hix5hd2.txt|   31 ++
 arch/arm/boot/dts/hisi-x5hd2.dtsi  |   60 +++
 drivers/i2c/busses/Kconfig |   10 +
 drivers/i2c/busses/Makefile|1 +
 drivers/i2c/busses/i2c-hix5hd2.c   |  555 
 5 files changed, 657 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-hix5hd2.txt
 create mode 100644 drivers/i2c/busses/i2c-hix5hd2.c

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] i2c: rk3x: adjust the LOW divison based on characteristics of SCL

2014-09-27 Thread Addy Ke
From: Addy 

As show in I2C specification:
- Standard-mode: the minimum HIGH period of the scl clock is 4.0us
 the minimum LOW period of the scl clock is 4.7us
- Fast-mode: the minimum HIGH period of the scl clock is 0.6us
 the minimum LOW period of the scl clock is 1.3us

I have measured i2c SCL waveforms in fast-mode by oscilloscope
on rk3288-pinky board. the LOW period of the scl clock is 1.3us.
It is so critical that we must adjust LOW division to increase
the LOW period of the scl clock.

After put this patch, we can find that min_low_ns is about
5.4us in Standard-mode and 1.6us in Fast-mode.

Thanks Doug for the suggestion about division formulas.

Signed-off-by: Addy 
---
Changes in v2:
- remove Fast-mode plus and HS-mode
- use new formulas suggested by Doug

 drivers/i2c/busses/i2c-rk3x.c | 104 +++---
 1 file changed, 97 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index e637c32..81672a8 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -428,19 +428,109 @@ out:
return IRQ_HANDLED;
 }
 
+static void rk3x_i2c_get_min_ns(unsigned int scl_rate,
+   unsigned long *min_low_ns,
+   unsigned long *min_high_ns)
+{
+   WARN_ON(scl_rate > 40);
+
+   /* As show in I2C specification:
+* - Standard-mode(100KHz):
+*   min_low_ns is 4700ns
+*   min_high_ns is 4000ns
+* - Fast-mode(400KHz):
+*   min_low_ns is 1300ns
+*   min_high_ns is 600ns
+*
+* (min_low_ns + min_high_ns) up to 1ns in Standard-mode
+* and 2500ns in Fast-mode
+*/
+   if (scl_rate <= 10) {
+   *min_low_ns = 4700 + 650;
+   *min_high_ns = 4000 + 650;
+   } else {
+   *min_low_ns = 1300 + 300;
+   *min_high_ns = 600 + 300;
+   }
+}
+
+static void rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate,
+  unsigned long *div_low, unsigned long *div_high)
+{
+   unsigned long min_low_ns, min_high_ns, min_total_ns;
+   unsigned long min_low_div, min_high_div;
+   unsigned long min_total_div, min_div_for_hold;
+   unsigned long extra_div, extra_low_div, ideal_low_div;
+   unsigned long i2c_rate_khz, scl_rate_khz;
+
+   rk3x_i2c_get_min_ns(scl_rate, &min_low_ns, &min_high_ns);
+   min_total_ns = min_low_ns + min_high_ns;
+
+   /* To avoid from overflow warning */
+   i2c_rate_khz = i2c_rate / 1000;
+   scl_rate_khz = scl_rate / 1000;
+
+   /*We need the total div to be >= this number
+* so we don't clock too fast.
+*/
+   min_total_div = DIV_ROUND_UP(i2c_rate_khz, scl_rate_khz * 8);
+
+   /* These are the min dividers needed for hold times */
+   min_low_div = DIV_ROUND_UP(i2c_rate_khz * min_low_ns, 8 * 100);
+   min_high_div = DIV_ROUND_UP(i2c_rate_khz * min_high_ns, 8 * 100);
+   min_div_for_hold = (min_low_div + min_high_div);
+
+   if (min_div_for_hold > min_total_div) {
+   /* Time needed to meet hold requirements is important.
+* Just use that
+* */
+   *div_low = min_low_div;
+   *div_high = min_high_div;
+   } else {
+   /* We've got to distribute some time among the low and high
+* so we don't run too fast.
+*/
+   extra_div = min_total_div - min_div_for_hold;
+   /* We'll try to split things up perfectly evenly,
+* biasing slightly towards having a higher div
+* for low (spend more time low).
+*/
+   ideal_low_div = DIV_ROUND_UP(i2c_rate_khz * min_low_ns,
+scl_rate_khz * 8 * min_total_ns);
+   /* Handle when the ideal low div is going to take up
+* more than we have.
+*/
+   if (ideal_low_div > min_low_div + extra_div)
+   ideal_low_div = min_low_div + extra_div;
+   /* Give low the "ideal" and give high whatever extra is left.*/
+   extra_low_div = ideal_low_div - min_low_div;
+   *div_low = ideal_low_div;
+   *div_high
+   = min_high_div + (extra_div - extra_low_div);
+   }
+
+   /* Adjust to the fact that the hardware has an implicit "+1".*/
+   *div_low = *div_low - 1;
+   *div_high = *div_high - 1;
+}
+
 static void rk3x_i2c_set_scl_rate(struct rk3x_i2c *i2c, unsigned long scl_rate)
 {
unsigned long i2c_rate = clk_get_rate(i2c->clk);
-   unsigned int div;
+   unsigned long div_low, div_high;
 
-   /* SCL rate = (clk rate) / (8 * DIV) */
-   div = DIV_ROUND_UP(i2c_rate, scl_rate * 8);
+   /* The formulas in rk3x TRM: