linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper
@ 2022-10-10 12:52 Andy Shevchenko
  2022-10-10 12:52 ` [PATCH v1 2/2] pinctrl: cy8c95x0: Implement ->gpio_request_enable() and ->gpio_set_direction() Andy Shevchenko
  2022-10-17  9:54 ` [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper Linus Walleij
  0 siblings, 2 replies; 5+ messages in thread
From: Andy Shevchenko @ 2022-10-10 12:52 UTC (permalink / raw)
  To: Linus Walleij, Andy Shevchenko, Patrick Rudolph, linux-gpio,
	linux-kernel

The code in newly introduced cy8c95x0_set_mode() helper may be
used later on by another function.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/pinctrl-cy8c95x0.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c
index 68509a2301b8..33eba7ad87f4 100644
--- a/drivers/pinctrl/pinctrl-cy8c95x0.c
+++ b/drivers/pinctrl/pinctrl-cy8c95x0.c
@@ -1124,9 +1124,7 @@ static int cy8c95x0_get_function_groups(struct pinctrl_dev *pctldev, unsigned in
 	return 0;
 }
 
-static int cy8c95x0_pinmux_cfg(struct cy8c95x0_pinctrl *chip,
-			       unsigned int val,
-			       unsigned long off)
+static int cy8c95x0_set_mode(struct cy8c95x0_pinctrl *chip, unsigned int off, bool mode)
 {
 	u8 port = cypress_get_port(chip, off);
 	u8 bit = cypress_get_pin_mask(chip, off);
@@ -1137,7 +1135,20 @@ static int cy8c95x0_pinmux_cfg(struct cy8c95x0_pinctrl *chip,
 	if (ret < 0)
 		return ret;
 
-	ret = regmap_write_bits(chip->regmap, CY8C95X0_PWMSEL, bit, val ? bit : 0);
+	return regmap_write_bits(chip->regmap, CY8C95X0_PWMSEL, bit, mode ? bit : 0);
+}
+
+static int cy8c95x0_pinmux_mode(struct cy8c95x0_pinctrl *chip,
+				unsigned int selector, unsigned int group)
+{
+	u8 port = cypress_get_port(chip, group);
+	u8 bit = cypress_get_pin_mask(chip, group);
+	int ret;
+
+	if (selector == 0)
+		return cy8c95x0_set_mode(chip, group, false);
+
+	ret = cy8c95x0_set_mode(chip, group, true);
 	if (ret < 0)
 		return ret;
 
@@ -1156,7 +1167,7 @@ static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
 	int ret;
 
 	mutex_lock(&chip->i2c_lock);
-	ret = cy8c95x0_pinmux_cfg(chip, selector, group);
+	ret = cy8c95x0_pinmux_mode(chip, selector, group);
 	mutex_unlock(&chip->i2c_lock);
 
 	return ret;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 2/2] pinctrl: cy8c95x0: Implement ->gpio_request_enable() and ->gpio_set_direction()
  2022-10-10 12:52 [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper Andy Shevchenko
@ 2022-10-10 12:52 ` Andy Shevchenko
  2022-10-17  9:55   ` Linus Walleij
  2022-10-17  9:54 ` [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper Linus Walleij
  1 sibling, 1 reply; 5+ messages in thread
From: Andy Shevchenko @ 2022-10-10 12:52 UTC (permalink / raw)
  To: Linus Walleij, Andy Shevchenko, Patrick Rudolph, linux-gpio,
	linux-kernel

Without ->gpio_request_enable() and ->gpio_set_direction()
callbacks it's not possible to mux GPIO via standard GPIO
interfaces (like `gpioget` or `gpioset` tools in user space).

Implement those functions to fill the above mentioned gap.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pinctrl/pinctrl-cy8c95x0.c | 112 +++++++++++++++++------------
 1 file changed, 68 insertions(+), 44 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c
index 33eba7ad87f4..b44b36be54b3 100644
--- a/drivers/pinctrl/pinctrl-cy8c95x0.c
+++ b/drivers/pinctrl/pinctrl-cy8c95x0.c
@@ -21,9 +21,10 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 
-#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 
 /* Fast access registers */
@@ -551,36 +552,7 @@ static int cy8c95x0_read_regs_mask(struct cy8c95x0_pinctrl *chip, int reg,
 
 static int cy8c95x0_gpio_direction_input(struct gpio_chip *gc, unsigned int off)
 {
-	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
-	u8 port = cypress_get_port(chip, off);
-	u8 bit = cypress_get_pin_mask(chip, off);
-	int ret;
-
-	mutex_lock(&chip->i2c_lock);
-	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
-	if (ret)
-		goto out;
-
-	ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, bit);
-	if (ret)
-		goto out;
-
-	if (test_bit(off, chip->push_pull)) {
-		/*
-		 * Disable driving the pin by forcing it to HighZ. Only setting the
-		 * direction register isn't sufficient in Push-Pull mode.
-		 */
-		ret = regmap_write_bits(chip->regmap, CY8C95X0_DRV_HIZ, bit, bit);
-		if (ret)
-			goto out;
-
-		__clear_bit(off, chip->push_pull);
-	}
-
-out:
-	mutex_unlock(&chip->i2c_lock);
-
-	return ret;
+	return pinctrl_gpio_direction_input(gc->base + off);
 }
 
 static int cy8c95x0_gpio_direction_output(struct gpio_chip *gc,
@@ -597,19 +569,7 @@ static int cy8c95x0_gpio_direction_output(struct gpio_chip *gc,
 	if (ret)
 		return ret;
 
-	mutex_lock(&chip->i2c_lock);
-	/* Select port... */
-	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
-	if (ret)
-		goto out;
-
-	/* ...then direction */
-	ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, 0);
-
-out:
-	mutex_unlock(&chip->i2c_lock);
-
-	return ret;
+	return pinctrl_gpio_direction_output(gc->base + off);
 }
 
 static int cy8c95x0_gpio_get_value(struct gpio_chip *gc, unsigned int off)
@@ -850,6 +810,8 @@ static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip)
 {
 	struct gpio_chip *gc = &chip->gpio_chip;
 
+	gc->request = gpiochip_generic_request;
+	gc->free = gpiochip_generic_free;
 	gc->direction_input  = cy8c95x0_gpio_direction_input;
 	gc->direction_output = cy8c95x0_gpio_direction_output;
 	gc->get = cy8c95x0_gpio_get_value;
@@ -1173,11 +1135,73 @@ static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
 	return ret;
 }
 
+static int cy8c95x0_gpio_request_enable(struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned int pin)
+{
+	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
+	int ret;
+
+	mutex_lock(&chip->i2c_lock);
+	ret = cy8c95x0_set_mode(chip, pin, false);
+	mutex_unlock(&chip->i2c_lock);
+
+	return ret;
+}
+
+static int cy8c95x0_pinmux_direction(struct cy8c95x0_pinctrl *chip,
+				     unsigned int pin, bool input)
+{
+	u8 port = cypress_get_port(chip, pin);
+	u8 bit = cypress_get_pin_mask(chip, pin);
+	int ret;
+
+	/* Select port... */
+	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
+	if (ret)
+		return ret;
+
+	/* ...then direction */
+	ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, input ? bit : 0);
+	if (ret)
+		return ret;
+
+	/*
+	 * Disable driving the pin by forcing it to HighZ. Only setting
+	 * the direction register isn't sufficient in Push-Pull mode.
+	 */
+	if (input && test_bit(pin, chip->push_pull)) {
+		ret = regmap_write_bits(chip->regmap, CY8C95X0_DRV_HIZ, bit, bit);
+		if (ret)
+			return ret;
+
+		__clear_bit(pin, chip->push_pull);
+	}
+
+	return 0;
+}
+
+static int cy8c95x0_gpio_set_direction(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned int pin, bool input)
+{
+	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
+	int ret;
+
+	mutex_lock(&chip->i2c_lock);
+	ret = cy8c95x0_pinmux_direction(chip, pin, input);
+	mutex_unlock(&chip->i2c_lock);
+
+	return ret;
+}
+
 static const struct pinmux_ops cy8c95x0_pmxops = {
 	.get_functions_count = cy8c95x0_get_functions_count,
 	.get_function_name = cy8c95x0_get_function_name,
 	.get_function_groups = cy8c95x0_get_function_groups,
 	.set_mux = cy8c95x0_set_mux,
+	.gpio_request_enable = cy8c95x0_gpio_request_enable,
+	.gpio_set_direction = cy8c95x0_gpio_set_direction,
 	.strict = true,
 };
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper
  2022-10-10 12:52 [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper Andy Shevchenko
  2022-10-10 12:52 ` [PATCH v1 2/2] pinctrl: cy8c95x0: Implement ->gpio_request_enable() and ->gpio_set_direction() Andy Shevchenko
@ 2022-10-17  9:54 ` Linus Walleij
  1 sibling, 0 replies; 5+ messages in thread
From: Linus Walleij @ 2022-10-17  9:54 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: Patrick Rudolph, linux-gpio, linux-kernel

On Mon, Oct 10, 2022 at 2:52 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> The code in newly introduced cy8c95x0_set_mode() helper may be
> used later on by another function.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 2/2] pinctrl: cy8c95x0: Implement ->gpio_request_enable() and ->gpio_set_direction()
  2022-10-10 12:52 ` [PATCH v1 2/2] pinctrl: cy8c95x0: Implement ->gpio_request_enable() and ->gpio_set_direction() Andy Shevchenko
@ 2022-10-17  9:55   ` Linus Walleij
  2022-10-17 12:17     ` Andy Shevchenko
  0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2022-10-17  9:55 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: Patrick Rudolph, linux-gpio, linux-kernel

On Mon, Oct 10, 2022 at 2:52 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> Without ->gpio_request_enable() and ->gpio_set_direction()
> callbacks it's not possible to mux GPIO via standard GPIO
> interfaces (like `gpioget` or `gpioset` tools in user space).
>
> Implement those functions to fill the above mentioned gap.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Patch applied, it looked a bit scary but I realize you probably
have tested it on the hardware and made sure it works.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 2/2] pinctrl: cy8c95x0: Implement ->gpio_request_enable() and ->gpio_set_direction()
  2022-10-17  9:55   ` Linus Walleij
@ 2022-10-17 12:17     ` Andy Shevchenko
  0 siblings, 0 replies; 5+ messages in thread
From: Andy Shevchenko @ 2022-10-17 12:17 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Patrick Rudolph, linux-gpio, linux-kernel

On Mon, Oct 17, 2022 at 11:55:07AM +0200, Linus Walleij wrote:
> On Mon, Oct 10, 2022 at 2:52 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> 
> > Without ->gpio_request_enable() and ->gpio_set_direction()
> > callbacks it's not possible to mux GPIO via standard GPIO
> > interfaces (like `gpioget` or `gpioset` tools in user space).
> >
> > Implement those functions to fill the above mentioned gap.
> >
> > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> 
> Patch applied, it looked a bit scary but I realize you probably
> have tested it on the hardware and made sure it works.

Yes, exactly. The problem the driver had (before this series) I realised is
that the switching to function won't make it GPIO request and GPIO request
didn't switch function.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-10-17 12:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-10 12:52 [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper Andy Shevchenko
2022-10-10 12:52 ` [PATCH v1 2/2] pinctrl: cy8c95x0: Implement ->gpio_request_enable() and ->gpio_set_direction() Andy Shevchenko
2022-10-17  9:55   ` Linus Walleij
2022-10-17 12:17     ` Andy Shevchenko
2022-10-17  9:54 ` [PATCH v1 1/2] pinctrl: cy8c95x0: Extract cy8c95x0_set_mode() helper Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).