[Xenomai-git] Philippe Gerum : drivers/spi: enable GPIO-based chip select
Module: xenomai-3 Branch: master Commit: 0f85395e3228ea30523d21a50ee9a0e5d0dfe82c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=0f85395e3228ea30523d21a50ee9a0e5d0dfe82c Author: Philippe GerumDate: Tue Jun 28 09:58:10 2016 +0200 drivers/spi: enable GPIO-based chip select --- kernel/drivers/spi/spi-device.c | 38 +- kernel/drivers/spi/spi-device.h |1 + kernel/drivers/spi/spi-master.c | 18 -- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/spi/spi-device.c b/kernel/drivers/spi/spi-device.c index 62482b2..08cf9b0 100644 --- a/kernel/drivers/spi/spi-device.c +++ b/kernel/drivers/spi/spi-device.c @@ -43,22 +43,14 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->config.speed_hz = spi->max_speed_hz; slave->config.mode = spi->mode; slave->master = master; - mutex_init(>ctl_lock); dev = >dev; dev->driver = >driver; dev->label = kasprintf(GFP_KERNEL, "%s/slave%d.%%d", dev_name(>dev), kmaster->bus_num); - if (dev->label == NULL) { - ret = -ENOMEM; - goto fail_label; - } - - dev->device_data = master; - ret = rtdm_dev_register(dev); - if (ret) - goto fail_register; + if (dev->label == NULL) + return -ENOMEM; if (gpio_is_valid(spi->cs_gpio)) slave->cs_gpio = spi->cs_gpio; @@ -68,21 +60,30 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->cs_gpio = kmaster->cs_gpios[spi->chip_select]; } - if (gpio_is_valid(slave->cs_gpio)) - dev_dbg(slave_to_kdev(slave), "using CS GPIO%d\n", - slave->cs_gpio); + if (gpio_is_valid(slave->cs_gpio)) { + ret = gpio_request(slave->cs_gpio, dev->label); + if (ret) + goto fail; + slave->cs_gpiod = gpio_to_desc(slave->cs_gpio); + if (slave->cs_gpiod == NULL) + goto fail; + } + + mutex_init(>ctl_lock); + + dev->device_data = master; + ret = rtdm_dev_register(dev); + if (ret) + goto fail; rtdm_lock_get_irqsave(>lock, c); list_add_tail(>next, >slaves); rtdm_lock_put_irqrestore(>lock, c); return 0; - -fail_register: +fail: kfree(dev->label); -fail_label: - return ret; } EXPORT_SYMBOL_GPL(rtdm_spi_add_remote_slave); @@ -93,6 +94,9 @@ void rtdm_spi_remove_remote_slave(struct rtdm_spi_remote_slave *slave) struct rtdm_device *dev; rtdm_lockctx_t c; + if (gpio_is_valid(slave->cs_gpio)) + gpio_free(slave->cs_gpio); + mutex_destroy(>ctl_lock); rtdm_lock_get_irqsave(>lock, c); list_del(>next); diff --git a/kernel/drivers/spi/spi-device.h b/kernel/drivers/spi/spi-device.h index fcfca90..ee43c38 100644 --- a/kernel/drivers/spi/spi-device.h +++ b/kernel/drivers/spi/spi-device.h @@ -30,6 +30,7 @@ struct rtdm_spi_master; struct rtdm_spi_remote_slave { u8 chip_select; int cs_gpio; + struct gpio_desc *cs_gpiod; struct rtdm_device dev; struct list_head next; struct rtdm_spi_config config; diff --git a/kernel/drivers/spi/spi-master.c b/kernel/drivers/spi/spi-master.c index 132a3b9..fe2ee40 100644 --- a/kernel/drivers/spi/spi-master.c +++ b/kernel/drivers/spi/spi-master.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "spi-master.h" static inline @@ -105,6 +106,7 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; if (slave->config.speed_hz == 0) return -EINVAL; /* Setup is missing. */ @@ -113,7 +115,11 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) rtdm_lock_get_irqsave(>lock, c); if (master->cs != slave) { - master->ops->chip_select(slave, true); + if (gpio_is_valid(slave->cs_gpio)) { + state = !!(slave->config.mode & SPI_CS_HIGH); + gpiod_set_raw_value(slave->cs_gpiod, state); + } else + master->ops->chip_select(slave, true); master->cs = slave; } @@ -126,10 +132,18 @@ static void do_chip_deselect(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; rtdm_lock_get_irqsave(>lock, c); - master->ops->chip_select(slave, false); + +
[Xenomai-git] Philippe Gerum : drivers/spi: enable GPIO-based chip select
Module: xenomai-3 Branch: stable-3.0.x Commit: 0f85395e3228ea30523d21a50ee9a0e5d0dfe82c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=0f85395e3228ea30523d21a50ee9a0e5d0dfe82c Author: Philippe GerumDate: Tue Jun 28 09:58:10 2016 +0200 drivers/spi: enable GPIO-based chip select --- kernel/drivers/spi/spi-device.c | 38 +- kernel/drivers/spi/spi-device.h |1 + kernel/drivers/spi/spi-master.c | 18 -- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/spi/spi-device.c b/kernel/drivers/spi/spi-device.c index 62482b2..08cf9b0 100644 --- a/kernel/drivers/spi/spi-device.c +++ b/kernel/drivers/spi/spi-device.c @@ -43,22 +43,14 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->config.speed_hz = spi->max_speed_hz; slave->config.mode = spi->mode; slave->master = master; - mutex_init(>ctl_lock); dev = >dev; dev->driver = >driver; dev->label = kasprintf(GFP_KERNEL, "%s/slave%d.%%d", dev_name(>dev), kmaster->bus_num); - if (dev->label == NULL) { - ret = -ENOMEM; - goto fail_label; - } - - dev->device_data = master; - ret = rtdm_dev_register(dev); - if (ret) - goto fail_register; + if (dev->label == NULL) + return -ENOMEM; if (gpio_is_valid(spi->cs_gpio)) slave->cs_gpio = spi->cs_gpio; @@ -68,21 +60,30 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->cs_gpio = kmaster->cs_gpios[spi->chip_select]; } - if (gpio_is_valid(slave->cs_gpio)) - dev_dbg(slave_to_kdev(slave), "using CS GPIO%d\n", - slave->cs_gpio); + if (gpio_is_valid(slave->cs_gpio)) { + ret = gpio_request(slave->cs_gpio, dev->label); + if (ret) + goto fail; + slave->cs_gpiod = gpio_to_desc(slave->cs_gpio); + if (slave->cs_gpiod == NULL) + goto fail; + } + + mutex_init(>ctl_lock); + + dev->device_data = master; + ret = rtdm_dev_register(dev); + if (ret) + goto fail; rtdm_lock_get_irqsave(>lock, c); list_add_tail(>next, >slaves); rtdm_lock_put_irqrestore(>lock, c); return 0; - -fail_register: +fail: kfree(dev->label); -fail_label: - return ret; } EXPORT_SYMBOL_GPL(rtdm_spi_add_remote_slave); @@ -93,6 +94,9 @@ void rtdm_spi_remove_remote_slave(struct rtdm_spi_remote_slave *slave) struct rtdm_device *dev; rtdm_lockctx_t c; + if (gpio_is_valid(slave->cs_gpio)) + gpio_free(slave->cs_gpio); + mutex_destroy(>ctl_lock); rtdm_lock_get_irqsave(>lock, c); list_del(>next); diff --git a/kernel/drivers/spi/spi-device.h b/kernel/drivers/spi/spi-device.h index fcfca90..ee43c38 100644 --- a/kernel/drivers/spi/spi-device.h +++ b/kernel/drivers/spi/spi-device.h @@ -30,6 +30,7 @@ struct rtdm_spi_master; struct rtdm_spi_remote_slave { u8 chip_select; int cs_gpio; + struct gpio_desc *cs_gpiod; struct rtdm_device dev; struct list_head next; struct rtdm_spi_config config; diff --git a/kernel/drivers/spi/spi-master.c b/kernel/drivers/spi/spi-master.c index 132a3b9..fe2ee40 100644 --- a/kernel/drivers/spi/spi-master.c +++ b/kernel/drivers/spi/spi-master.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "spi-master.h" static inline @@ -105,6 +106,7 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; if (slave->config.speed_hz == 0) return -EINVAL; /* Setup is missing. */ @@ -113,7 +115,11 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) rtdm_lock_get_irqsave(>lock, c); if (master->cs != slave) { - master->ops->chip_select(slave, true); + if (gpio_is_valid(slave->cs_gpio)) { + state = !!(slave->config.mode & SPI_CS_HIGH); + gpiod_set_raw_value(slave->cs_gpiod, state); + } else + master->ops->chip_select(slave, true); master->cs = slave; } @@ -126,10 +132,18 @@ static void do_chip_deselect(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; rtdm_lock_get_irqsave(>lock, c); - master->ops->chip_select(slave, false);
[Xenomai-git] Philippe Gerum : drivers/spi: enable GPIO-based chip select
Module: xenomai-3 Branch: wip/drivers Commit: 0f85395e3228ea30523d21a50ee9a0e5d0dfe82c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=0f85395e3228ea30523d21a50ee9a0e5d0dfe82c Author: Philippe GerumDate: Tue Jun 28 09:58:10 2016 +0200 drivers/spi: enable GPIO-based chip select --- kernel/drivers/spi/spi-device.c | 38 +- kernel/drivers/spi/spi-device.h |1 + kernel/drivers/spi/spi-master.c | 18 -- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/spi/spi-device.c b/kernel/drivers/spi/spi-device.c index 62482b2..08cf9b0 100644 --- a/kernel/drivers/spi/spi-device.c +++ b/kernel/drivers/spi/spi-device.c @@ -43,22 +43,14 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->config.speed_hz = spi->max_speed_hz; slave->config.mode = spi->mode; slave->master = master; - mutex_init(>ctl_lock); dev = >dev; dev->driver = >driver; dev->label = kasprintf(GFP_KERNEL, "%s/slave%d.%%d", dev_name(>dev), kmaster->bus_num); - if (dev->label == NULL) { - ret = -ENOMEM; - goto fail_label; - } - - dev->device_data = master; - ret = rtdm_dev_register(dev); - if (ret) - goto fail_register; + if (dev->label == NULL) + return -ENOMEM; if (gpio_is_valid(spi->cs_gpio)) slave->cs_gpio = spi->cs_gpio; @@ -68,21 +60,30 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->cs_gpio = kmaster->cs_gpios[spi->chip_select]; } - if (gpio_is_valid(slave->cs_gpio)) - dev_dbg(slave_to_kdev(slave), "using CS GPIO%d\n", - slave->cs_gpio); + if (gpio_is_valid(slave->cs_gpio)) { + ret = gpio_request(slave->cs_gpio, dev->label); + if (ret) + goto fail; + slave->cs_gpiod = gpio_to_desc(slave->cs_gpio); + if (slave->cs_gpiod == NULL) + goto fail; + } + + mutex_init(>ctl_lock); + + dev->device_data = master; + ret = rtdm_dev_register(dev); + if (ret) + goto fail; rtdm_lock_get_irqsave(>lock, c); list_add_tail(>next, >slaves); rtdm_lock_put_irqrestore(>lock, c); return 0; - -fail_register: +fail: kfree(dev->label); -fail_label: - return ret; } EXPORT_SYMBOL_GPL(rtdm_spi_add_remote_slave); @@ -93,6 +94,9 @@ void rtdm_spi_remove_remote_slave(struct rtdm_spi_remote_slave *slave) struct rtdm_device *dev; rtdm_lockctx_t c; + if (gpio_is_valid(slave->cs_gpio)) + gpio_free(slave->cs_gpio); + mutex_destroy(>ctl_lock); rtdm_lock_get_irqsave(>lock, c); list_del(>next); diff --git a/kernel/drivers/spi/spi-device.h b/kernel/drivers/spi/spi-device.h index fcfca90..ee43c38 100644 --- a/kernel/drivers/spi/spi-device.h +++ b/kernel/drivers/spi/spi-device.h @@ -30,6 +30,7 @@ struct rtdm_spi_master; struct rtdm_spi_remote_slave { u8 chip_select; int cs_gpio; + struct gpio_desc *cs_gpiod; struct rtdm_device dev; struct list_head next; struct rtdm_spi_config config; diff --git a/kernel/drivers/spi/spi-master.c b/kernel/drivers/spi/spi-master.c index 132a3b9..fe2ee40 100644 --- a/kernel/drivers/spi/spi-master.c +++ b/kernel/drivers/spi/spi-master.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "spi-master.h" static inline @@ -105,6 +106,7 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; if (slave->config.speed_hz == 0) return -EINVAL; /* Setup is missing. */ @@ -113,7 +115,11 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) rtdm_lock_get_irqsave(>lock, c); if (master->cs != slave) { - master->ops->chip_select(slave, true); + if (gpio_is_valid(slave->cs_gpio)) { + state = !!(slave->config.mode & SPI_CS_HIGH); + gpiod_set_raw_value(slave->cs_gpiod, state); + } else + master->ops->chip_select(slave, true); master->cs = slave; } @@ -126,10 +132,18 @@ static void do_chip_deselect(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; rtdm_lock_get_irqsave(>lock, c); - master->ops->chip_select(slave, false);
[Xenomai-git] Philippe Gerum : drivers/spi: enable GPIO-based chip select
Module: xenomai-3 Branch: wip/drivers Commit: f2d77932c737e31a3c2abce81ba00436a60ed1f6 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=f2d77932c737e31a3c2abce81ba00436a60ed1f6 Author: Philippe GerumDate: Tue Jun 28 09:58:10 2016 +0200 drivers/spi: enable GPIO-based chip select --- kernel/drivers/spi/spi-device.c | 38 +- kernel/drivers/spi/spi-device.h |1 + kernel/drivers/spi/spi-master.c | 18 -- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/spi/spi-device.c b/kernel/drivers/spi/spi-device.c index 62482b2..08cf9b0 100644 --- a/kernel/drivers/spi/spi-device.c +++ b/kernel/drivers/spi/spi-device.c @@ -43,22 +43,14 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->config.speed_hz = spi->max_speed_hz; slave->config.mode = spi->mode; slave->master = master; - mutex_init(>ctl_lock); dev = >dev; dev->driver = >driver; dev->label = kasprintf(GFP_KERNEL, "%s/slave%d.%%d", dev_name(>dev), kmaster->bus_num); - if (dev->label == NULL) { - ret = -ENOMEM; - goto fail_label; - } - - dev->device_data = master; - ret = rtdm_dev_register(dev); - if (ret) - goto fail_register; + if (dev->label == NULL) + return -ENOMEM; if (gpio_is_valid(spi->cs_gpio)) slave->cs_gpio = spi->cs_gpio; @@ -68,21 +60,30 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->cs_gpio = kmaster->cs_gpios[spi->chip_select]; } - if (gpio_is_valid(slave->cs_gpio)) - dev_dbg(slave_to_kdev(slave), "using CS GPIO%d\n", - slave->cs_gpio); + if (gpio_is_valid(slave->cs_gpio)) { + ret = gpio_request(slave->cs_gpio, dev->label); + if (ret) + goto fail; + slave->cs_gpiod = gpio_to_desc(slave->cs_gpio); + if (slave->cs_gpiod == NULL) + goto fail; + } + + mutex_init(>ctl_lock); + + dev->device_data = master; + ret = rtdm_dev_register(dev); + if (ret) + goto fail; rtdm_lock_get_irqsave(>lock, c); list_add_tail(>next, >slaves); rtdm_lock_put_irqrestore(>lock, c); return 0; - -fail_register: +fail: kfree(dev->label); -fail_label: - return ret; } EXPORT_SYMBOL_GPL(rtdm_spi_add_remote_slave); @@ -93,6 +94,9 @@ void rtdm_spi_remove_remote_slave(struct rtdm_spi_remote_slave *slave) struct rtdm_device *dev; rtdm_lockctx_t c; + if (gpio_is_valid(slave->cs_gpio)) + gpio_free(slave->cs_gpio); + mutex_destroy(>ctl_lock); rtdm_lock_get_irqsave(>lock, c); list_del(>next); diff --git a/kernel/drivers/spi/spi-device.h b/kernel/drivers/spi/spi-device.h index fcfca90..ee43c38 100644 --- a/kernel/drivers/spi/spi-device.h +++ b/kernel/drivers/spi/spi-device.h @@ -30,6 +30,7 @@ struct rtdm_spi_master; struct rtdm_spi_remote_slave { u8 chip_select; int cs_gpio; + struct gpio_desc *cs_gpiod; struct rtdm_device dev; struct list_head next; struct rtdm_spi_config config; diff --git a/kernel/drivers/spi/spi-master.c b/kernel/drivers/spi/spi-master.c index 132a3b9..fe2ee40 100644 --- a/kernel/drivers/spi/spi-master.c +++ b/kernel/drivers/spi/spi-master.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "spi-master.h" static inline @@ -105,6 +106,7 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; if (slave->config.speed_hz == 0) return -EINVAL; /* Setup is missing. */ @@ -113,7 +115,11 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) rtdm_lock_get_irqsave(>lock, c); if (master->cs != slave) { - master->ops->chip_select(slave, true); + if (gpio_is_valid(slave->cs_gpio)) { + state = !!(slave->config.mode & SPI_CS_HIGH); + gpiod_set_raw_value(slave->cs_gpiod, state); + } else + master->ops->chip_select(slave, true); master->cs = slave; } @@ -126,10 +132,18 @@ static void do_chip_deselect(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; rtdm_lock_get_irqsave(>lock, c); - master->ops->chip_select(slave, false);
[Xenomai-git] Philippe Gerum : drivers/spi: enable GPIO-based chip select
Module: xenomai-3 Branch: wip/drivers Commit: a220f522106c1c086908445f06992663f6bd5a64 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=a220f522106c1c086908445f06992663f6bd5a64 Author: Philippe GerumDate: Tue Jun 28 09:58:10 2016 +0200 drivers/spi: enable GPIO-based chip select --- kernel/drivers/spi/spi-device.c | 38 +- kernel/drivers/spi/spi-device.h |1 + kernel/drivers/spi/spi-master.c | 18 -- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/spi/spi-device.c b/kernel/drivers/spi/spi-device.c index 62482b2..08cf9b0 100644 --- a/kernel/drivers/spi/spi-device.c +++ b/kernel/drivers/spi/spi-device.c @@ -43,22 +43,14 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->config.speed_hz = spi->max_speed_hz; slave->config.mode = spi->mode; slave->master = master; - mutex_init(>ctl_lock); dev = >dev; dev->driver = >driver; dev->label = kasprintf(GFP_KERNEL, "%s/slave%d.%%d", dev_name(>dev), kmaster->bus_num); - if (dev->label == NULL) { - ret = -ENOMEM; - goto fail_label; - } - - dev->device_data = master; - ret = rtdm_dev_register(dev); - if (ret) - goto fail_register; + if (dev->label == NULL) + return -ENOMEM; if (gpio_is_valid(spi->cs_gpio)) slave->cs_gpio = spi->cs_gpio; @@ -68,21 +60,30 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->cs_gpio = kmaster->cs_gpios[spi->chip_select]; } - if (gpio_is_valid(slave->cs_gpio)) - dev_dbg(slave_to_kdev(slave), "using CS GPIO%d\n", - slave->cs_gpio); + if (gpio_is_valid(slave->cs_gpio)) { + ret = gpio_request(slave->cs_gpio, dev->label); + if (ret) + goto fail; + slave->cs_gpiod = gpio_to_desc(slave->cs_gpio); + if (slave->cs_gpiod == NULL) + goto fail; + } + + mutex_init(>ctl_lock); + + dev->device_data = master; + ret = rtdm_dev_register(dev); + if (ret) + goto fail; rtdm_lock_get_irqsave(>lock, c); list_add_tail(>next, >slaves); rtdm_lock_put_irqrestore(>lock, c); return 0; - -fail_register: +fail: kfree(dev->label); -fail_label: - return ret; } EXPORT_SYMBOL_GPL(rtdm_spi_add_remote_slave); @@ -93,6 +94,9 @@ void rtdm_spi_remove_remote_slave(struct rtdm_spi_remote_slave *slave) struct rtdm_device *dev; rtdm_lockctx_t c; + if (gpio_is_valid(slave->cs_gpio)) + gpio_free(slave->cs_gpio); + mutex_destroy(>ctl_lock); rtdm_lock_get_irqsave(>lock, c); list_del(>next); diff --git a/kernel/drivers/spi/spi-device.h b/kernel/drivers/spi/spi-device.h index fcfca90..ee43c38 100644 --- a/kernel/drivers/spi/spi-device.h +++ b/kernel/drivers/spi/spi-device.h @@ -30,6 +30,7 @@ struct rtdm_spi_master; struct rtdm_spi_remote_slave { u8 chip_select; int cs_gpio; + struct gpio_desc *cs_gpiod; struct rtdm_device dev; struct list_head next; struct rtdm_spi_config config; diff --git a/kernel/drivers/spi/spi-master.c b/kernel/drivers/spi/spi-master.c index 132a3b9..fe2ee40 100644 --- a/kernel/drivers/spi/spi-master.c +++ b/kernel/drivers/spi/spi-master.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "spi-master.h" static inline @@ -105,6 +106,7 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; if (slave->config.speed_hz == 0) return -EINVAL; /* Setup is missing. */ @@ -113,7 +115,11 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) rtdm_lock_get_irqsave(>lock, c); if (master->cs != slave) { - master->ops->chip_select(slave, true); + if (gpio_is_valid(slave->cs_gpio)) { + state = !!(slave->config.mode & SPI_CS_HIGH); + gpiod_set_raw_value(slave->cs_gpiod, state); + } else + master->ops->chip_select(slave, true); master->cs = slave; } @@ -126,10 +132,18 @@ static void do_chip_deselect(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; rtdm_lock_get_irqsave(>lock, c); - master->ops->chip_select(slave, false);
[Xenomai-git] Philippe Gerum : drivers/spi: enable GPIO-based chip select
Module: xenomai-3 Branch: wip/drivers Commit: 19b67f374050aa430a028078fe94633e57a8ff98 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=19b67f374050aa430a028078fe94633e57a8ff98 Author: Philippe GerumDate: Tue Jun 28 09:58:10 2016 +0200 drivers/spi: enable GPIO-based chip select --- kernel/drivers/spi/spi-device.c | 38 +- kernel/drivers/spi/spi-device.h |1 + kernel/drivers/spi/spi-master.c | 18 -- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/spi/spi-device.c b/kernel/drivers/spi/spi-device.c index 62482b2..08cf9b0 100644 --- a/kernel/drivers/spi/spi-device.c +++ b/kernel/drivers/spi/spi-device.c @@ -43,22 +43,14 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->config.speed_hz = spi->max_speed_hz; slave->config.mode = spi->mode; slave->master = master; - mutex_init(>ctl_lock); dev = >dev; dev->driver = >driver; dev->label = kasprintf(GFP_KERNEL, "%s/slave%d.%%d", dev_name(>dev), kmaster->bus_num); - if (dev->label == NULL) { - ret = -ENOMEM; - goto fail_label; - } - - dev->device_data = master; - ret = rtdm_dev_register(dev); - if (ret) - goto fail_register; + if (dev->label == NULL) + return -ENOMEM; if (gpio_is_valid(spi->cs_gpio)) slave->cs_gpio = spi->cs_gpio; @@ -68,21 +60,30 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->cs_gpio = kmaster->cs_gpios[spi->chip_select]; } - if (gpio_is_valid(slave->cs_gpio)) - dev_dbg(slave_to_kdev(slave), "using CS GPIO%d\n", - slave->cs_gpio); + if (gpio_is_valid(slave->cs_gpio)) { + ret = gpio_request(slave->cs_gpio, dev->label); + if (ret) + goto fail; + slave->cs_gpiod = gpio_to_desc(slave->cs_gpio); + if (slave->cs_gpiod == NULL) + goto fail; + } + + mutex_init(>ctl_lock); + + dev->device_data = master; + ret = rtdm_dev_register(dev); + if (ret) + goto fail; rtdm_lock_get_irqsave(>lock, c); list_add_tail(>next, >slaves); rtdm_lock_put_irqrestore(>lock, c); return 0; - -fail_register: +fail: kfree(dev->label); -fail_label: - return ret; } EXPORT_SYMBOL_GPL(rtdm_spi_add_remote_slave); @@ -93,6 +94,9 @@ void rtdm_spi_remove_remote_slave(struct rtdm_spi_remote_slave *slave) struct rtdm_device *dev; rtdm_lockctx_t c; + if (gpio_is_valid(slave->cs_gpio)) + gpio_free(slave->cs_gpio); + mutex_destroy(>ctl_lock); rtdm_lock_get_irqsave(>lock, c); list_del(>next); diff --git a/kernel/drivers/spi/spi-device.h b/kernel/drivers/spi/spi-device.h index fcfca90..ee43c38 100644 --- a/kernel/drivers/spi/spi-device.h +++ b/kernel/drivers/spi/spi-device.h @@ -30,6 +30,7 @@ struct rtdm_spi_master; struct rtdm_spi_remote_slave { u8 chip_select; int cs_gpio; + struct gpio_desc *cs_gpiod; struct rtdm_device dev; struct list_head next; struct rtdm_spi_config config; diff --git a/kernel/drivers/spi/spi-master.c b/kernel/drivers/spi/spi-master.c index 132a3b9..fe2ee40 100644 --- a/kernel/drivers/spi/spi-master.c +++ b/kernel/drivers/spi/spi-master.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "spi-master.h" static inline @@ -105,6 +106,7 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; if (slave->config.speed_hz == 0) return -EINVAL; /* Setup is missing. */ @@ -113,7 +115,11 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) rtdm_lock_get_irqsave(>lock, c); if (master->cs != slave) { - master->ops->chip_select(slave, true); + if (gpio_is_valid(slave->cs_gpio)) { + state = !!(slave->config.mode & SPI_CS_HIGH); + gpiod_set_raw_value(slave->cs_gpiod, state); + } else + master->ops->chip_select(slave, true); master->cs = slave; } @@ -126,10 +132,18 @@ static void do_chip_deselect(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; rtdm_lock_get_irqsave(>lock, c); - master->ops->chip_select(slave, false);
[Xenomai-git] Philippe Gerum : drivers/spi: enable GPIO-based chip select
Module: xenomai-3 Branch: wip/drivers Commit: 2e3034e16e8ef107fff1168b23ef3708b15f888e URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=2e3034e16e8ef107fff1168b23ef3708b15f888e Author: Philippe GerumDate: Tue Jun 28 09:58:10 2016 +0200 drivers/spi: enable GPIO-based chip select --- kernel/drivers/spi/spi-device.c | 38 +- kernel/drivers/spi/spi-device.h |1 + kernel/drivers/spi/spi-master.c | 17 +++-- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/spi/spi-device.c b/kernel/drivers/spi/spi-device.c index 62482b2..08cf9b0 100644 --- a/kernel/drivers/spi/spi-device.c +++ b/kernel/drivers/spi/spi-device.c @@ -43,22 +43,14 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->config.speed_hz = spi->max_speed_hz; slave->config.mode = spi->mode; slave->master = master; - mutex_init(>ctl_lock); dev = >dev; dev->driver = >driver; dev->label = kasprintf(GFP_KERNEL, "%s/slave%d.%%d", dev_name(>dev), kmaster->bus_num); - if (dev->label == NULL) { - ret = -ENOMEM; - goto fail_label; - } - - dev->device_data = master; - ret = rtdm_dev_register(dev); - if (ret) - goto fail_register; + if (dev->label == NULL) + return -ENOMEM; if (gpio_is_valid(spi->cs_gpio)) slave->cs_gpio = spi->cs_gpio; @@ -68,21 +60,30 @@ int rtdm_spi_add_remote_slave(struct rtdm_spi_remote_slave *slave, slave->cs_gpio = kmaster->cs_gpios[spi->chip_select]; } - if (gpio_is_valid(slave->cs_gpio)) - dev_dbg(slave_to_kdev(slave), "using CS GPIO%d\n", - slave->cs_gpio); + if (gpio_is_valid(slave->cs_gpio)) { + ret = gpio_request(slave->cs_gpio, dev->label); + if (ret) + goto fail; + slave->cs_gpiod = gpio_to_desc(slave->cs_gpio); + if (slave->cs_gpiod == NULL) + goto fail; + } + + mutex_init(>ctl_lock); + + dev->device_data = master; + ret = rtdm_dev_register(dev); + if (ret) + goto fail; rtdm_lock_get_irqsave(>lock, c); list_add_tail(>next, >slaves); rtdm_lock_put_irqrestore(>lock, c); return 0; - -fail_register: +fail: kfree(dev->label); -fail_label: - return ret; } EXPORT_SYMBOL_GPL(rtdm_spi_add_remote_slave); @@ -93,6 +94,9 @@ void rtdm_spi_remove_remote_slave(struct rtdm_spi_remote_slave *slave) struct rtdm_device *dev; rtdm_lockctx_t c; + if (gpio_is_valid(slave->cs_gpio)) + gpio_free(slave->cs_gpio); + mutex_destroy(>ctl_lock); rtdm_lock_get_irqsave(>lock, c); list_del(>next); diff --git a/kernel/drivers/spi/spi-device.h b/kernel/drivers/spi/spi-device.h index fcfca90..ee43c38 100644 --- a/kernel/drivers/spi/spi-device.h +++ b/kernel/drivers/spi/spi-device.h @@ -30,6 +30,7 @@ struct rtdm_spi_master; struct rtdm_spi_remote_slave { u8 chip_select; int cs_gpio; + struct gpio_desc *cs_gpiod; struct rtdm_device dev; struct list_head next; struct rtdm_spi_config config; diff --git a/kernel/drivers/spi/spi-master.c b/kernel/drivers/spi/spi-master.c index 132a3b9..35e0f55 100644 --- a/kernel/drivers/spi/spi-master.c +++ b/kernel/drivers/spi/spi-master.c @@ -105,6 +105,7 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; if (slave->config.speed_hz == 0) return -EINVAL; /* Setup is missing. */ @@ -113,7 +114,11 @@ static int do_chip_select(struct rtdm_spi_remote_slave *slave) rtdm_lock_get_irqsave(>lock, c); if (master->cs != slave) { - master->ops->chip_select(slave, true); + if (gpio_is_valid(slave->cs_gpio)) { + state = !!(slave->config.mode & SPI_CS_HIGH); + gpiod_set_raw_value(slave->cs_gpiod, state); + } else + master->ops->chip_select(slave, true); master->cs = slave; } @@ -126,10 +131,18 @@ static void do_chip_deselect(struct rtdm_spi_remote_slave *slave) { /* master->bus_lock held */ struct rtdm_spi_master *master = slave->master; rtdm_lockctx_t c; + int state; rtdm_lock_get_irqsave(>lock, c); - master->ops->chip_select(slave, false); + + if (gpio_is_valid(slave->cs_gpio)) { + state = !(slave->config.mode &