mirror of https://github.com/hak5/openwrt.git
backport SPI master with no RXTX support (from 2.6.36)
Signed-off-by: Miguel Gaio <miguel.gaio@efixo.com> SVN-Revision: 23498lede-17.01
parent
d5854cfd4d
commit
cd9b90235c
|
@ -0,0 +1,237 @@
|
||||||
|
From 04bb2a031cf95b34b7432dd47b318a932a895b4c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||||
|
Date: Wed, 30 Jun 2010 14:27:32 -0600
|
||||||
|
Subject: [PATCH] spi/bitbang: add support for SPI_MASTER_NO_{TX, RX} modes
|
||||||
|
|
||||||
|
This patch adds a new flags argument to bitbang_txrx_be_cpha0 and
|
||||||
|
bitbang_txrx_be_cpha1 transfer functions. This enables support for
|
||||||
|
SPI_MASTER_NO_{TX,RX} transfer modes. The change should have no impact
|
||||||
|
on speed of the existing drivers. bitbank_txrx_* functions are usually
|
||||||
|
inlined into the drivers. When the argument is equal to constant zero,
|
||||||
|
the optimizer would be able to eliminate the dead code (flags checks)
|
||||||
|
easily. Tested on ARM and GCC 4.4.x and in all cases the checks were
|
||||||
|
eliminated in the inlined function.
|
||||||
|
|
||||||
|
Reviewed-by: Kyungmin Park <kyungmin.park@samsung.com>
|
||||||
|
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||||
|
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
||||||
|
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||||
|
---
|
||||||
|
drivers/spi/spi_bitbang_txrx.h | 16 ++++++++++------
|
||||||
|
drivers/spi/spi_butterfly.c | 2 +-
|
||||||
|
drivers/spi/spi_gpio.c | 8 ++++----
|
||||||
|
drivers/spi/spi_lm70llp.c | 2 +-
|
||||||
|
drivers/spi/spi_s3c24xx_gpio.c | 8 ++++----
|
||||||
|
drivers/spi/spi_sh_sci.c | 8 ++++----
|
||||||
|
6 files changed, 24 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/spi/spi_bitbang_txrx.h
|
||||||
|
+++ b/drivers/spi/spi_bitbang_txrx.h
|
||||||
|
@@ -44,7 +44,7 @@
|
||||||
|
|
||||||
|
static inline u32
|
||||||
|
bitbang_txrx_be_cpha0(struct spi_device *spi,
|
||||||
|
- unsigned nsecs, unsigned cpol,
|
||||||
|
+ unsigned nsecs, unsigned cpol, unsigned flags,
|
||||||
|
u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
/* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */
|
||||||
|
@@ -53,7 +53,8 @@ bitbang_txrx_be_cpha0(struct spi_device
|
||||||
|
for (word <<= (32 - bits); likely(bits); bits--) {
|
||||||
|
|
||||||
|
/* setup MSB (to slave) on trailing edge */
|
||||||
|
- setmosi(spi, word & (1 << 31));
|
||||||
|
+ if ((flags & SPI_MASTER_NO_TX) == 0)
|
||||||
|
+ setmosi(spi, word & (1 << 31));
|
||||||
|
spidelay(nsecs); /* T(setup) */
|
||||||
|
|
||||||
|
setsck(spi, !cpol);
|
||||||
|
@@ -61,7 +62,8 @@ bitbang_txrx_be_cpha0(struct spi_device
|
||||||
|
|
||||||
|
/* sample MSB (from slave) on leading edge */
|
||||||
|
word <<= 1;
|
||||||
|
- word |= getmiso(spi);
|
||||||
|
+ if ((flags & SPI_MASTER_NO_RX) == 0)
|
||||||
|
+ word |= getmiso(spi);
|
||||||
|
setsck(spi, cpol);
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
@@ -69,7 +71,7 @@ bitbang_txrx_be_cpha0(struct spi_device
|
||||||
|
|
||||||
|
static inline u32
|
||||||
|
bitbang_txrx_be_cpha1(struct spi_device *spi,
|
||||||
|
- unsigned nsecs, unsigned cpol,
|
||||||
|
+ unsigned nsecs, unsigned cpol, unsigned flags,
|
||||||
|
u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
/* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */
|
||||||
|
@@ -79,7 +81,8 @@ bitbang_txrx_be_cpha1(struct spi_device
|
||||||
|
|
||||||
|
/* setup MSB (to slave) on leading edge */
|
||||||
|
setsck(spi, !cpol);
|
||||||
|
- setmosi(spi, word & (1 << 31));
|
||||||
|
+ if ((flags & SPI_MASTER_NO_TX) == 0)
|
||||||
|
+ setmosi(spi, word & (1 << 31));
|
||||||
|
spidelay(nsecs); /* T(setup) */
|
||||||
|
|
||||||
|
setsck(spi, cpol);
|
||||||
|
@@ -87,7 +90,8 @@ bitbang_txrx_be_cpha1(struct spi_device
|
||||||
|
|
||||||
|
/* sample MSB (from slave) on trailing edge */
|
||||||
|
word <<= 1;
|
||||||
|
- word |= getmiso(spi);
|
||||||
|
+ if ((flags & SPI_MASTER_NO_RX) == 0)
|
||||||
|
+ word |= getmiso(spi);
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
--- a/drivers/spi/spi_butterfly.c
|
||||||
|
+++ b/drivers/spi/spi_butterfly.c
|
||||||
|
@@ -156,7 +156,7 @@ butterfly_txrx_word_mode0(struct spi_dev
|
||||||
|
unsigned nsecs,
|
||||||
|
u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
--- a/drivers/spi/spi_gpio.c
|
||||||
|
+++ b/drivers/spi/spi_gpio.c
|
||||||
|
@@ -157,25 +157,25 @@ static inline void spidelay(unsigned nse
|
||||||
|
static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
--- a/drivers/spi/spi_lm70llp.c
|
||||||
|
+++ b/drivers/spi/spi_lm70llp.c
|
||||||
|
@@ -191,7 +191,7 @@ static void lm70_chipselect(struct spi_d
|
||||||
|
*/
|
||||||
|
static u32 lm70_txrx(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spi_lm70llp_attach(struct parport *p)
|
||||||
|
--- a/drivers/spi/spi_s3c24xx_gpio.c
|
||||||
|
+++ b/drivers/spi/spi_s3c24xx_gpio.c
|
||||||
|
@@ -64,25 +64,25 @@ static inline u32 getmiso(struct spi_dev
|
||||||
|
static u32 s3c2410_spigpio_txrx_mode0(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 s3c2410_spigpio_txrx_mode1(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 s3c2410_spigpio_txrx_mode2(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 s3c2410_spigpio_txrx_mode3(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- a/drivers/spi/spi_sh_sci.c
|
||||||
|
+++ b/drivers/spi/spi_sh_sci.c
|
||||||
|
@@ -83,25 +83,25 @@ static inline u32 getmiso(struct spi_dev
|
||||||
|
static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sh_sci_spi_chipselect(struct spi_device *dev, int value)
|
||||||
|
--- a/drivers/spi/spi_gpio_old.c
|
||||||
|
+++ b/drivers/spi/spi_gpio_old.c
|
||||||
|
@@ -80,25 +80,25 @@ static inline void do_spidelay(struct sp
|
||||||
|
static u32 spi_gpio_txrx_mode0(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 spi_gpio_txrx_mode1(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 spi_gpio_txrx_mode2(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 spi_gpio_txrx_mode3(struct spi_device *spi,
|
||||||
|
unsigned nsecs, u32 word, u8 bits)
|
||||||
|
{
|
||||||
|
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spi_gpio_chipselect(struct spi_device *dev, int on)
|
|
@ -0,0 +1,217 @@
|
||||||
|
From 3c8e1a84fd6b984a7bce8816db2e3defc57bbfe4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||||
|
Date: Wed, 30 Jun 2010 14:27:37 -0600
|
||||||
|
Subject: [PATCH] spi/spi-gpio: add support for controllers without MISO or MOSI pin
|
||||||
|
|
||||||
|
There are some boards that do not strictly follow SPI standard and use
|
||||||
|
only 3 wires (SCLK, MOSI or MISO, SS) for connecting some simple auxiliary
|
||||||
|
chips and controls them with GPIO based 'spi controller'. In this
|
||||||
|
configuration the MISO or MOSI line is missing (it is not required if the
|
||||||
|
chip does not transfer any data back to host or host only reads data from
|
||||||
|
chip).
|
||||||
|
|
||||||
|
This patch adds support for such non-standard configuration in GPIO-based
|
||||||
|
SPI controller. It has been tested in configuration without MISO pin.
|
||||||
|
|
||||||
|
Reviewed-by: Kyungmin Park <kyungmin.park@samsung.com>
|
||||||
|
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||||
|
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
||||||
|
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||||
|
---
|
||||||
|
drivers/spi/spi_gpio.c | 101 ++++++++++++++++++++++++++++++++++-------
|
||||||
|
include/linux/spi/spi_gpio.h | 5 ++
|
||||||
|
2 files changed, 88 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/spi/spi_gpio.c
|
||||||
|
+++ b/drivers/spi/spi_gpio.c
|
||||||
|
@@ -178,6 +178,44 @@ static u32 spi_gpio_txrx_word_mode3(stru
|
||||||
|
return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * These functions do not call setmosi or getmiso if respective flag
|
||||||
|
+ * (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to
|
||||||
|
+ * call when such pin is not present or defined in the controller.
|
||||||
|
+ * A separate set of callbacks is defined to get highest possible
|
||||||
|
+ * speed in the generic case (when both MISO and MOSI lines are
|
||||||
|
+ * available), as optimiser will remove the checks when argument is
|
||||||
|
+ * constant.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi,
|
||||||
|
+ unsigned nsecs, u32 word, u8 bits)
|
||||||
|
+{
|
||||||
|
+ unsigned flags = spi->master->flags;
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi,
|
||||||
|
+ unsigned nsecs, u32 word, u8 bits)
|
||||||
|
+{
|
||||||
|
+ unsigned flags = spi->master->flags;
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi,
|
||||||
|
+ unsigned nsecs, u32 word, u8 bits)
|
||||||
|
+{
|
||||||
|
+ unsigned flags = spi->master->flags;
|
||||||
|
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi,
|
||||||
|
+ unsigned nsecs, u32 word, u8 bits)
|
||||||
|
+{
|
||||||
|
+ unsigned flags = spi->master->flags;
|
||||||
|
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
|
||||||
|
@@ -243,19 +281,30 @@ static int __devinit spi_gpio_alloc(unsi
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devinit
|
||||||
|
-spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label)
|
||||||
|
+spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label,
|
||||||
|
+ u16 *res_flags)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
|
/* NOTE: SPI_*_GPIO symbols may reference "pdata" */
|
||||||
|
|
||||||
|
- value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false);
|
||||||
|
- if (value)
|
||||||
|
- goto done;
|
||||||
|
-
|
||||||
|
- value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
|
||||||
|
- if (value)
|
||||||
|
- goto free_mosi;
|
||||||
|
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) {
|
||||||
|
+ value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false);
|
||||||
|
+ if (value)
|
||||||
|
+ goto done;
|
||||||
|
+ } else {
|
||||||
|
+ /* HW configuration without MOSI pin */
|
||||||
|
+ *res_flags |= SPI_MASTER_NO_TX;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) {
|
||||||
|
+ value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
|
||||||
|
+ if (value)
|
||||||
|
+ goto free_mosi;
|
||||||
|
+ } else {
|
||||||
|
+ /* HW configuration without MISO pin */
|
||||||
|
+ *res_flags |= SPI_MASTER_NO_RX;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
value = spi_gpio_alloc(SPI_SCK_GPIO, label, false);
|
||||||
|
if (value)
|
||||||
|
@@ -264,9 +313,11 @@ spi_gpio_request(struct spi_gpio_platfor
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
free_miso:
|
||||||
|
- gpio_free(SPI_MISO_GPIO);
|
||||||
|
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
|
||||||
|
+ gpio_free(SPI_MISO_GPIO);
|
||||||
|
free_mosi:
|
||||||
|
- gpio_free(SPI_MOSI_GPIO);
|
||||||
|
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
|
||||||
|
+ gpio_free(SPI_MOSI_GPIO);
|
||||||
|
done:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
@@ -277,6 +328,7 @@ static int __devinit spi_gpio_probe(stru
|
||||||
|
struct spi_master *master;
|
||||||
|
struct spi_gpio *spi_gpio;
|
||||||
|
struct spi_gpio_platform_data *pdata;
|
||||||
|
+ u16 master_flags = 0;
|
||||||
|
|
||||||
|
pdata = pdev->dev.platform_data;
|
||||||
|
#ifdef GENERIC_BITBANG
|
||||||
|
@@ -284,7 +336,7 @@ static int __devinit spi_gpio_probe(stru
|
||||||
|
return -ENODEV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- status = spi_gpio_request(pdata, dev_name(&pdev->dev));
|
||||||
|
+ status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
|
||||||
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
@@ -300,6 +352,7 @@ static int __devinit spi_gpio_probe(stru
|
||||||
|
if (pdata)
|
||||||
|
spi_gpio->pdata = *pdata;
|
||||||
|
|
||||||
|
+ master->flags = master_flags;
|
||||||
|
master->bus_num = pdev->id;
|
||||||
|
master->num_chipselect = SPI_N_CHIPSEL;
|
||||||
|
master->setup = spi_gpio_setup;
|
||||||
|
@@ -307,10 +360,18 @@ static int __devinit spi_gpio_probe(stru
|
||||||
|
|
||||||
|
spi_gpio->bitbang.master = spi_master_get(master);
|
||||||
|
spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
|
||||||
|
- spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
|
||||||
|
- spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
|
||||||
|
- spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
|
||||||
|
- spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3;
|
||||||
|
+
|
||||||
|
+ if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) {
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3;
|
||||||
|
+ } else {
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0;
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1;
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2;
|
||||||
|
+ spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3;
|
||||||
|
+ }
|
||||||
|
spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer;
|
||||||
|
spi_gpio->bitbang.flags = SPI_CS_HIGH;
|
||||||
|
|
||||||
|
@@ -318,8 +379,10 @@ static int __devinit spi_gpio_probe(stru
|
||||||
|
if (status < 0) {
|
||||||
|
spi_master_put(spi_gpio->bitbang.master);
|
||||||
|
gpio_free:
|
||||||
|
- gpio_free(SPI_MISO_GPIO);
|
||||||
|
- gpio_free(SPI_MOSI_GPIO);
|
||||||
|
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
|
||||||
|
+ gpio_free(SPI_MISO_GPIO);
|
||||||
|
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
|
||||||
|
+ gpio_free(SPI_MOSI_GPIO);
|
||||||
|
gpio_free(SPI_SCK_GPIO);
|
||||||
|
spi_master_put(master);
|
||||||
|
}
|
||||||
|
@@ -342,8 +405,10 @@ static int __devexit spi_gpio_remove(str
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
|
- gpio_free(SPI_MISO_GPIO);
|
||||||
|
- gpio_free(SPI_MOSI_GPIO);
|
||||||
|
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
|
||||||
|
+ gpio_free(SPI_MISO_GPIO);
|
||||||
|
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
|
||||||
|
+ gpio_free(SPI_MOSI_GPIO);
|
||||||
|
gpio_free(SPI_SCK_GPIO);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
--- a/include/linux/spi/spi_gpio.h
|
||||||
|
+++ b/include/linux/spi/spi_gpio.h
|
||||||
|
@@ -29,11 +29,16 @@
|
||||||
|
* SPI_GPIO_NO_CHIPSELECT to the controller_data:
|
||||||
|
* .controller_data = (void *) SPI_GPIO_NO_CHIPSELECT;
|
||||||
|
*
|
||||||
|
+ * If the MISO or MOSI pin is not available then it should be set to
|
||||||
|
+ * SPI_GPIO_NO_MISO or SPI_GPIO_NO_MOSI.
|
||||||
|
+ *
|
||||||
|
* If the bitbanged bus is later switched to a "native" controller,
|
||||||
|
* that platform_device and controller_data should be removed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SPI_GPIO_NO_CHIPSELECT ((unsigned long)-1l)
|
||||||
|
+#define SPI_GPIO_NO_MISO ((unsigned long)-1l)
|
||||||
|
+#define SPI_GPIO_NO_MOSI ((unsigned long)-1l)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct spi_gpio_platform_data - parameter for bitbanged SPI master
|
Loading…
Reference in New Issue