lkml.org 
[lkml]   [2019]   [Nov]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v4 5/5] gpio: syscon: Add support for the Xylon LogiCVC GPIOs
Date
The LogiCVC display hardware block comes with GPIO capabilities
that must be exposed separately from the main driver (as GPIOs) for
use with regulators and panels. A syscon is used to share the same
regmap across the two drivers.

Since the GPIO capabilities are pretty simple, add them to the syscon
GPIO driver.

Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
---
drivers/gpio/gpio-syscon.c | 65 ++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)

diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c
index 36136b7f3a3b..cf1127f81824 100644
--- a/drivers/gpio/gpio-syscon.c
+++ b/drivers/gpio/gpio-syscon.c
@@ -190,6 +190,67 @@ static const struct syscon_gpio_data keystone_dsp_gpio = {
.set = keystone_gpio_set,
};

+#define LOGICVC_CTRL_REG 0x40
+#define LOGICVC_CTRL_GPIO_SHIFT 11
+#define LOGICVC_CTRL_GPIO_BITS 5
+
+#define LOGICVC_POWER_CTRL_REG 0x78
+#define LOGICVC_POWER_CTRL_GPIO_SHIFT 0
+#define LOGICVC_POWER_CTRL_GPIO_BITS 4
+
+static void logicvc_gpio_offset(struct syscon_gpio_priv *priv,
+ unsigned offset, unsigned int *reg,
+ unsigned int *bit)
+{
+ if (offset >= LOGICVC_CTRL_GPIO_BITS) {
+ *reg = LOGICVC_POWER_CTRL_REG;
+
+ /* To the (virtual) power ctrl offset. */
+ offset -= LOGICVC_CTRL_GPIO_BITS;
+ /* To the actual bit offset in reg. */
+ offset += LOGICVC_POWER_CTRL_GPIO_SHIFT;
+ } else {
+ *reg = LOGICVC_CTRL_REG;
+
+ /* To the actual bit offset in reg. */
+ offset += LOGICVC_CTRL_GPIO_SHIFT;
+ }
+
+ *bit = BIT(offset);
+}
+
+static int logicvc_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct syscon_gpio_priv *priv = gpiochip_get_data(chip);
+ unsigned int reg, bit, value;
+ int ret;
+
+ logicvc_gpio_offset(priv, offset, &reg, &bit);
+
+ ret = regmap_read(priv->syscon, reg, &value);
+ if (ret)
+ return ret;
+
+ return !!(value & bit);
+}
+
+static void logicvc_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct syscon_gpio_priv *priv = gpiochip_get_data(chip);
+ unsigned int reg, bit;
+
+ logicvc_gpio_offset(priv, offset, &reg, &bit);
+
+ regmap_update_bits(priv->syscon, reg, bit, val ? bit : 0);
+}
+
+static const struct syscon_gpio_data logicvc_gpio = {
+ .flags = GPIO_SYSCON_FEAT_OUT,
+ .bit_count = LOGICVC_CTRL_GPIO_BITS + LOGICVC_POWER_CTRL_GPIO_BITS,
+ .get = logicvc_gpio_get,
+ .set = logicvc_gpio_set,
+};
+
static const struct of_device_id syscon_gpio_ids[] = {
{
.compatible = "cirrus,ep7209-mctrl-gpio",
@@ -203,6 +264,10 @@ static const struct of_device_id syscon_gpio_ids[] = {
.compatible = "rockchip,rk3328-grf-gpio",
.data = &rockchip_rk3328_gpio_mute,
},
+ {
+ .compatible = "xylon,logicvc-3.02.a-gpio",
+ .data = &logicvc_gpio,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, syscon_gpio_ids);
--
2.24.0
\
 
 \ /
  Last update: 2019-11-28 16:56    [W:0.210 / U:0.084 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site