[PATCH 2/2] gpio: Add support for SLG7XL45106 I2C GPO expander

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Raviteja Narayanam <raviteja.narayanam@xxxxxxxxxx>

Dialog semiconductors SLG7XL45106 is an 8-bit I2C GPO expander.
The output port is controlled by a data byte with register
address.

Signed-off-by: Raviteja Narayanam <raviteja.narayanam@xxxxxxxxxx>
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxxxxx>
---
 MAINTAINERS                     |   7 ++
 drivers/gpio/Kconfig            |   9 +++
 drivers/gpio/Makefile           |   1 +
 drivers/gpio/gpio-slg7xl45106.c | 133 ++++++++++++++++++++++++++++++++
 4 files changed, 150 insertions(+)
 create mode 100644 drivers/gpio/gpio-slg7xl45106.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1fc9ead83d2a..3b3f322b5012 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5875,6 +5875,13 @@ F:	include/linux/regulator/da9211.h
 F:	include/sound/da[79]*.h
 F:	sound/soc/codecs/da[79]*.[ch]
 
+DIALOG SLG7XL45106 GPO DRIVER
+M:	Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxx>
+L:	linux-gpio@xxxxxxxxxxxxxxx
+S:	Maintained
+F:	Documentation/devicetree/bindings/gpio/gpio-slg7xl45106.yaml
+F:	drivers/gpio/gpio-slg7xl45106.c
+
 DIAMOND SYSTEMS GPIO-MM GPIO DRIVER
 M:	William Breathitt Gray <vilhelm.gray@xxxxxxxxx>
 L:	linux-gpio@xxxxxxxxxxxxxxx
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b01961999ced..1e10f96c9c09 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1101,6 +1101,15 @@ config GPIO_PCF857X
 	  This driver provides an in-kernel interface to those GPIOs using
 	  platform-neutral GPIO calls.
 
+config GPIO_SLG7XL45106
+	tristate "SLG7XL45106 8-Bit I2C GPO expander"
+	help
+	  Say yes here to enable the GPO driver for the Dialog SLG7XL45106 chip.
+	  This expander has 8 output pins.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called gpio-slg7xl45106.
+
 config GPIO_TPIC2810
 	tristate "TPIC2810 8-Bit I2C GPO expander"
 	help
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 14352f6dfe8e..8248e4fcc22f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -136,6 +136,7 @@ obj-$(CONFIG_GPIO_SIFIVE)		+= gpio-sifive.o
 obj-$(CONFIG_GPIO_SIM)			+= gpio-sim.o
 obj-$(CONFIG_GPIO_SIOX)			+= gpio-siox.o
 obj-$(CONFIG_GPIO_SL28CPLD)		+= gpio-sl28cpld.o
+obj-$(CONFIG_GPIO_SLG7XL45106)		+= gpio-slg7xl45106.o
 obj-$(CONFIG_GPIO_SODAVILLE)		+= gpio-sodaville.o
 obj-$(CONFIG_GPIO_SPEAR_SPICS)		+= gpio-spear-spics.o
 obj-$(CONFIG_GPIO_SPRD)			+= gpio-sprd.o
diff --git a/drivers/gpio/gpio-slg7xl45106.c b/drivers/gpio/gpio-slg7xl45106.c
new file mode 100644
index 000000000000..61935b8538d1
--- /dev/null
+++ b/drivers/gpio/gpio-slg7xl45106.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for slg7xl45106 I2C GPO expander
+ *
+ * Copyright (C) 2021 Xilinx, Inc.
+ * Copyright (C) 2022 AMD, Inc.
+ *
+ * Based on gpio-pca9570.c
+ * Copyright (C) 2020 Sungbo Eo <mans0n@xxxxxxxxxx>
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#define SLG7XL45106_GPO_REG	0xDB
+
+/**
+ * struct slg7xl45106 - GPIO driver data
+ * @chip: GPIO controller chip
+ * @lock: Protects write sequences
+ */
+struct slg7xl45106 {
+	struct gpio_chip chip;
+	struct mutex lock;	/* To protect writes */
+};
+
+static int slg7xl45106_read(struct slg7xl45106 *gpio)
+{
+	struct i2c_client *client = to_i2c_client(gpio->chip.parent);
+
+	return i2c_smbus_read_byte_data(client, SLG7XL45106_GPO_REG);
+}
+
+static int slg7xl45106_write(struct slg7xl45106 *gpio, u8 value)
+{
+	struct i2c_client *client = to_i2c_client(gpio->chip.parent);
+
+	return i2c_smbus_write_byte_data(client, SLG7XL45106_GPO_REG, value);
+}
+
+static int slg7xl45106_get_direction(struct gpio_chip *chip,
+				     unsigned int offset)
+{
+	/* This device always output */
+	return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int slg7xl45106_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct slg7xl45106 *gpio = gpiochip_get_data(chip);
+	int ret;
+
+	ret = slg7xl45106_read(gpio);
+	if (ret < 0)
+		return ret;
+
+	return !!(ret & BIT(offset));
+}
+
+static void slg7xl45106_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct slg7xl45106 *gpio = gpiochip_get_data(chip);
+	u8 buffer;
+
+	mutex_lock(&gpio->lock);
+
+	buffer = slg7xl45106_read(gpio);
+	if (buffer < 0)
+		goto out;
+
+	if (value)
+		buffer |= BIT(offset);
+	else
+		buffer &= ~BIT(offset);
+
+	slg7xl45106_write(gpio, buffer);
+
+out:
+	mutex_unlock(&gpio->lock);
+}
+
+static int slg7xl45106_probe(struct i2c_client *client)
+{
+	struct slg7xl45106 *gpio;
+
+	gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
+	if (!gpio)
+		return -ENOMEM;
+
+	gpio->chip.label = client->name;
+	gpio->chip.parent = &client->dev;
+	gpio->chip.owner = THIS_MODULE;
+	gpio->chip.get_direction = slg7xl45106_get_direction;
+	gpio->chip.get = slg7xl45106_get;
+	gpio->chip.set = slg7xl45106_set;
+	gpio->chip.base = -1;
+	gpio->chip.ngpio = (uintptr_t)device_get_match_data(&client->dev);
+	gpio->chip.can_sleep = true;
+
+	mutex_init(&gpio->lock);
+
+	i2c_set_clientdata(client, gpio);
+
+	return devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio);
+}
+
+static const struct i2c_device_id slg7xl45106_id_table[] = {
+	{ "slg7xl45106", 8 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, slg7xl45106_id_table);
+
+static const struct of_device_id slg7xl45106_of_match_table[] = {
+	{ .compatible = "dlg,slg7xl45106", .data = (void *)8 },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, slg7xl45106_of_match_table);
+
+static struct i2c_driver slg7xl45106_driver = {
+	.driver = {
+		.name = "slg7xl45106",
+		.of_match_table = slg7xl45106_of_match_table,
+	},
+	.probe_new = slg7xl45106_probe,
+	.id_table = slg7xl45106_id_table,
+};
+module_i2c_driver(slg7xl45106_driver);
+
+MODULE_AUTHOR("Raviteja Narayanam <raviteja.narayanam@xxxxxxxxxx>");
+MODULE_DESCRIPTION("GPIO expander driver for slg7xl45106");
+MODULE_LICENSE("GPL");
-- 
2.17.1




[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux