From: Marco Felsch <m.felsch@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 06/12] spi: add support to handle cs-gpios
Date: Fri, 15 Nov 2024 20:57:41 +0100 [thread overview]
Message-ID: <20241115195747.997164-6-m.felsch@pengutronix.de> (raw)
In-Reply-To: <20241115195747.997164-1-m.felsch@pengutronix.de>
At the moment all drivers have to parse the cs-gpios on their own and
have to implement the mapping. By this commit we add the support to
handle this within the core and if there is a valid CS GPIO for a device
we assign it accordingly.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
drivers/spi/spi.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++
include/spi/spi.h | 9 +++++++
2 files changed, 75 insertions(+)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 36d0653a191c..c239de9d8549 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -8,6 +8,8 @@
*/
#include <common.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
#include <linux/spi/spi-mem.h>
#include <spi/spi.h>
#include <xfuncs.h>
@@ -64,6 +66,8 @@ struct spi_device *spi_new_device(struct spi_controller *ctrl,
proxy = xzalloc(sizeof *proxy);
proxy->master = ctrl;
proxy->chip_select = chip->chip_select;
+ if (ctrl->cs_gpiods)
+ proxy->cs_gpiod = ctrl->cs_gpiods[chip->chip_select];
proxy->max_speed_hz = chip->max_speed_hz;
proxy->mode = chip->mode;
proxy->bits_per_word = chip->bits_per_word ? chip->bits_per_word : 8;
@@ -215,6 +219,62 @@ static void scan_boardinfo(struct spi_controller *ctrl)
}
}
+/**
+ * spi_get_gpio_descs() - grab chip select GPIOs for the master
+ * @ctlr: The SPI master to grab GPIO descriptors for
+ */
+static int spi_get_gpio_descs(struct spi_controller *ctlr)
+{
+ int nb, i;
+ struct gpio_desc **cs;
+ struct device *dev = ctlr->dev;
+
+ nb = gpiod_count(dev, "cs");
+ if (nb < 0) {
+ /* No GPIOs at all is fine, else return the error */
+ if (nb == -ENOENT)
+ return 0;
+ return nb;
+ }
+
+ ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect);
+
+ cs = devm_kcalloc(dev, ctlr->num_chipselect, sizeof(*cs),
+ GFP_KERNEL);
+ if (!cs)
+ return -ENOMEM;
+ ctlr->cs_gpiods = cs;
+
+ for (i = 0; i < nb; i++) {
+ /*
+ * Most chipselects are active low, the inverted
+ * semantics are handled by special quirks in gpiolib,
+ * so initializing them GPIOD_OUT_LOW here means
+ * "unasserted", in most cases this will drive the physical
+ * line high.
+ */
+ cs[i] = gpiod_get_index_optional(dev, "cs", i, GPIOD_OUT_LOW);
+ if (IS_ERR(cs[i]))
+ return PTR_ERR(cs[i]);
+
+ if (cs[i]) {
+ /*
+ * If we find a CS GPIO, name it after the device and
+ * chip select line.
+ */
+ char *gpioname;
+
+ gpioname = basprintf("%s CS%d", dev_name(dev), i);
+ if (!gpioname)
+ return -ENOMEM;
+ gpiod_set_consumer_name(cs[i], gpioname);
+ free(gpioname);
+ }
+ }
+
+ return 0;
+}
+
static int spi_controller_check_ops(struct spi_controller *ctlr)
{
/*
@@ -285,6 +345,12 @@ int spi_register_controller(struct spi_controller *ctrl)
if (ctrl->bus_num < 0)
ctrl->bus_num = dyn_bus_id--;
+ if (ctrl->use_gpio_descriptors) {
+ status = spi_get_gpio_descs(ctrl);
+ if (status)
+ return status;
+ }
+
list_add_tail(&ctrl->list, &spi_controller_list);
spi_of_register_slaves(ctrl);
diff --git a/include/spi/spi.h b/include/spi/spi.h
index 9261d508befd..53d6bd32e025 100644
--- a/include/spi/spi.h
+++ b/include/spi/spi.h
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/bitops.h>
+#include <linux/gpio/consumer.h>
struct spi_controller_mem_ops;
struct spi_message;
@@ -99,6 +100,7 @@ struct spi_device {
void *controller_state;
void *controller_data;
const char *modalias;
+ struct gpio_desc *cs_gpiod; /* Chip select gpio desc */
/*
* likely need more hooks for more protocol options affecting how
@@ -156,6 +158,9 @@ static inline void spi_set_ctldata(struct spi_device *spi, void *state)
* the device whose settings are being modified.
* @transfer: adds a message to the controller's transfer queue.
* @cleanup: frees controller-specific state
+ * @cs_gpiods: Array of GPIO descriptors to use as chip select lines; one per CS
+ * number. Any individual value may be NULL for CS lines that
+ * are not GPIOs (driven by the SPI controller itself).
* @list: link with the global spi_controller list
*
* Each SPI controller can communicate with one or more @spi_device
@@ -233,6 +238,10 @@ struct spi_controller {
/* called on release() to free memory provided by spi_controller */
void (*cleanup)(struct spi_device *spi);
+ /* GPIO chip select */
+ struct gpio_desc **cs_gpiods;
+ bool use_gpio_descriptors;
+
struct list_head list;
};
--
2.39.5
next prev parent reply other threads:[~2024-11-15 19:58 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-15 19:57 [PATCH 01/12] spi: cosmetic style fixes Marco Felsch
2024-11-15 19:57 ` [PATCH 02/12] spi: fix spi_message init during __spi_validate Marco Felsch
2024-11-15 19:57 ` [PATCH 03/12] spi: add spi_{set,get}_ctldata accessors Marco Felsch
2024-11-15 19:57 ` [PATCH 04/12] gpiolib: add support for gpiod_get_index and gpiod_get_index_optional Marco Felsch
2024-11-15 19:57 ` [PATCH 05/12] gpiolib: add support for gpiod_set_consumer_name Marco Felsch
2024-11-15 19:57 ` Marco Felsch [this message]
2024-11-25 9:19 ` [PATCH 06/12] spi: add support to handle cs-gpios Sascha Hauer
2024-11-25 10:00 ` Marco Felsch
2024-11-15 19:57 ` [PATCH 07/12] spi: add support to setup spi-cs-{setup,hold,inactive}-delay-ns Marco Felsch
2024-11-15 19:57 ` [PATCH 08/12] spi: allow reporting the effectivly used speed_hz for a transfer Marco Felsch
2024-11-15 19:57 ` [PATCH 09/12] spi: import spi_controller::flags Marco Felsch
2024-11-15 19:57 ` [PATCH 10/12] spi: add support for spi_controller::set_cs_timing Marco Felsch
2024-11-25 9:24 ` Sascha Hauer
2024-11-25 10:08 ` Marco Felsch
2024-11-25 10:20 ` Sascha Hauer
2024-11-15 19:57 ` [PATCH 11/12] spi: Provide common spi_message processing loop Marco Felsch
2024-11-15 19:57 ` [PATCH 12/12] spi: add support for BCM2835 SPI controller Marco Felsch
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=20241115195747.997164-6-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