Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Daniel Mack and committed by
Mark Brown
38ab18ca 161c2dd3

+125 -3
+29
Documentation/devicetree/bindings/spi/spi-gpio.txt
··· 1 + SPI-GPIO devicetree bindings 2 + 3 + Required 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 + 14 + Example: 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 +
+96 -3
drivers/spi/spi-gpio.c
··· 22 22 #include <linux/init.h> 23 23 #include <linux/platform_device.h> 24 24 #include <linux/gpio.h> 25 + #include <linux/of_device.h> 26 + #include <linux/of_gpio.h> 25 27 26 28 #include <linux/spi/spi.h> 27 29 #include <linux/spi/spi_bitbang.h> ··· 234 232 235 233 static int spi_gpio_setup(struct spi_device *spi) 236 234 { 237 - unsigned int cs = (unsigned int) spi->controller_data; 235 + unsigned int cs; 238 236 int status = 0; 239 237 struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 238 + struct device_node *np = spi->master->dev.of_node; 240 239 241 240 if (spi->bits_per_word > 32) 242 241 return -EINVAL; 242 + 243 + if (np) { 244 + /* 245 + * In DT environments, the CS GPIOs have already been 246 + * initialized from the "cs-gpios" property of the node. 247 + */ 248 + cs = spi_gpio->cs_gpios[spi->chip_select]; 249 + } else { 250 + /* 251 + * ... otherwise, take it from spi->controller_data 252 + */ 253 + cs = (unsigned int) spi->controller_data; 254 + } 243 255 244 256 if (!spi->controller_state) { 245 257 if (cs != SPI_GPIO_NO_CHIPSELECT) { ··· 266 250 } 267 251 if (!status) { 268 252 status = spi_bitbang_setup(spi); 253 + /* in case it was initialized from static board data */ 269 254 spi_gpio->cs_gpios[spi->chip_select] = cs; 270 255 } 271 256 ··· 343 326 return value; 344 327 } 345 328 329 + #ifdef CONFIG_OF 330 + static struct of_device_id spi_gpio_dt_ids[] = { 331 + { .compatible = "spi-gpio" }, 332 + {} 333 + }; 334 + MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids); 335 + 336 + static int spi_gpio_probe_dt(struct platform_device *pdev) 337 + { 338 + int ret; 339 + u32 tmp; 340 + struct spi_gpio_platform_data *pdata; 341 + struct device_node *np = pdev->dev.of_node; 342 + const struct of_device_id *of_id = 343 + of_match_device(spi_gpio_dt_ids, &pdev->dev); 344 + 345 + if (!of_id) 346 + return 0; 347 + 348 + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 349 + if (!pdata) 350 + return -ENOMEM; 351 + 352 + pdata->sck = of_get_named_gpio(np, "gpio-sck", 0); 353 + pdata->miso = of_get_named_gpio(np, "gpio-miso", 0); 354 + pdata->mosi = of_get_named_gpio(np, "gpio-mosi", 0); 355 + 356 + ret = of_property_read_u32(np, "num-chipselects", &tmp); 357 + if (ret < 0) { 358 + dev_err(&pdev->dev, "num-chipselects property not found\n"); 359 + goto error_free; 360 + } 361 + 362 + pdata->num_chipselect = tmp; 363 + pdev->dev.platform_data = pdata; 364 + 365 + return 1; 366 + 367 + error_free: 368 + devm_kfree(&pdev->dev, pdata); 369 + return ret; 370 + } 371 + #else 372 + static inline int spi_probe_dt(struct platform_device *) 373 + { 374 + return 0; 375 + } 376 + #endif 377 + 346 378 static int __devinit spi_gpio_probe(struct platform_device *pdev) 347 379 { 348 380 int status; ··· 399 333 struct spi_gpio *spi_gpio; 400 334 struct spi_gpio_platform_data *pdata; 401 335 u16 master_flags = 0; 336 + bool use_of = 0; 337 + 338 + status = spi_gpio_probe_dt(pdev); 339 + if (status < 0) 340 + return status; 341 + if (status > 0) 342 + use_of = 1; 402 343 403 344 pdata = pdev->dev.platform_data; 404 345 #ifdef GENERIC_BITBANG ··· 435 362 master->num_chipselect = SPI_N_CHIPSEL; 436 363 master->setup = spi_gpio_setup; 437 364 master->cleanup = spi_gpio_cleanup; 365 + #ifdef CONFIG_OF 366 + master->dev.of_node = pdev->dev.of_node; 367 + 368 + if (use_of) { 369 + int i; 370 + struct device_node *np = pdev->dev.of_node; 371 + 372 + /* 373 + * In DT environments, take the CS GPIO from the "cs-gpios" 374 + * property of the node. 375 + */ 376 + 377 + for (i = 0; i < SPI_N_CHIPSEL; i++) 378 + spi_gpio->cs_gpios[i] = 379 + of_get_named_gpio(np, "cs-gpios", i); 380 + } 381 + #endif 438 382 439 383 spi_gpio->bitbang.master = spi_master_get(master); 440 384 spi_gpio->bitbang.chipselect = spi_gpio_chipselect; ··· 512 422 MODULE_ALIAS("platform:" DRIVER_NAME); 513 423 514 424 static struct platform_driver spi_gpio_driver = { 515 - .driver.name = DRIVER_NAME, 516 - .driver.owner = THIS_MODULE, 425 + .driver = { 426 + .name = DRIVER_NAME, 427 + .owner = THIS_MODULE, 428 + .of_match_table = of_match_ptr(spi_gpio_dt_ids), 429 + }, 517 430 .probe = spi_gpio_probe, 518 431 .remove = __devexit_p(spi_gpio_remove), 519 432 };