diff options
| author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-11-15 14:19:57 -0500 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2012-11-21 18:25:33 -0500 |
| commit | 743179849015dc71bb2ea63d8cd4bfa7fdfb4bc6 (patch) | |
| tree | dcf0d554dd907740a5f4519355d4e896a94efd3b | |
| parent | 15d0983f5cc862facc8453a592220598a36d7f9d (diff) | |
of_spi: add generic binding support to specify cs gpio
This will allow to use gpio for chip select with no modification in the
driver binding
When use the cs-gpios, the gpio number will be passed via the cs_gpio field
and the number of chip select will automatically increased with max(hw cs, gpio cs).
So if for example the controller has 2 CS lines, and the cs-gpios
property looks like this:
cs-gpios = <&gpio1 0 0> <0> <&gpio1 1 0> <&gpio1 2 0>;
Then it should be configured so that num_chipselect = 4 with the
following mapping:
cs0 : &gpio1 0 0
cs1 : native
cs2 : &gpio1 1 0
cs3 : &gpio1 2 0
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: devicetree-discuss@lists.ozlabs.org
Cc: spi-devel-general@lists.sourceforge.net
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
[grant.likely: fixed up type of cs count so min() can do type checking]
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
| -rw-r--r-- | Documentation/devicetree/bindings/spi/spi-bus.txt | 20 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 54 | ||||
| -rw-r--r-- | include/linux/spi/spi.h | 3 |
3 files changed, 74 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index d2c33d0f533e..77a8b0d39b54 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt | |||
| @@ -12,6 +12,7 @@ The SPI master node requires the following properties: | |||
| 12 | - #size-cells - should be zero. | 12 | - #size-cells - should be zero. |
| 13 | - compatible - name of SPI bus controller following generic names | 13 | - compatible - name of SPI bus controller following generic names |
| 14 | recommended practice. | 14 | recommended practice. |
| 15 | - cs-gpios - (optional) gpios chip select. | ||
| 15 | No other properties are required in the SPI bus node. It is assumed | 16 | No other properties are required in the SPI bus node. It is assumed |
| 16 | that a driver for an SPI bus device will understand that it is an SPI bus. | 17 | that a driver for an SPI bus device will understand that it is an SPI bus. |
| 17 | However, the binding does not attempt to define the specific method for | 18 | However, the binding does not attempt to define the specific method for |
| @@ -24,6 +25,22 @@ support describing the chip select layout. | |||
| 24 | Optional property: | 25 | Optional property: |
| 25 | - num-cs : total number of chipselects | 26 | - num-cs : total number of chipselects |
| 26 | 27 | ||
| 28 | If cs-gpios is used the number of chip select will automatically increased | ||
| 29 | with max(cs-gpios > hw cs) | ||
| 30 | |||
| 31 | So if for example the controller has 2 CS lines, and the cs-gpios | ||
| 32 | property looks like this: | ||
| 33 | |||
| 34 | cs-gpios = <&gpio1 0 0> <0> <&gpio1 1 0> <&gpio1 2 0>; | ||
| 35 | |||
| 36 | Then it should be configured so that num_chipselect = 4 with the | ||
| 37 | following mapping: | ||
| 38 | |||
| 39 | cs0 : &gpio1 0 0 | ||
| 40 | cs1 : native | ||
| 41 | cs2 : &gpio1 1 0 | ||
| 42 | cs3 : &gpio1 2 0 | ||
| 43 | |||
| 27 | SPI slave nodes must be children of the SPI master node and can | 44 | SPI slave nodes must be children of the SPI master node and can |
| 28 | contain the following properties. | 45 | contain the following properties. |
| 29 | - reg - (required) chip select address of device. | 46 | - reg - (required) chip select address of device. |
| @@ -37,6 +54,9 @@ contain the following properties. | |||
| 37 | - spi-cs-high - (optional) Empty property indicating device requires | 54 | - spi-cs-high - (optional) Empty property indicating device requires |
| 38 | chip select active high | 55 | chip select active high |
| 39 | 56 | ||
| 57 | If a gpio chipselect is used for the SPI slave the gpio number will be passed | ||
| 58 | via the cs_gpio | ||
| 59 | |||
| 40 | SPI example for an MPC5200 SPI bus: | 60 | SPI example for an MPC5200 SPI bus: |
| 41 | spi@f00 { | 61 | spi@f00 { |
| 42 | #address-cells = <1>; | 62 | #address-cells = <1>; |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 84c2861d6f4d..1587a4a5ff41 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/mod_devicetable.h> | 31 | #include <linux/mod_devicetable.h> |
| 32 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
| 33 | #include <linux/of_gpio.h> | ||
| 33 | #include <linux/pm_runtime.h> | 34 | #include <linux/pm_runtime.h> |
| 34 | #include <linux/export.h> | 35 | #include <linux/export.h> |
| 35 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
| @@ -327,6 +328,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master) | |||
| 327 | spi->dev.parent = &master->dev; | 328 | spi->dev.parent = &master->dev; |
| 328 | spi->dev.bus = &spi_bus_type; | 329 | spi->dev.bus = &spi_bus_type; |
| 329 | spi->dev.release = spidev_release; | 330 | spi->dev.release = spidev_release; |
| 331 | spi->cs_gpio = -EINVAL; | ||
| 330 | device_initialize(&spi->dev); | 332 | device_initialize(&spi->dev); |
| 331 | return spi; | 333 | return spi; |
| 332 | } | 334 | } |
| @@ -344,15 +346,16 @@ EXPORT_SYMBOL_GPL(spi_alloc_device); | |||
| 344 | int spi_add_device(struct spi_device *spi) | 346 | int spi_add_device(struct spi_device *spi) |
| 345 | { | 347 | { |
| 346 | static DEFINE_MUTEX(spi_add_lock); | 348 | static DEFINE_MUTEX(spi_add_lock); |
| 347 | struct device *dev = spi->master->dev.parent; | 349 | struct spi_master *master = spi->master; |
| 350 | struct device *dev = master->dev.parent; | ||
| 348 | struct device *d; | 351 | struct device *d; |
| 349 | int status; | 352 | int status; |
| 350 | 353 | ||
| 351 | /* Chipselects are numbered 0..max; validate. */ | 354 | /* Chipselects are numbered 0..max; validate. */ |
| 352 | if (spi->chip_select >= spi->master->num_chipselect) { | 355 | if (spi->chip_select >= master->num_chipselect) { |
| 353 | dev_err(dev, "cs%d >= max %d\n", | 356 | dev_err(dev, "cs%d >= max %d\n", |
| 354 | spi->chip_select, | 357 | spi->chip_select, |
| 355 | spi->master->num_chipselect); | 358 | master->num_chipselect); |
| 356 | return -EINVAL; | 359 | return -EINVAL; |
| 357 | } | 360 | } |
| 358 | 361 | ||
| @@ -376,6 +379,9 @@ int spi_add_device(struct spi_device *spi) | |||
| 376 | goto done; | 379 | goto done; |
| 377 | } | 380 | } |
| 378 | 381 | ||
| 382 | if (master->cs_gpios) | ||
| 383 | spi->cs_gpio = master->cs_gpios[spi->chip_select]; | ||
| 384 | |||
| 379 | /* Drivers may modify this initial i/o setup, but will | 385 | /* Drivers may modify this initial i/o setup, but will |
| 380 | * normally rely on the device being setup. Devices | 386 | * normally rely on the device being setup. Devices |
| 381 | * using SPI_CS_HIGH can't coexist well otherwise... | 387 | * using SPI_CS_HIGH can't coexist well otherwise... |
| @@ -946,6 +952,44 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) | |||
| 946 | } | 952 | } |
| 947 | EXPORT_SYMBOL_GPL(spi_alloc_master); | 953 | EXPORT_SYMBOL_GPL(spi_alloc_master); |
| 948 | 954 | ||
| 955 | #ifdef CONFIG_OF | ||
| 956 | static int of_spi_register_master(struct spi_master *master) | ||
| 957 | { | ||
| 958 | u16 nb; | ||
| 959 | int i, *cs; | ||
| 960 | struct device_node *np = master->dev.of_node; | ||
| 961 | |||
| 962 | if (!np) | ||
| 963 | return 0; | ||
| 964 | |||
| 965 | nb = of_gpio_named_count(np, "cs-gpios"); | ||
| 966 | master->num_chipselect = max(nb, master->num_chipselect); | ||
| 967 | |||
| 968 | if (nb < 1) | ||
| 969 | return 0; | ||
| 970 | |||
| 971 | cs = devm_kzalloc(&master->dev, | ||
| 972 | sizeof(int) * master->num_chipselect, | ||
| 973 | GFP_KERNEL); | ||
| 974 | master->cs_gpios = cs; | ||
| 975 | |||
| 976 | if (!master->cs_gpios) | ||
| 977 | return -ENOMEM; | ||
| 978 | |||
| 979 | memset(cs, -EINVAL, master->num_chipselect); | ||
| 980 | |||
| 981 | for (i = 0; i < nb; i++) | ||
| 982 | cs[i] = of_get_named_gpio(np, "cs-gpios", i); | ||
| 983 | |||
| 984 | return 0; | ||
| 985 | } | ||
| 986 | #else | ||
| 987 | static int of_spi_register_master(struct spi_master *master) | ||
| 988 | { | ||
| 989 | return 0; | ||
| 990 | } | ||
| 991 | #endif | ||
| 992 | |||
| 949 | /** | 993 | /** |
| 950 | * spi_register_master - register SPI master controller | 994 | * spi_register_master - register SPI master controller |
| 951 | * @master: initialized master, originally from spi_alloc_master() | 995 | * @master: initialized master, originally from spi_alloc_master() |
| @@ -977,6 +1021,10 @@ int spi_register_master(struct spi_master *master) | |||
| 977 | if (!dev) | 1021 | if (!dev) |
| 978 | return -ENODEV; | 1022 | return -ENODEV; |
| 979 | 1023 | ||
| 1024 | status = of_spi_register_master(master); | ||
| 1025 | if (status) | ||
| 1026 | return status; | ||
| 1027 | |||
| 980 | /* even if it's just one always-selected device, there must | 1028 | /* even if it's just one always-selected device, there must |
| 981 | * be at least one chipselect | 1029 | * be at least one chipselect |
| 982 | */ | 1030 | */ |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index fa702aeb5038..f62918946d86 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -90,6 +90,7 @@ struct spi_device { | |||
| 90 | void *controller_state; | 90 | void *controller_state; |
| 91 | void *controller_data; | 91 | void *controller_data; |
| 92 | char modalias[SPI_NAME_SIZE]; | 92 | char modalias[SPI_NAME_SIZE]; |
| 93 | int cs_gpio; /* chip select gpio */ | ||
| 93 | 94 | ||
| 94 | /* | 95 | /* |
| 95 | * likely need more hooks for more protocol options affecting how | 96 | * likely need more hooks for more protocol options affecting how |
| @@ -362,6 +363,8 @@ struct spi_master { | |||
| 362 | int (*transfer_one_message)(struct spi_master *master, | 363 | int (*transfer_one_message)(struct spi_master *master, |
| 363 | struct spi_message *mesg); | 364 | struct spi_message *mesg); |
| 364 | int (*unprepare_transfer_hardware)(struct spi_master *master); | 365 | int (*unprepare_transfer_hardware)(struct spi_master *master); |
| 366 | /* gpio chip select */ | ||
| 367 | int *cs_gpios; | ||
| 365 | }; | 368 | }; |
| 366 | 369 | ||
| 367 | static inline void *spi_master_get_devdata(struct spi_master *master) | 370 | static inline void *spi_master_get_devdata(struct spi_master *master) |
