[PATCH 2/2] i2c: pcf8575: Add support for 8 bit I2C IO expanders (like pca8574)

Lukasz Majewski lukma at denx.de
Mon Jun 7 14:26:34 CEST 2021


This patch add support for using NXP's pca8574 I2C IO expander, which
has only 8 IO lines.

After this change the .data member's information from struct udevice_id
are used to either sent one or two bytes.

Moreover, the '_le16' suffix from pcf8575_i2c_{write|read}_le16()
functions have been removed as now we also sent 8 bit data.

Signed-off-by: Lukasz Majewski <lukma at denx.de>

---

 drivers/gpio/pcf8575_gpio.c | 40 ++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/drivers/gpio/pcf8575_gpio.c b/drivers/gpio/pcf8575_gpio.c
index bae9695f28b1..d5930d941fc0 100644
--- a/drivers/gpio/pcf8575_gpio.c
+++ b/drivers/gpio/pcf8575_gpio.c
@@ -12,15 +12,9 @@
  *
  * Copyright (C) 2007 David Brownell
  *
- */
-
-/*
- * NOTE: The driver and devicetree bindings are borrowed from Linux
- * Kernel, but driver does not support all PCF857x devices. It currently
- * supports PCF8575 16-bit expander by TI and NXP.
+ * Add support for 8 bit expanders - like pca8574
+ * Copyright (C) 2021 Lukasz Majewski - DENX Software Engineering
  *
- * TODO(vigneshr at ti.com):
- * Support 8 bit PCF857x compatible expanders.
  */
 
 #include <common.h>
@@ -49,15 +43,15 @@ struct pcf8575_chip {
 	unsigned int out;	/* software latch */
 };
 
-/* Read/Write to 16-bit I/O expander */
+/* Read/Write to I/O expander */
 
-static int pcf8575_i2c_write_le16(struct udevice *dev, unsigned int word)
+static int pcf8575_i2c_write(struct udevice *dev, unsigned int word)
 {
 	struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
 	u8 buf[2] = { word & 0xff, word >> 8, };
 	int ret;
 
-	ret = dm_i2c_write(dev, 0, buf, 2);
+	ret = dm_i2c_write(dev, 0, buf, dev_get_driver_data(dev));
 	if (ret)
 		printf("%s i2c write failed to addr %x\n", __func__,
 		       chip->chip_addr);
@@ -65,13 +59,13 @@ static int pcf8575_i2c_write_le16(struct udevice *dev, unsigned int word)
 	return ret;
 }
 
-static int pcf8575_i2c_read_le16(struct udevice *dev)
+static int pcf8575_i2c_read(struct udevice *dev)
 {
 	struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
-	u8 buf[2];
+	u8 buf[2] = {0x00, 0x00};
 	int ret;
 
-	ret = dm_i2c_read(dev, 0, buf, 2);
+	ret = dm_i2c_read(dev, 0, buf, dev_get_driver_data(dev));
 	if (ret) {
 		printf("%s i2c read failed from addr %x\n", __func__,
 		       chip->chip_addr);
@@ -87,7 +81,7 @@ static int pcf8575_direction_input(struct udevice *dev, unsigned offset)
 	int status;
 
 	plat->out |= BIT(offset);
-	status = pcf8575_i2c_write_le16(dev, plat->out);
+	status = pcf8575_i2c_write(dev, plat->out);
 
 	return status;
 }
@@ -103,7 +97,7 @@ static int pcf8575_direction_output(struct udevice *dev,
 	else
 		plat->out &= ~BIT(offset);
 
-	ret = pcf8575_i2c_write_le16(dev, plat->out);
+	ret = pcf8575_i2c_write(dev, plat->out);
 
 	return ret;
 }
@@ -112,7 +106,7 @@ static int pcf8575_get_value(struct udevice *dev, unsigned int offset)
 {
 	int             value;
 
-	value = pcf8575_i2c_read_le16(dev);
+	value = pcf8575_i2c_read(dev);
 
 	return (value < 0) ? value : ((value & BIT(offset)) >> offset);
 }
@@ -130,8 +124,11 @@ static int pcf8575_ofdata_plat(struct udevice *dev)
 
 	int n_latch;
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					     "gpio-count", 16);
+	/*
+	 * Number of pins depends on the expander device and is specified
+	 * in the struct udevice_id (as in the Linue kernel).
+	 */
+	uc_priv->gpio_count = dev_get_driver_data(dev) * 8;
 	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 					 "gpio-bank-name", NULL);
 	if (!uc_priv->bank_name)
@@ -163,8 +160,9 @@ static const struct dm_gpio_ops pcf8575_gpio_ops = {
 };
 
 static const struct udevice_id pcf8575_gpio_ids[] = {
-	{ .compatible = "nxp,pcf8575" },
-	{ .compatible = "ti,pcf8575" },
+	{ .compatible = "nxp,pcf8575", .data = 2 },
+	{ .compatible = "ti,pcf8575", .data = 2 },
+	{ .compatible = "nxp,pca8574", .data = 1 },
 	{ }
 };
 
-- 
2.20.1



More information about the U-Boot mailing list