aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2012-09-05 05:04:36 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-05 19:41:09 -0400
commit38ab18caa0ad9c844ba60f9618c5de6d6954da3e (patch)
treec4be63a707abc38de33cac71ea7c6bf674c2b26f
parent161c2dd3ca143f0dca50d72292bf651eabe2aa23 (diff)
spi: spi-gpio: Add DT bindings
This patch adds DT bindings to the spi-gpio driver and some documentation about how to use it. Signed-off-by: Daniel Mack <zonque@gmail.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--Documentation/devicetree/bindings/spi/spi-gpio.txt29
-rw-r--r--drivers/spi/spi-gpio.c99
2 files changed, 125 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-gpio.txt b/Documentation/devicetree/bindings/spi/spi-gpio.txt
new file mode 100644
index 000000000000..8a824be15754
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-gpio.txt
@@ -0,0 +1,29 @@
1SPI-GPIO devicetree bindings
2
3Required properties:
4
5 - compatible: should be set to "spi-gpio"
6 - #address-cells: should be set to <0x1>
7 - ranges
8 - gpio-sck: GPIO spec for the SCK line to use
9 - gpio-miso: GPIO spec for the MISO line to use
10 - gpio-mosi: GPIO spec for the MOSI line to use
11 - cs-gpios: GPIOs to use for chipselect lines
12 - num-chipselects: number of chipselect lines
13
14Example:
15
16 spi {
17 compatible = "spi-gpio";
18 #address-cells = <0x1>;
19 ranges;
20
21 gpio-sck = <&gpio 95 0>;
22 gpio-miso = <&gpio 98 0>;
23 gpio-mosi = <&gpio 97 0>;
24 cs-gpios = <&gpio 125 0>;
25 num-chipselects = <1>;
26
27 /* clients */
28 };
29
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
index ff7263ce12c7..aed161595840 100644
--- a/drivers/spi/spi-gpio.c
+++ b/drivers/spi/spi-gpio.c
@@ -22,6 +22,8 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/of_device.h>
26#include <linux/of_gpio.h>
25 27
26#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
27#include <linux/spi/spi_bitbang.h> 29#include <linux/spi/spi_bitbang.h>
@@ -232,13 +234,27 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
232 234
233static int spi_gpio_setup(struct spi_device *spi) 235static int spi_gpio_setup(struct spi_device *spi)
234{ 236{
235 unsigned int cs = (unsigned int) spi->controller_data; 237 unsigned int cs;
236 int status = 0; 238 int status = 0;
237 struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 239 struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
240 struct device_node *np = spi->master->dev.of_node;
238 241
239 if (spi->bits_per_word > 32) 242 if (spi->bits_per_word > 32)
240 return -EINVAL; 243 return -EINVAL;
241 244
245 if (np) {
246 /*
247 * In DT environments, the CS GPIOs have already been
248 * initialized from the "cs-gpios" property of the node.
249 */
250 cs = spi_gpio->cs_gpios[spi->chip_select];
251 } else {
252 /*
253 * ... otherwise, take it from spi->controller_data
254 */
255 cs = (unsigned int) spi->controller_data;
256 }
257
242 if (!spi->controller_state) { 258 if (!spi->controller_state) {
243 if (cs != SPI_GPIO_NO_CHIPSELECT) { 259 if (cs != SPI_GPIO_NO_CHIPSELECT) {
244 status = gpio_request(cs, dev_name(&spi->dev)); 260 status = gpio_request(cs, dev_name(&spi->dev));
@@ -250,6 +266,7 @@ static int spi_gpio_setup(struct spi_device *spi)
250 } 266 }
251 if (!status) { 267 if (!status) {
252 status = spi_bitbang_setup(spi); 268 status = spi_bitbang_setup(spi);
269 /* in case it was initialized from static board data */
253 spi_gpio->cs_gpios[spi->chip_select] = cs; 270 spi_gpio->cs_gpios[spi->chip_select] = cs;
254 } 271 }
255 272
@@ -326,6 +343,55 @@ done:
326 return value; 343 return value;
327} 344}
328 345
346#ifdef CONFIG_OF
347static struct of_device_id spi_gpio_dt_ids[] = {
348 { .compatible = "spi-gpio" },
349 {}
350};
351MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids);
352
353static int spi_gpio_probe_dt(struct platform_device *pdev)
354{
355 int ret;
356 u32 tmp;
357 struct spi_gpio_platform_data *pdata;
358 struct device_node *np = pdev->dev.of_node;
359 const struct of_device_id *of_id =
360 of_match_device(spi_gpio_dt_ids, &pdev->dev);
361
362 if (!of_id)
363 return 0;
364
365 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
366 if (!pdata)
367 return -ENOMEM;
368
369 pdata->sck = of_get_named_gpio(np, "gpio-sck", 0);
370 pdata->miso = of_get_named_gpio(np, "gpio-miso", 0);
371 pdata->mosi = of_get_named_gpio(np, "gpio-mosi", 0);
372
373 ret = of_property_read_u32(np, "num-chipselects", &tmp);
374 if (ret < 0) {
375 dev_err(&pdev->dev, "num-chipselects property not found\n");
376 goto error_free;
377 }
378
379 pdata->num_chipselect = tmp;
380 pdev->dev.platform_data = pdata;
381
382 return 1;
383
384error_free:
385 devm_kfree(&pdev->dev, pdata);
386 return ret;
387}
388#else
389static inline int spi_probe_dt(struct platform_device *)
390{
391 return 0;
392}
393#endif
394
329static int __devinit spi_gpio_probe(struct platform_device *pdev) 395static int __devinit spi_gpio_probe(struct platform_device *pdev)
330{ 396{
331 int status; 397 int status;
@@ -333,6 +399,13 @@ static int __devinit spi_gpio_probe(struct platform_device *pdev)
333 struct spi_gpio *spi_gpio; 399 struct spi_gpio *spi_gpio;
334 struct spi_gpio_platform_data *pdata; 400 struct spi_gpio_platform_data *pdata;
335 u16 master_flags = 0; 401 u16 master_flags = 0;
402 bool use_of = 0;
403
404 status = spi_gpio_probe_dt(pdev);
405 if (status < 0)
406 return status;
407 if (status > 0)
408 use_of = 1;
336 409
337 pdata = pdev->dev.platform_data; 410 pdata = pdev->dev.platform_data;
338#ifdef GENERIC_BITBANG 411#ifdef GENERIC_BITBANG
@@ -362,6 +435,23 @@ static int __devinit spi_gpio_probe(struct platform_device *pdev)
362 master->num_chipselect = SPI_N_CHIPSEL; 435 master->num_chipselect = SPI_N_CHIPSEL;
363 master->setup = spi_gpio_setup; 436 master->setup = spi_gpio_setup;
364 master->cleanup = spi_gpio_cleanup; 437 master->cleanup = spi_gpio_cleanup;
438#ifdef CONFIG_OF
439 master->dev.of_node = pdev->dev.of_node;
440
441 if (use_of) {
442 int i;
443 struct device_node *np = pdev->dev.of_node;
444
445 /*
446 * In DT environments, take the CS GPIO from the "cs-gpios"
447 * property of the node.
448 */
449
450 for (i = 0; i < SPI_N_CHIPSEL; i++)
451 spi_gpio->cs_gpios[i] =
452 of_get_named_gpio(np, "cs-gpios", i);
453 }
454#endif
365 455
366 spi_gpio->bitbang.master = spi_master_get(master); 456 spi_gpio->bitbang.master = spi_master_get(master);
367 spi_gpio->bitbang.chipselect = spi_gpio_chipselect; 457 spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
@@ -422,8 +512,11 @@ static int __devexit spi_gpio_remove(struct platform_device *pdev)
422MODULE_ALIAS("platform:" DRIVER_NAME); 512MODULE_ALIAS("platform:" DRIVER_NAME);
423 513
424static struct platform_driver spi_gpio_driver = { 514static struct platform_driver spi_gpio_driver = {
425 .driver.name = DRIVER_NAME, 515 .driver = {
426 .driver.owner = THIS_MODULE, 516 .name = DRIVER_NAME,
517 .owner = THIS_MODULE,
518 .of_match_table = of_match_ptr(spi_gpio_dt_ids),
519 },
427 .probe = spi_gpio_probe, 520 .probe = spi_gpio_probe,
428 .remove = __devexit_p(spi_gpio_remove), 521 .remove = __devexit_p(spi_gpio_remove),
429}; 522};