linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] spi: xcomm: support GPO pin
@ 2024-07-04 13:49 Nuno Sa
  2024-07-04 13:49 ` [PATCH 1/4] spi: xcomm: add gpiochip support Nuno Sa
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Nuno Sa @ 2024-07-04 13:49 UTC (permalink / raw)
  To: linux-spi; +Cc: Mark Brown, Michael Hennerich

Main purpose of the series is to expose one supported pin as GPO through
a simple gpiochip.

While in here and as the driver is fairly simple add some more straight
forward cleanups. 

---
Michael Hennerich (1):
      spi: xcomm: add gpiochip support

Nuno Sa (3):
      spi: xcomm: make use of devm_spi_alloc_host()
      spi: xcomm: remove i2c_set_clientdata()
      spi: xcomm: fix coding style

 drivers/spi/spi-xcomm.c | 88 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 70 insertions(+), 18 deletions(-)
---
base-commit: 5b6cad81d0c1b1c71533f2898a47f3d2fcfc4595
change-id: 20240704-dev-spi-xcomm-gpiochip-8114c9894f07
--

Thanks!
- Nuno Sá


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

* [PATCH 1/4] spi: xcomm: add gpiochip support
  2024-07-04 13:49 [PATCH 0/4] spi: xcomm: support GPO pin Nuno Sa
@ 2024-07-04 13:49 ` Nuno Sa
  2024-07-04 13:53   ` Mark Brown
  2024-07-04 13:49 ` [PATCH 2/4] spi: xcomm: make use of devm_spi_alloc_host() Nuno Sa
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Nuno Sa @ 2024-07-04 13:49 UTC (permalink / raw)
  To: linux-spi; +Cc: Mark Brown, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

The hardware can expose one pin as a GPO. Hence, register a simple
gpiochip to support it.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Co-developed-by: Nuno Sa <nuno.sa@analog.com>
Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/spi/spi-xcomm.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c
index 63354dd3110f..358e0b84ee60 100644
--- a/drivers/spi/spi-xcomm.c
+++ b/drivers/spi/spi-xcomm.c
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/gpio/driver.h>
 #include <linux/spi/spi.h>
 #include <asm/unaligned.h>
 
@@ -26,12 +27,16 @@
 
 #define SPI_XCOMM_CMD_UPDATE_CONFIG	0x03
 #define SPI_XCOMM_CMD_WRITE		0x04
+#define SPI_XCOMM_CMD_GPIO_SET		0x05
 
 #define SPI_XCOMM_CLOCK 48000000
 
 struct spi_xcomm {
 	struct i2c_client *i2c;
 
+	struct gpio_chip gc;
+	int gpio_val;
+
 	uint16_t settings;
 	uint16_t chipselect;
 
@@ -40,6 +45,54 @@ struct spi_xcomm {
 	uint8_t buf[63];
 };
 
+static void spi_xcomm_gpio_set_value(struct gpio_chip *chip,
+				     unsigned int offset, int val)
+{
+	struct spi_xcomm *spi_xcomm = gpiochip_get_data(chip);
+	unsigned char buf[2];
+	int ret;
+
+	buf[0] = SPI_XCOMM_CMD_GPIO_SET;
+	buf[1] = !!val;
+	ret = i2c_master_send(spi_xcomm->i2c, buf, 2);
+	if (ret < 0)
+		return;
+
+	spi_xcomm->gpio_val = !!val;
+}
+
+static int spi_xcomm_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
+{
+	struct spi_xcomm *spi_xcomm = gpiochip_get_data(chip);
+
+	return spi_xcomm->gpio_val;
+}
+
+static int spi_xcomm_gpio_get_direction(struct gpio_chip *chip,
+					unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int spi_xcomm_gpio_add(struct spi_xcomm *spi_xcomm)
+{
+	struct device *dev = &spi_xcomm->i2c->dev;
+
+	if (!IS_ENABLED(CONFIG_GPIOLIB))
+		return 0;
+
+	spi_xcomm->gc.get_direction = spi_xcomm_gpio_get_direction;
+	spi_xcomm->gc.get = spi_xcomm_gpio_get_value;
+	spi_xcomm->gc.set = spi_xcomm_gpio_set_value;
+	spi_xcomm->gc.can_sleep = 1;
+	spi_xcomm->gc.base = -1;
+	spi_xcomm->gc.ngpio = 1;
+	spi_xcomm->gc.label = spi_xcomm->i2c->name;
+	spi_xcomm->gc.owner = THIS_MODULE;
+
+	return devm_gpiochip_add_data(dev, &spi_xcomm->gc, spi_xcomm);
+}
+
 static int spi_xcomm_sync_config(struct spi_xcomm *spi_xcomm, unsigned int len)
 {
 	uint16_t settings;
@@ -227,7 +280,7 @@ static int spi_xcomm_probe(struct i2c_client *i2c)
 	if (ret < 0)
 		spi_controller_put(host);
 
-	return ret;
+	return spi_xcomm_gpio_add(spi_xcomm);
 }
 
 static const struct i2c_device_id spi_xcomm_ids[] = {

-- 
2.45.2


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

* [PATCH 2/4] spi: xcomm: make use of devm_spi_alloc_host()
  2024-07-04 13:49 [PATCH 0/4] spi: xcomm: support GPO pin Nuno Sa
  2024-07-04 13:49 ` [PATCH 1/4] spi: xcomm: add gpiochip support Nuno Sa
@ 2024-07-04 13:49 ` Nuno Sa
  2024-07-04 13:49 ` [PATCH 3/4] spi: xcomm: remove i2c_set_clientdata() Nuno Sa
  2024-07-04 13:49 ` [PATCH 4/4] spi: xcomm: fix coding style Nuno Sa
  3 siblings, 0 replies; 9+ messages in thread
From: Nuno Sa @ 2024-07-04 13:49 UTC (permalink / raw)
  To: linux-spi; +Cc: Mark Brown, Michael Hennerich

Use devm_spi_alloc_host() so that there's no need to call
spi_controller_put() in the error path.

Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/spi/spi-xcomm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c
index 358e0b84ee60..5a27eaed4183 100644
--- a/drivers/spi/spi-xcomm.c
+++ b/drivers/spi/spi-xcomm.c
@@ -261,7 +261,7 @@ static int spi_xcomm_probe(struct i2c_client *i2c)
 	struct spi_controller *host;
 	int ret;
 
-	host = spi_alloc_host(&i2c->dev, sizeof(*spi_xcomm));
+	host = devm_spi_alloc_host(&i2c->dev, sizeof(*spi_xcomm));
 	if (!host)
 		return -ENOMEM;
 
@@ -278,7 +278,7 @@ static int spi_xcomm_probe(struct i2c_client *i2c)
 
 	ret = devm_spi_register_controller(&i2c->dev, host);
 	if (ret < 0)
-		spi_controller_put(host);
+		return ret;
 
 	return spi_xcomm_gpio_add(spi_xcomm);
 }

-- 
2.45.2


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

* [PATCH 3/4] spi: xcomm: remove i2c_set_clientdata()
  2024-07-04 13:49 [PATCH 0/4] spi: xcomm: support GPO pin Nuno Sa
  2024-07-04 13:49 ` [PATCH 1/4] spi: xcomm: add gpiochip support Nuno Sa
  2024-07-04 13:49 ` [PATCH 2/4] spi: xcomm: make use of devm_spi_alloc_host() Nuno Sa
@ 2024-07-04 13:49 ` Nuno Sa
  2024-07-04 13:49 ` [PATCH 4/4] spi: xcomm: fix coding style Nuno Sa
  3 siblings, 0 replies; 9+ messages in thread
From: Nuno Sa @ 2024-07-04 13:49 UTC (permalink / raw)
  To: linux-spi; +Cc: Mark Brown, Michael Hennerich

i2c_get_clientdata() is not being called anywhere so that we do not need
to set clientdata.

Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/spi/spi-xcomm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c
index 5a27eaed4183..136d81fb5f56 100644
--- a/drivers/spi/spi-xcomm.c
+++ b/drivers/spi/spi-xcomm.c
@@ -274,7 +274,6 @@ static int spi_xcomm_probe(struct i2c_client *i2c)
 	host->flags = SPI_CONTROLLER_HALF_DUPLEX;
 	host->transfer_one_message = spi_xcomm_transfer_one;
 	host->dev.of_node = i2c->dev.of_node;
-	i2c_set_clientdata(i2c, host);
 
 	ret = devm_spi_register_controller(&i2c->dev, host);
 	if (ret < 0)

-- 
2.45.2


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

* [PATCH 4/4] spi: xcomm: fix coding style
  2024-07-04 13:49 [PATCH 0/4] spi: xcomm: support GPO pin Nuno Sa
                   ` (2 preceding siblings ...)
  2024-07-04 13:49 ` [PATCH 3/4] spi: xcomm: remove i2c_set_clientdata() Nuno Sa
@ 2024-07-04 13:49 ` Nuno Sa
  3 siblings, 0 replies; 9+ messages in thread
From: Nuno Sa @ 2024-07-04 13:49 UTC (permalink / raw)
  To: linux-spi; +Cc: Mark Brown, Michael Hennerich

Just cosmetics. No functional change intended.

While at it, removed a couple of redundant else if() statements.

Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/spi/spi-xcomm.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c
index 136d81fb5f56..9052bddedd10 100644
--- a/drivers/spi/spi-xcomm.c
+++ b/drivers/spi/spi-xcomm.c
@@ -37,12 +37,12 @@ struct spi_xcomm {
 	struct gpio_chip gc;
 	int gpio_val;
 
-	uint16_t settings;
-	uint16_t chipselect;
+	u16 settings;
+	u16 chipselect;
 
 	unsigned int current_speed;
 
-	uint8_t buf[63];
+	u8 buf[63];
 };
 
 static void spi_xcomm_gpio_set_value(struct gpio_chip *chip,
@@ -95,8 +95,8 @@ static int spi_xcomm_gpio_add(struct spi_xcomm *spi_xcomm)
 
 static int spi_xcomm_sync_config(struct spi_xcomm *spi_xcomm, unsigned int len)
 {
-	uint16_t settings;
-	uint8_t *buf = spi_xcomm->buf;
+	u16 settings;
+	u8 *buf = spi_xcomm->buf;
 
 	settings = spi_xcomm->settings;
 	settings |= len << SPI_XCOMM_SETTINGS_LEN_OFFSET;
@@ -109,10 +109,10 @@ static int spi_xcomm_sync_config(struct spi_xcomm *spi_xcomm, unsigned int len)
 }
 
 static void spi_xcomm_chipselect(struct spi_xcomm *spi_xcomm,
-	struct spi_device *spi, int is_active)
+				 struct spi_device *spi, int is_active)
 {
 	unsigned long cs = spi_get_chipselect(spi, 0);
-	uint16_t chipselect = spi_xcomm->chipselect;
+	u16 chipselect = spi_xcomm->chipselect;
 
 	if (is_active)
 		chipselect |= BIT(cs);
@@ -123,7 +123,8 @@ static void spi_xcomm_chipselect(struct spi_xcomm *spi_xcomm,
 }
 
 static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm,
-	struct spi_device *spi, struct spi_transfer *t, unsigned int *settings)
+				    struct spi_device *spi, struct spi_transfer *t,
+				    unsigned int *settings)
 {
 	if (t->len > 62)
 		return -EINVAL;
@@ -161,7 +162,7 @@ static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm,
 }
 
 static int spi_xcomm_txrx_bufs(struct spi_xcomm *spi_xcomm,
-	struct spi_device *spi, struct spi_transfer *t)
+			       struct spi_device *spi, struct spi_transfer *t)
 {
 	int ret;
 
@@ -172,13 +173,13 @@ static int spi_xcomm_txrx_bufs(struct spi_xcomm *spi_xcomm,
 		ret = i2c_master_send(spi_xcomm->i2c, spi_xcomm->buf, t->len + 1);
 		if (ret < 0)
 			return ret;
-		else if (ret != t->len + 1)
+		if (ret != t->len + 1)
 			return -EIO;
 	} else if (t->rx_buf) {
 		ret = i2c_master_recv(spi_xcomm->i2c, t->rx_buf, t->len);
 		if (ret < 0)
 			return ret;
-		else if (ret != t->len)
+		if (ret != t->len)
 			return -EIO;
 	}
 
@@ -186,12 +187,12 @@ static int spi_xcomm_txrx_bufs(struct spi_xcomm *spi_xcomm,
 }
 
 static int spi_xcomm_transfer_one(struct spi_controller *host,
-	struct spi_message *msg)
+				  struct spi_message *msg)
 {
 	struct spi_xcomm *spi_xcomm = spi_controller_get_devdata(host);
 	unsigned int settings = spi_xcomm->settings;
 	struct spi_device *spi = msg->spi;
-	unsigned cs_change = 0;
+	unsigned int cs_change = 0;
 	struct spi_transfer *t;
 	bool is_first = true;
 	int status = 0;
@@ -200,7 +201,6 @@ static int spi_xcomm_transfer_one(struct spi_controller *host,
 	spi_xcomm_chipselect(spi_xcomm, spi, true);
 
 	list_for_each_entry(t, &msg->transfers, transfer_list) {
-
 		if (!t->tx_buf && !t->rx_buf && t->len) {
 			status = -EINVAL;
 			break;

-- 
2.45.2


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

* Re: [PATCH 1/4] spi: xcomm: add gpiochip support
  2024-07-04 13:49 ` [PATCH 1/4] spi: xcomm: add gpiochip support Nuno Sa
@ 2024-07-04 13:53   ` Mark Brown
  2024-07-04 14:00     ` Nuno Sá
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Brown @ 2024-07-04 13:53 UTC (permalink / raw)
  To: Nuno Sa; +Cc: linux-spi, Michael Hennerich

[-- Attachment #1: Type: text/plain, Size: 393 bytes --]

On Thu, Jul 04, 2024 at 03:49:12PM +0200, Nuno Sa wrote:

> +static int spi_xcomm_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
> +{
> +	struct spi_xcomm *spi_xcomm = gpiochip_get_data(chip);
> +
> +	return spi_xcomm->gpio_val;
> +}

It seems like the hardware doesn't support input at all so should there
even be a get operation?  gpiolib appears to cope fine with omitting it.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 1/4] spi: xcomm: add gpiochip support
  2024-07-04 13:53   ` Mark Brown
@ 2024-07-04 14:00     ` Nuno Sá
  2024-07-04 15:45       ` Mark Brown
  0 siblings, 1 reply; 9+ messages in thread
From: Nuno Sá @ 2024-07-04 14:00 UTC (permalink / raw)
  To: Mark Brown, Nuno Sa; +Cc: linux-spi, Michael Hennerich

On Thu, 2024-07-04 at 14:53 +0100, Mark Brown wrote:
> On Thu, Jul 04, 2024 at 03:49:12PM +0200, Nuno Sa wrote:
> 
> > +static int spi_xcomm_gpio_get_value(struct gpio_chip *chip, unsigned int
> > offset)
> > +{
> > +	struct spi_xcomm *spi_xcomm = gpiochip_get_data(chip);
> > +
> > +	return spi_xcomm->gpio_val;
> > +}
> 
> It seems like the hardware doesn't support input at all so should there
> even be a get operation?  gpiolib appears to cope fine with omitting it.

Just following recommendations :)

https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/gpio/driver.h#L336

- Nuno Sá

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

* Re: [PATCH 1/4] spi: xcomm: add gpiochip support
  2024-07-04 14:00     ` Nuno Sá
@ 2024-07-04 15:45       ` Mark Brown
  2024-07-05  9:13         ` Nuno Sá
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Brown @ 2024-07-04 15:45 UTC (permalink / raw)
  To: Nuno Sá; +Cc: Nuno Sa, linux-spi, Michael Hennerich

[-- Attachment #1: Type: text/plain, Size: 743 bytes --]

On Thu, Jul 04, 2024 at 04:00:15PM +0200, Nuno Sá wrote:
> On Thu, 2024-07-04 at 14:53 +0100, Mark Brown wrote:
> > On Thu, Jul 04, 2024 at 03:49:12PM +0200, Nuno Sa wrote:
> > 
> > > +static int spi_xcomm_gpio_get_value(struct gpio_chip *chip, unsigned int
> > > offset)
> > > +{
> > > +	struct spi_xcomm *spi_xcomm = gpiochip_get_data(chip);
> > > +
> > > +	return spi_xcomm->gpio_val;
> > > +}

> > It seems like the hardware doesn't support input at all so should there
> > even be a get operation?  gpiolib appears to cope fine with omitting it.

> Just following recommendations :)

> https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/gpio/driver.h#L336

That comment is for get_direction(), not get().

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 1/4] spi: xcomm: add gpiochip support
  2024-07-04 15:45       ` Mark Brown
@ 2024-07-05  9:13         ` Nuno Sá
  0 siblings, 0 replies; 9+ messages in thread
From: Nuno Sá @ 2024-07-05  9:13 UTC (permalink / raw)
  To: Mark Brown; +Cc: Nuno Sa, linux-spi, Michael Hennerich

On Thu, 2024-07-04 at 16:45 +0100, Mark Brown wrote:
> On Thu, Jul 04, 2024 at 04:00:15PM +0200, Nuno Sá wrote:
> > On Thu, 2024-07-04 at 14:53 +0100, Mark Brown wrote:
> > > On Thu, Jul 04, 2024 at 03:49:12PM +0200, Nuno Sa wrote:
> > > 
> > > > +static int spi_xcomm_gpio_get_value(struct gpio_chip *chip, unsigned int
> > > > offset)
> > > > +{
> > > > +	struct spi_xcomm *spi_xcomm = gpiochip_get_data(chip);
> > > > +
> > > > +	return spi_xcomm->gpio_val;
> > > > +}
> 
> > > It seems like the hardware doesn't support input at all so should there
> > > even be a get operation?  gpiolib appears to cope fine with omitting it.
> 
> > Just following recommendations :)
> 
> > https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/gpio/driver.h#L336
> 
> That comment is for get_direction(), not get().

Oh right, sorry. For some reason I assumed get_direction()... Well, get() was mainly
to not get an error when reading the GPIO value from userspace (eg:
/sys/clagg/gpio). 

That said, we're just caching the value in the driver in case the i2c transfer does
not fail so I guess yes, we can make this even simpler and remove get() and
'gpio_val'. Userspace apps can very well cache the value themselves.

- Nuno Sá

 

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

end of thread, other threads:[~2024-07-05  9:13 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-04 13:49 [PATCH 0/4] spi: xcomm: support GPO pin Nuno Sa
2024-07-04 13:49 ` [PATCH 1/4] spi: xcomm: add gpiochip support Nuno Sa
2024-07-04 13:53   ` Mark Brown
2024-07-04 14:00     ` Nuno Sá
2024-07-04 15:45       ` Mark Brown
2024-07-05  9:13         ` Nuno Sá
2024-07-04 13:49 ` [PATCH 2/4] spi: xcomm: make use of devm_spi_alloc_host() Nuno Sa
2024-07-04 13:49 ` [PATCH 3/4] spi: xcomm: remove i2c_set_clientdata() Nuno Sa
2024-07-04 13:49 ` [PATCH 4/4] spi: xcomm: fix coding style Nuno Sa

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).