From: Marco Felsch <m.felsch@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH] fixup! gpio: add DA9062 MFD gpio support
Date: Fri, 11 Oct 2019 09:22:17 +0200 [thread overview]
Message-ID: <20191011072217.13607-1-m.felsch@pengutronix.de> (raw)
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
Hi,
We need to move the gpio-controller to the mfd root node due to
hierarchical GPIO irqchips to keep inline with the linux bindings.
Please see the discussion [1] for further information.
[1] https://patchwork.ozlabs.org/patch/1163309/
Regards,
Marco
drivers/gpio/Kconfig | 4 -
drivers/gpio/Makefile | 1 -
drivers/gpio/gpio-da9062.c | 206 -------------------------------------
drivers/mfd/da9063.c | 136 ++++++++++++++++++++++++
4 files changed, 136 insertions(+), 211 deletions(-)
delete mode 100644 drivers/gpio/gpio-da9062.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 806b96ae26..7a1503198b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -13,10 +13,6 @@ config GPIO_DIGIC
bool "GPIO support for Canon DIGIC"
depends on ARCH_DIGIC
-config GPIO_DA9062
- bool "GPIO support for DA9062 MFD"
- depends on MFD_DA9063
-
config GPIO_74164
bool "Generic SPI attached shift register"
depends on SPI
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 6f2bf11af8..990df01788 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,7 +4,6 @@ obj-$(CONFIG_GPIO_74164) += gpio-74164.o
obj-$(CONFIG_MACH_MIPS_ATH79) += gpio-ath79.o
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
-obj-$(CONFIG_GPIO_DA9062) += gpio-da9062.o
obj-$(CONFIG_GPIO_DIGIC) += gpio-digic.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_IMX) += gpio-imx.o
diff --git a/drivers/gpio/gpio-da9062.c b/drivers/gpio/gpio-da9062.c
deleted file mode 100644
index 2f018166cc..0000000000
--- a/drivers/gpio/gpio-da9062.c
+++ /dev/null
@@ -1,206 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2019 Pengutronix, Marco Felsch <kernel@pengutronix.de>
- */
-
-#include <common.h>
-#include <driver.h>
-#include <gpio.h>
-#include <i2c/i2c.h>
-#include <linux/bitops.h>
-#include <malloc.h>
-
-struct da9062_gpio {
- struct gpio_chip gpio;
- struct i2c_client *client;
- struct device_d *dev;
-};
-
-#define DA9062AA_STATUS_B 0x002
-#define DA9062AA_GPIO_0_1 0x015
-#define DA9062AA_GPIO_MODE0_4 0x01D
-
-/* DA9062AA_GPIO_0_1 (addr=0x015) */
-#define DA9062AA_GPIO0_PIN_MASK 0x03
-
-#define DA9062_PIN_SHIFT(offset) (4 * (offset % 2))
-#define DA9062_PIN_ALTERNATE 0x00 /* gpio alternate mode */
-#define DA9062_PIN_GPI 0x01 /* gpio in */
-#define DA9062_PIN_GPO_OD 0x02 /* gpio out open-drain */
-#define DA9062_PIN_GPO_PP 0x03 /* gpio out push-pull */
-
-static inline struct da9062_gpio *to_da9062(struct gpio_chip *chip)
-{
- return container_of(chip, struct da9062_gpio, gpio);
-}
-
-static int gpio_da9062_reg_update(struct da9062_gpio *priv, unsigned int reg,
- uint8_t mask, uint8_t val)
-{
- struct i2c_client *client;
- uint8_t tmp;
- int ret;
-
- if (reg < 0x100)
- client = priv->client;
-
- if (WARN_ON(!client))
- return -EINVAL;
-
- ret = i2c_read_reg(client, reg & 0xffu, &tmp, 1);
- if (ret < 0) {
- dev_warn(priv->dev, "failed to read reg %02x\n", reg);
- return ret;
- }
-
- tmp &= ~mask;
- tmp |= val;
-
- ret = i2c_write_reg(client, reg & 0xffu, &tmp, 1);
- if (ret < 0) {
- dev_warn(priv->dev, "failed to write %02x into reg %02x\n",
- tmp, reg);
- return ret;
- }
-
- return 0;
-}
-
-static int gpio_da9062_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- struct da9062_gpio *priv = to_da9062(chip);
- u8 mask, mode;
-
- mode = DA9062_PIN_GPI << DA9062_PIN_SHIFT(offset);
- mask = DA9062AA_GPIO0_PIN_MASK << DA9062_PIN_SHIFT(offset);
-
- return gpio_da9062_reg_update(priv, DA9062AA_GPIO_0_1 + (offset >> 1),
- mask, mode);
-}
-
-static int gpio_da9062_direction_output(struct gpio_chip *chip, unsigned offset,
- int value)
-{
- struct da9062_gpio *priv = to_da9062(chip);
-
- return gpio_da9062_reg_update(priv, DA9062AA_GPIO_MODE0_4, BIT(offset),
- value << offset);
-}
-
-static int gpio_da9062_get_pin_mode(struct da9062_gpio *priv, unsigned offset)
-{
- int ret;
- u8 val;
-
- ret = i2c_read_reg(priv->client, DA9062AA_GPIO_0_1 + (offset >> 1),
- &val, 1);
- if (ret < 0)
- return ret;
-
- val >>= DA9062_PIN_SHIFT(offset);
- val &= DA9062AA_GPIO0_PIN_MASK;
-
- return val;
-}
-
-static int gpio_da9062_get(struct gpio_chip *chip, unsigned offset)
-{
- struct da9062_gpio *priv = to_da9062(chip);
- int gpio_dir;
- int ret;
- u8 val;
-
- gpio_dir = gpio_da9062_get_pin_mode(priv, offset);
- if (gpio_dir < 0)
- return gpio_dir;
-
- switch (gpio_dir) {
- case DA9062_PIN_ALTERNATE:
- return -ENOTSUPP;
- case DA9062_PIN_GPI:
- ret = i2c_read_reg(priv->client, DA9062AA_STATUS_B, &val, 1);
- if (ret < 0)
- return ret;
- break;
- case DA9062_PIN_GPO_OD:
- /* falltrough */
- case DA9062_PIN_GPO_PP:
- ret = i2c_read_reg(priv->client, DA9062AA_GPIO_MODE0_4, &val, 1);
- if (ret < 0)
- return ret;
- }
-
- return val & BIT(offset);
-}
-
-static int gpio_da9062_get_direction(struct gpio_chip *chip, unsigned offset)
-{
- struct da9062_gpio *priv = to_da9062(chip);
- int gpio_dir;
-
- gpio_dir = gpio_da9062_get_pin_mode(priv, offset);
- if (gpio_dir < 0)
- return gpio_dir;
-
- switch (gpio_dir) {
- case DA9062_PIN_ALTERNATE:
- return -ENOTSUPP;
- case DA9062_PIN_GPI:
- return 1;
- case DA9062_PIN_GPO_OD:
- /* falltrough */
- case DA9062_PIN_GPO_PP:
- return 0;
- }
-
- return -EINVAL;
-}
-
-static void gpio_da9062_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- struct da9062_gpio *priv = to_da9062(chip);
-
- gpio_da9062_reg_update(priv, DA9062AA_GPIO_MODE0_4, BIT(offset),
- value << offset);
-}
-
-static struct gpio_ops gpio_da9062_ops = {
- .direction_input = gpio_da9062_direction_input,
- .direction_output = gpio_da9062_direction_output,
- .get_direction = gpio_da9062_get_direction,
- .get = gpio_da9062_get,
- .set = gpio_da9062_set,
-};
-
-static int gpio_da9062_probe(struct device_d *dev)
-{
- struct da9062_gpio *priv;
-
- if (!dev->parent)
- return -EPROBE_DEFER;
-
- priv = xzalloc(sizeof(*priv));
- if (!priv)
- return -ENOMEM;
-
- priv->client = to_i2c_client(dev->parent);
- priv->dev = dev;
- priv->gpio.base = -1;
- priv->gpio.ngpio = 5;
- priv->gpio.ops = &gpio_da9062_ops;
- priv->gpio.dev = dev;
-
- return gpiochip_add(&priv->gpio);
-}
-
-static struct of_device_id const gpio_da9062_dt_ids[] = {
- { .compatible = "dlg,da9062-gpio", },
- { }
-};
-
-static struct driver_d gpio_da9062_driver = {
- .name = "da9062-gpio",
- .probe = gpio_da9062_probe,
- .of_compatible = DRV_OF_COMPAT(gpio_da9062_dt_ids),
-};
-device_platform_driver(gpio_da9062_driver);
diff --git a/drivers/mfd/da9063.c b/drivers/mfd/da9063.c
index 9c1752a38c..f0381944d9 100644
--- a/drivers/mfd/da9063.c
+++ b/drivers/mfd/da9063.c
@@ -15,8 +15,10 @@
#include <common.h>
#include <driver.h>
+#include <gpio.h>
#include <restart.h>
#include <i2c/i2c.h>
+#include <linux/bitops.h>
#include <malloc.h>
#include <notifier.h>
#include <reset_source.h>
@@ -25,6 +27,7 @@
struct da9063 {
struct restart_handler restart;
struct watchdog wd;
+ struct gpio_chip gpio;
struct i2c_client *client;
/* dummy client for accessing bank #1 */
struct i2c_client *client1;
@@ -61,6 +64,19 @@ struct da9063 {
/* DA9063_REG_CONTROL_I (addr=0x10e) */
#define DA9062_WATCHDOG_SD BIT(3)
+#define DA9062AA_STATUS_B 0x002
+#define DA9062AA_GPIO_0_1 0x015
+#define DA9062AA_GPIO_MODE0_4 0x01D
+
+/* DA9062AA_GPIO_0_1 (addr=0x015) */
+#define DA9062AA_GPIO0_PIN_MASK 0x03
+
+#define DA9062_PIN_SHIFT(offset) (4 * (offset % 2))
+#define DA9062_PIN_ALTERNATE 0x00 /* gpio alternate mode */
+#define DA9062_PIN_GPI 0x01 /* gpio in */
+#define DA9062_PIN_GPO_OD 0x02 /* gpio out open-drain */
+#define DA9062_PIN_GPO_PP 0x03 /* gpio out push-pull */
+
struct da906x_device_data {
int (*init)(struct da9063 *priv);
};
@@ -104,6 +120,118 @@ static int da906x_reg_update(struct da9063 *priv, unsigned int reg,
return 0;
}
+static inline struct da9063 *to_da9063(struct gpio_chip *chip)
+{
+ return container_of(chip, struct da9063, gpio);
+}
+
+static int da9063_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct da9063 *priv = to_da9063(chip);
+ u8 mask, mode;
+
+ mode = DA9062_PIN_GPI << DA9062_PIN_SHIFT(offset);
+ mask = DA9062AA_GPIO0_PIN_MASK << DA9062_PIN_SHIFT(offset);
+
+ return da906x_reg_update(priv, DA9062AA_GPIO_0_1 + (offset >> 1),
+ mask, mode);
+}
+
+static int da9063_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct da9063 *priv = to_da9063(chip);
+
+ return da906x_reg_update(priv, DA9062AA_GPIO_MODE0_4, BIT(offset),
+ value << offset);
+}
+
+static int da9063_gpio_get_pin_mode(struct da9063 *priv, unsigned offset)
+{
+ int ret;
+ u8 val;
+
+ ret = i2c_read_reg(priv->client, DA9062AA_GPIO_0_1 + (offset >> 1),
+ &val, 1);
+ if (ret < 0)
+ return ret;
+
+ val >>= DA9062_PIN_SHIFT(offset);
+ val &= DA9062AA_GPIO0_PIN_MASK;
+
+ return val;
+}
+
+static int da9063_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct da9063 *priv = to_da9063(chip);
+ int gpio_dir;
+ int ret;
+ u8 val;
+
+ gpio_dir = da9063_gpio_get_pin_mode(priv, offset);
+ if (gpio_dir < 0)
+ return gpio_dir;
+
+ switch (gpio_dir) {
+ case DA9062_PIN_ALTERNATE:
+ return -ENOTSUPP;
+ case DA9062_PIN_GPI:
+ ret = i2c_read_reg(priv->client, DA9062AA_STATUS_B, &val, 1);
+ if (ret < 0)
+ return ret;
+ break;
+ case DA9062_PIN_GPO_OD:
+ /* falltrough */
+ case DA9062_PIN_GPO_PP:
+ ret = i2c_read_reg(priv->client, DA9062AA_GPIO_MODE0_4, &val, 1);
+ if (ret < 0)
+ return ret;
+ }
+
+ return val & BIT(offset);
+}
+
+static int da9063_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+ struct da9063 *priv = to_da9063(chip);
+ int gpio_dir;
+
+ gpio_dir = da9063_gpio_get_pin_mode(priv, offset);
+ if (gpio_dir < 0)
+ return gpio_dir;
+
+ switch (gpio_dir) {
+ case DA9062_PIN_ALTERNATE:
+ return -ENOTSUPP;
+ case DA9062_PIN_GPI:
+ return 1;
+ case DA9062_PIN_GPO_OD:
+ /* falltrough */
+ case DA9062_PIN_GPO_PP:
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static void da9063_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct da9063 *priv = to_da9063(chip);
+
+ da906x_reg_update(priv, DA9062AA_GPIO_MODE0_4, BIT(offset),
+ value << offset);
+
+}
+
+static struct gpio_ops da9063_gpio_ops = {
+ .direction_input = da9063_gpio_direction_input,
+ .direction_output = da9063_gpio_direction_output,
+ .get_direction = da9063_gpio_get_direction,
+ .get = da9063_gpio_get,
+ .set = da9063_gpio_set,
+};
+
static int da9063_watchdog_ping(struct da9063 *priv)
{
int ret;
@@ -265,6 +393,14 @@ static int da9063_probe(struct device_d *dev)
restart_handler_register(&priv->restart);
+ priv->gpio.base = -1;
+ priv->gpio.ngpio = 5;
+ priv->gpio.ops = &da9063_gpio_ops;
+ priv->gpio.dev = dev;
+ ret = gpiochip_add(&priv->gpio);
+ if (ret)
+ goto on_error;
+
if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node)
return of_platform_populate(dev->device_node, NULL, dev);
--
2.20.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next reply other threads:[~2019-10-11 7:22 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-11 7:22 Marco Felsch [this message]
2019-10-14 10:57 ` Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191011072217.13607-1-m.felsch@pengutronix.de \
--to=m.felsch@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox