Skip to content

Commit f3186dd

Browse files
Linus Walleijbroonie
authored andcommitted
spi: Optionally use GPIO descriptors for CS GPIOs
This augments the SPI core to optionally use GPIO descriptors for chip select on a per-master-driver opt-in basis. Drivers using this will rely on the SPI core to look up GPIO descriptors associated with the device, such as when using device tree or board files with GPIO descriptor tables. When getting descriptors from the device tree, this will in turn activate the code in gpiolib that was added in commit 6953c57 ("gpio: of: Handle SPI chipselect legacy bindings") which means that these descriptors are aware of the active low semantics that is the default for SPI CS GPIO lines and we can assume that all of these are "active high" and thus assign SPI_CS_HIGH to all CS lines on the DT path. The previously used gpio_set_value() would call down into gpiod_set_raw_value() and ignore the polarity inversion semantics. It seems like many drivers go to great lengths to set up the CS GPIO line as non-asserted, respecting SPI_CS_HIGH. We pull this out of the SPI drivers and into the core, and by simply requesting the line as GPIOD_OUT_LOW when retrieveing it from the device and relying on the gpiolib to handle any inversion semantics. This way a lot of code can be simplified and removed in each converted driver. The end goal after dealing with each driver in turn, is to delete the non-descriptor path (of_spi_register_master() for example) and let the core deal with only descriptors. The different SPI drivers have complex interactions with the core so we cannot simply change them all over, we need to use a stepwise, bisectable approach so that each driver can be converted and fixed in isolation. This patch has the intended side effect of adding support for ACPI GPIOs as it starts relying on gpiod_get_*() to get the GPIO handle associated with the device. Cc: Linuxarm <linuxarm@huawei.com> Acked-by: Jonathan Cameron <jonathan.cameron@huawei.com> Tested-by: Fangjian (Turing) <f.fangjian@huawei.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 8d24547 commit f3186dd

File tree

2 files changed

+113
-14
lines changed

2 files changed

+113
-14
lines changed

drivers/spi/spi.c

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/spi/spi.h>
2020
#include <linux/spi/spi-mem.h>
2121
#include <linux/of_gpio.h>
22+
#include <linux/gpio/consumer.h>
2223
#include <linux/pm_runtime.h>
2324
#include <linux/pm_domain.h>
2425
#include <linux/property.h>
@@ -578,7 +579,10 @@ int spi_add_device(struct spi_device *spi)
578579
goto done;
579580
}
580581

581-
if (ctlr->cs_gpios)
582+
/* Descriptors take precedence */
583+
if (ctlr->cs_gpiods)
584+
spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
585+
else if (ctlr->cs_gpios)
582586
spi->cs_gpio = ctlr->cs_gpios[spi->chip_select];
583587

584588
/* Drivers may modify this initial i/o setup, but will
@@ -772,10 +776,20 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
772776
if (spi->mode & SPI_CS_HIGH)
773777
enable = !enable;
774778

775-
if (gpio_is_valid(spi->cs_gpio)) {
776-
/* Honour the SPI_NO_CS flag */
777-
if (!(spi->mode & SPI_NO_CS))
778-
gpio_set_value(spi->cs_gpio, !enable);
779+
if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio)) {
780+
/*
781+
* Honour the SPI_NO_CS flag and invert the enable line, as
782+
* active low is default for SPI. Execution paths that handle
783+
* polarity inversion in gpiolib (such as device tree) will
784+
* enforce active high using the SPI_CS_HIGH resulting in a
785+
* double inversion through the code above.
786+
*/
787+
if (!(spi->mode & SPI_NO_CS)) {
788+
if (spi->cs_gpiod)
789+
gpiod_set_value(spi->cs_gpiod, !enable);
790+
else
791+
gpio_set_value(spi->cs_gpio, !enable);
792+
}
779793
/* Some SPI masters need both GPIO CS & slave_select */
780794
if ((spi->controller->flags & SPI_MASTER_GPIO_SS) &&
781795
spi->controller->set_cs)
@@ -1615,13 +1629,21 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
16151629
spi->mode |= SPI_CPHA;
16161630
if (of_property_read_bool(nc, "spi-cpol"))
16171631
spi->mode |= SPI_CPOL;
1618-
if (of_property_read_bool(nc, "spi-cs-high"))
1619-
spi->mode |= SPI_CS_HIGH;
16201632
if (of_property_read_bool(nc, "spi-3wire"))
16211633
spi->mode |= SPI_3WIRE;
16221634
if (of_property_read_bool(nc, "spi-lsb-first"))
16231635
spi->mode |= SPI_LSB_FIRST;
16241636

1637+
/*
1638+
* For descriptors associated with the device, polarity inversion is
1639+
* handled in the gpiolib, so all chip selects are "active high" in
1640+
* the logical sense, the gpiolib will invert the line if need be.
1641+
*/
1642+
if (ctlr->use_gpio_descriptors)
1643+
spi->mode |= SPI_CS_HIGH;
1644+
else if (of_property_read_bool(nc, "spi-cs-high"))
1645+
spi->mode |= SPI_CS_HIGH;
1646+
16251647
/* Device DUAL/QUAD mode */
16261648
if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
16271649
switch (value) {
@@ -2137,6 +2159,60 @@ static int of_spi_register_master(struct spi_controller *ctlr)
21372159
}
21382160
#endif
21392161

2162+
/**
2163+
* spi_get_gpio_descs() - grab chip select GPIOs for the master
2164+
* @ctlr: The SPI master to grab GPIO descriptors for
2165+
*/
2166+
static int spi_get_gpio_descs(struct spi_controller *ctlr)
2167+
{
2168+
int nb, i;
2169+
struct gpio_desc **cs;
2170+
struct device *dev = &ctlr->dev;
2171+
2172+
nb = gpiod_count(dev, "cs");
2173+
ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect);
2174+
2175+
/* No GPIOs at all is fine, else return the error */
2176+
if (nb == 0 || nb == -ENOENT)
2177+
return 0;
2178+
else if (nb < 0)
2179+
return nb;
2180+
2181+
cs = devm_kcalloc(dev, ctlr->num_chipselect, sizeof(*cs),
2182+
GFP_KERNEL);
2183+
if (!cs)
2184+
return -ENOMEM;
2185+
ctlr->cs_gpiods = cs;
2186+
2187+
for (i = 0; i < nb; i++) {
2188+
/*
2189+
* Most chipselects are active low, the inverted
2190+
* semantics are handled by special quirks in gpiolib,
2191+
* so initializing them GPIOD_OUT_LOW here means
2192+
* "unasserted", in most cases this will drive the physical
2193+
* line high.
2194+
*/
2195+
cs[i] = devm_gpiod_get_index_optional(dev, "cs", i,
2196+
GPIOD_OUT_LOW);
2197+
2198+
if (cs[i]) {
2199+
/*
2200+
* If we find a CS GPIO, name it after the device and
2201+
* chip select line.
2202+
*/
2203+
char *gpioname;
2204+
2205+
gpioname = devm_kasprintf(dev, GFP_KERNEL, "%s CS%d",
2206+
dev_name(dev), i);
2207+
if (!gpioname)
2208+
return -ENOMEM;
2209+
gpiod_set_consumer_name(cs[i], gpioname);
2210+
}
2211+
}
2212+
2213+
return 0;
2214+
}
2215+
21402216
static int spi_controller_check_ops(struct spi_controller *ctlr)
21412217
{
21422218
/*
@@ -2199,9 +2275,16 @@ int spi_register_controller(struct spi_controller *ctlr)
21992275
return status;
22002276

22012277
if (!spi_controller_is_slave(ctlr)) {
2202-
status = of_spi_register_master(ctlr);
2203-
if (status)
2204-
return status;
2278+
if (ctlr->use_gpio_descriptors) {
2279+
status = spi_get_gpio_descs(ctlr);
2280+
if (status)
2281+
return status;
2282+
} else {
2283+
/* Legacy code path for GPIOs from DT */
2284+
status = of_spi_register_master(ctlr);
2285+
if (status)
2286+
return status;
2287+
}
22052288
}
22062289

22072290
/* even if it's just one always-selected device, there must
@@ -2915,6 +2998,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
29152998
* cs_change is set for each transfer.
29162999
*/
29173000
if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
3001+
spi->cs_gpiod ||
29183002
gpio_is_valid(spi->cs_gpio))) {
29193003
size_t maxsize;
29203004
int ret;

include/linux/spi/spi.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/kthread.h>
1313
#include <linux/completion.h>
1414
#include <linux/scatterlist.h>
15+
#include <linux/gpio/consumer.h>
1516

1617
struct dma_chan;
1718
struct property_entry;
@@ -116,7 +117,10 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
116117
* @modalias: Name of the driver to use with this device, or an alias
117118
* for that name. This appears in the sysfs "modalias" attribute
118119
* for driver coldplugging, and in uevents used for hotplugging
119-
* @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when
120+
* @cs_gpio: LEGACY: gpio number of the chipselect line (optional, -ENOENT when
121+
* not using a GPIO line) use cs_gpiod in new drivers by opting in on
122+
* the spi_master.
123+
* @cs_gpiod: gpio descriptor of the chipselect line (optional, NULL when
120124
* not using a GPIO line)
121125
*
122126
* @statistics: statistics for the spi_device
@@ -163,7 +167,8 @@ struct spi_device {
163167
void *controller_data;
164168
char modalias[SPI_NAME_SIZE];
165169
const char *driver_override;
166-
int cs_gpio; /* chip select gpio */
170+
int cs_gpio; /* LEGACY: chip select gpio */
171+
struct gpio_desc *cs_gpiod; /* chip select gpio desc */
167172

168173
/* the statistics */
169174
struct spi_statistics statistics;
@@ -376,9 +381,17 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
376381
* controller has native support for memory like operations.
377382
* @unprepare_message: undo any work done by prepare_message().
378383
* @slave_abort: abort the ongoing transfer request on an SPI slave controller
379-
* @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
380-
* number. Any individual value may be -ENOENT for CS lines that
384+
* @cs_gpios: LEGACY: array of GPIO descs to use as chip select lines; one per
385+
* CS number. Any individual value may be -ENOENT for CS lines that
386+
* are not GPIOs (driven by the SPI controller itself). Use the cs_gpiods
387+
* in new drivers.
388+
* @cs_gpiods: Array of GPIO descs to use as chip select lines; one per CS
389+
* number. Any individual value may be NULL for CS lines that
381390
* are not GPIOs (driven by the SPI controller itself).
391+
* @use_gpio_descriptors: Turns on the code in the SPI core to parse and grab
392+
* GPIO descriptors rather than using global GPIO numbers grabbed by the
393+
* driver. This will fill in @cs_gpiods and @cs_gpios should not be used,
394+
* and SPI devices will have the cs_gpiod assigned rather than cs_gpio.
382395
* @statistics: statistics for the spi_controller
383396
* @dma_tx: DMA transmit channel
384397
* @dma_rx: DMA receive channel
@@ -557,6 +570,8 @@ struct spi_controller {
557570

558571
/* gpio chip select */
559572
int *cs_gpios;
573+
struct gpio_desc **cs_gpiods;
574+
bool use_gpio_descriptors;
560575

561576
/* statistics */
562577
struct spi_statistics statistics;

0 commit comments

Comments
 (0)