Skip to contentSkip to conversation

I2C support for NXP LPC18xx family

PATCH Superseded Joachim Eastwood 2 participants 5 messages Jul 12, 2015 – Aug 15, 2015

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover I2C support for NXP LPC18xx family

This patch set adds a I2C driver and documentation for the I2C peripheral found on many NXP LPC MCUs.

The driver is a rework of an old driver by Kevin Wells. It has been modified to support modern resource allocation, device tree and generally cleaned up. Driver was originally written to support the LPC2xxx platforms.

Patches based on v4.2-rc1 and tested on Embedded Artists' LPC4357 Developer's Kit with several I2C devices.

Joachim Eastwood (2):
i2c: add i2c-lpc2k driver
doc: dt: add documentation for i2c-lpc2k

 .../devicetree/bindings/i2c/i2c-lpc2k.txt          |  33 ++
 drivers/i2c/busses/Kconfig                         |  10 +
 drivers/i2c/busses/Makefile                        |   1 +
 drivers/i2c/busses/i2c-lpc2k.c                     | 551 +++++++++++++++++++++
 4 files changed, 595 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt
 create mode 100644 drivers/i2c/busses/i2c-lpc2k.c
Signature · 1 line
1.8.0
#1 lore raw

PATCH 1/2 i2c: add i2c-lpc2k driver

Add support for the I2C controller found on several NXP devices including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller is implemented as a state machine and the driver act upon the state changes when the bus is accessed.

The I2C controller supports master/slave operation, bus arbitration, programmable clock rate, and speeds up to 1 Mbit/s.

---
 drivers/i2c/busses/Kconfig     |  10 +
 drivers/i2c/busses/Makefile    |   1 +
 drivers/i2c/busses/i2c-lpc2k.c | 551 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 562 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-lpc2k.c
drivers/i2c/busses/Kconfig +10 -0
index 35ac23768ce9..a880c82bed3d 100644
@@ -612,6 +612,16 @@ config I2C_KEMPLD
 	  This driver can also be built as a module. If so, the module
 	  will be called i2c-kempld.
 
+config I2C_LPC2K
+	tristate "I2C bus support for NXP LPC2K/LPC178x/18xx/43xx"
+	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
+	help
+	  This driver supports the I2C interface found several NXP
+	  devices including LPC2xxx, LPC178x/7x and LPC18xx/43xx.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-lpc2k.
+
 config I2C_MESON
 	tristate "Amlogic Meson I2C controller"
 	depends on ARCH_MESON
drivers/i2c/busses/Makefile +1 -0
index e5f537c80da0..65b84097e665 100644
@@ -58,6 +58,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
 obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
+obj-$(CONFIG_I2C_LPC2K)		+= i2c-lpc2k.o
 obj-$(CONFIG_I2C_MESON)		+= i2c-meson.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
 obj-$(CONFIG_I2C_MT65XX)	+= i2c-mt65xx.o
drivers/i2c/busses/i2c-lpc2k.c new file +551 -0

551 lines not on this page · raw message

Signature · 1 line
1.8.0
#2 lore raw

PATCH 1/2 i2c: add i2c-lpc2k driver

Quoted 9 lines · Joachim Eastwood

Add support for the I2C controller found on several NXP devices including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller is implemented as a state machine and the driver act upon the state changes when the bus is accessed.

The I2C controller supports master/slave operation, bus arbitration, programmable clock rate, and speeds up to 1 Mbit/s.

Thanks for the submission! Looking mostly good already.

Quoted 13 lines
drivers/i2c/busses/i2c-lpc2k.c new file +13 -0
+static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
+{
+	unsigned char data;
+	u32 status;
+
+	/*
+	 * I2C in the LPC2xxx series is basically a state machine.
+	 * Just run through the steps based on the current status.
+	 */
+	status = readl(i2c->reg_base + LPC24XX_I2STAT);
+
+	switch (status) {
+	case M_START:

drivers/i2c/busses/i2c-lpc2k.c line 142

Quoted 10 lines
drivers/i2c/busses/i2c-lpc2k.c new file +10 -0
+	case M_REPSTART:
+		/* Start bit was just sent out, send out addr and dir */
+		data = (i2c->msg->addr << 1);
+		if (i2c->msg->flags & I2C_M_RD)
+			data |= 1;
+
+		writel(data, i2c->reg_base + LPC24XX_I2DAT);
+		writel(LPC24XX_STA, i2c->reg_base + LPC24XX_I2CONCLR);
+
+		dev_dbg(&i2c->adap.dev, "Start sent with addr 0x%02x\n", data);

I assume the driver is basically working. So, in my book, most of this debug output is useful when the driver was developed, not so much afterwards. Also, it is printed in interrupt context possibly causing latency. However, the information is useful for understanding the driver, so I'd suggest to convert them into comments?

drivers/i2c/busses/i2c-lpc2k.c line 474

Quoted 3 lines
drivers/i2c/busses/i2c-lpc2k.c new file +3 -0
+	i2c->adap.nr = pdev->id;
+
+	ret = i2c_add_numbered_adapter(&i2c->adap);

Intended? Most DT enabled drivers simply user i2c_add_adapter(). The core then takes care of aliases defined in DT.

And please have a look at Documentation/i2c/fault-codes. Arbitration Lost should be -EAGAIN, NACK should be -ENXIO, and so forth...

Thanks,

Wolfram

#3 lore raw

PATCH 1/2 i2c: add i2c-lpc2k driver

Hi Wolfram,

Quoted 34 lines · Wolfram Sang
Quoted 9 lines · Joachim Eastwood

Add support for the I2C controller found on several NXP devices including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller is implemented as a state machine and the driver act upon the state changes when the bus is accessed.

The I2C controller supports master/slave operation, bus arbitration, programmable clock rate, and speeds up to 1 Mbit/s.

Thanks for the submission! Looking mostly good already.

Quoted 21 lines
drivers/i2c/busses/i2c-lpc2k.c new file +21 -0
+static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
+{
+     unsigned char data;
+     u32 status;
+
+     /*
+      * I2C in the LPC2xxx series is basically a state machine.
+      * Just run through the steps based on the current status.
+      */
+     status = readl(i2c->reg_base + LPC24XX_I2STAT);
+
+     switch (status) {
+     case M_START:
+     case M_REPSTART:
+             /* Start bit was just sent out, send out addr and dir */
+             data = (i2c->msg->addr << 1);
+             if (i2c->msg->flags & I2C_M_RD)
+                     data |= 1;
+
+             writel(data, i2c->reg_base + LPC24XX_I2DAT);
+             writel(LPC24XX_STA, i2c->reg_base + LPC24XX_I2CONCLR);
Quoted 8 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+             dev_dbg(&i2c->adap.dev, "Start sent with addr 0x%02x\n", data);

I assume the driver is basically working. So, in my book, most of this debug output is useful when the driver was developed, not so much afterwards. Also, it is printed in interrupt context possibly causing latency. However, the information is useful for understanding the driver, so I'd suggest to convert them into comments?

I'll go through all the dev_dbg stuff with what you wrote in mind. Think I'll end up with removing most of it.

Think most of the debugging stuff was added by Emcraft while they were bring it up on lpc178x and lpc18xx.

Quoted 6 lines

drivers/i2c/busses/i2c-lpc2k.c line 474

Quoted 3 lines
drivers/i2c/busses/i2c-lpc2k.c new file +3 -0
+     i2c->adap.nr = pdev->id;
+
+     ret = i2c_add_numbered_adapter(&i2c->adap);

Intended? Most DT enabled drivers simply user i2c_add_adapter(). The core then takes care of aliases defined in DT.

No, it's not intended. It's an old driver and I just didn't know about i2c_add_adapter(). I'll change it in the next version.

Quoted 2 lines

And please have a look at Documentation/i2c/fault-codes. Arbitration Lost should be -EAGAIN, NACK should be -ENXIO, and so forth...

Ok, will do.

Thanks for looking, Wolfram. I'll address your comments and try to send out a new version tomorrow.

regards,
Joachim Eastwood

#4 lore raw

PATCH 2/2 doc: dt: add documentation for i2c-lpc2k

In reply to Joachim Eastwood

Add binding documentation for the nxp,lpc1788-i2c controller which also can be found on LPC2xxx, LPC178x/7x and LPC18xx/43xx devices.

---
 .../devicetree/bindings/i2c/i2c-lpc2k.txt          | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt
Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt new file +33 -0
new file mode 100644
index 000000000000..4101aa621ad4
@@ -0,0 +1,33 @@
+NXP I2C controller for LPC2xxx/178x/18xx/43xx
+
+Required properties:
+ - compatible: must be "nxp,lpc1788-i2c"
+ - reg: physical address and length of the device registers
+ - interrupts: a single interrupt specifier
+ - clocks: clock for the device
+ - #address-cells: should be <1>
+ - #size-cells: should be <0>
+
+Optional properties:
+- clock-frequency: the desired I2C bus clock frequency in Hz; in
+  absence of this property the default value is used (100 kHz).
+
+Example:
+i2c0: i2c at 400a1000 {
+	compatible = "nxp,lpc1788-i2c";
+	reg = <0x400a1000 0x1000>;
+	interrupts = <18>;
+	clocks = <&ccu1 CLK_APB1_I2C0>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+};
+
+&i2c0 {
+	clock-frequency = <400000>;
+
+	lm75 at 48 {
+		compatible = "nxp,lm75";
+		reg = <0x48>;
+	};
+};
+
Signature · 1 line
1.8.0