Signed-off-by: Baruch Siach <[email protected]>
---
drivers/spi/spi-dw.c | 26 +++++++++++++++++++++++---
drivers/spi/spi-dw.h | 6 +++++-
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index bf98d63d92b3..69b8772b3ed8 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
+#include <linux/gpio.h>
#include "spi-dw.h"
@@ -265,6 +266,8 @@ static void giveback(struct dw_spi *dws)
struct spi_transfer *last_transfer;
unsigned long flags;
struct spi_message *msg;
+ int cs_gpio = dws->cur_msg->spi->cs_gpio;
+ u16 mode = dws->cur_msg->spi->mode;
spin_lock_irqsave(&dws->lock, flags);
msg = dws->cur_msg;
@@ -280,8 +283,12 @@ static void giveback(struct dw_spi *dws)
struct spi_transfer,
transfer_list);
- if (!last_transfer->cs_change && dws->cs_control)
- dws->cs_control(MRST_SPI_DEASSERT);
+ if (!last_transfer->cs_change) {
+ if (dws->cs_control)
+ dws->cs_control(MRST_SPI_DEASSERT);
+ if (gpio_is_valid(cs_gpio))
+ gpio_set_value(cs_gpio, !(mode & SPI_CS_HIGH));
+ }
msg->state = NULL;
if (msg->complete)
@@ -509,7 +516,8 @@ static void pump_transfers(unsigned long data)
dw_writew(dws, DW_SPI_CTRL0, cr0);
spi_set_clk(dws, clk_div ? clk_div : chip->clk_div);
- spi_chip_sel(dws, spi->chip_select);
+ spi_chip_sel(dws, spi->chip_select, spi->cs_gpio,
+ spi->mode & SPI_CS_HIGH);
/* Set the interrupt mask, for poll mode just disable all int */
spi_mask_intr(dws, 0xff);
@@ -615,6 +623,7 @@ static int dw_spi_setup(struct spi_device *spi)
{
struct dw_spi_chip *chip_info = NULL;
struct chip_data *chip;
+ int ret;
/* Only alloc on first setup */
chip = spi_get_ctldata(spi);
@@ -668,6 +677,17 @@ static int dw_spi_setup(struct spi_device *spi)
| (spi->mode << SPI_MODE_OFFSET)
| (chip->tmode << SPI_TMOD_OFFSET);
+ if (gpio_is_valid(spi->cs_gpio)) {
+ ret = devm_gpio_request(&spi->dev, spi->cs_gpio,
+ dev_name(&spi->dev));
+ if (ret)
+ return ret;
+ ret = gpio_direction_output(spi->cs_gpio,
+ !(spi->mode & SPI_CS_HIGH));
+ if (ret)
+ return ret;
+ }
+
return 0;
}
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 587643dae11e..4a3a6d764b48 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -3,6 +3,7 @@
#include <linux/io.h>
#include <linux/scatterlist.h>
+#include <linux/gpio.h>
/* Register offsets */
#define DW_SPI_CTRL0 0x00
@@ -186,13 +187,16 @@ static inline void spi_set_clk(struct dw_spi *dws, u16
div)
dw_writel(dws, DW_SPI_BAUDR, div);
}
-static inline void spi_chip_sel(struct dw_spi *dws, u16 cs)
+static inline void spi_chip_sel(struct dw_spi *dws, u16 cs, int cs_gpio,
+ int gpio_active_val)
{
if (cs > dws->num_cs)
return;
if (dws->cs_control)
dws->cs_control(1);
+ if (gpio_is_valid(cs_gpio))
+ gpio_set_value(cs_gpio, gpio_active_val);
dw_writel(dws, DW_SPI_SER, 1 << cs);
}
--
1.8.5.2
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html