From: Peng Fan <van.freenix@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/2] dm: spi: soft_spi: support linux way and bug fix
Date: Mon, 21 Mar 2016 16:29:37 +0800 [thread overview]
Message-ID: <1458548978-8741-1-git-send-email-van.freenix@gmail.com> (raw)
1. Support compatible string "spi-gpio" which is used by Linux
Linux use different bindings, so use UBOOT_COMPAT and
LINUX_COMPAT to differentiate them.
2. Bug fix
When doing xfer, should use device->parent, but not device
When doing bit xfer, should use "!!(tmpdout & 0x80)", but not
"(tmpdout & 0x80)"
3. Introduce SPI_MASTER_NO_RX and SPI_MASTER_NO_TX to handle
no rx or no tx case.
4. Tested on i.MX6 UltraLite board with 74LV595 spi-gpio chip.
Signed-off-by: Peng Fan <van.freenix@gmail.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Jagan Teki <jteki@openedev.com>
Cc: Stefano Babic <sbabic@denx.de>
---
drivers/spi/soft_spi.c | 75 ++++++++++++++++++++++++++++++++++++++------------
1 file changed, 57 insertions(+), 18 deletions(-)
diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
index aa4abcc..9a2b5f2 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -26,15 +26,23 @@ struct soft_spi_platdata {
struct gpio_desc mosi;
struct gpio_desc miso;
int spi_delay_us;
+ int flags;
};
+#define SPI_MASTER_NO_RX BIT(0)
+#define SPI_MASTER_NO_TX BIT(1)
+
+#define UBOOT_COMPAT BIT(0)
+#define LINUX_COMPAT BIT(1)
+
struct soft_spi_priv {
unsigned int mode;
};
static int soft_spi_scl(struct udevice *dev, int bit)
{
- struct soft_spi_platdata *plat = dev->platdata;
+ struct udevice *bus = dev_get_parent(dev);
+ struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->sclk, bit);
@@ -43,7 +51,8 @@ static int soft_spi_scl(struct udevice *dev, int bit)
static int soft_spi_sda(struct udevice *dev, int bit)
{
- struct soft_spi_platdata *plat = dev->platdata;
+ struct udevice *bus = dev_get_parent(dev);
+ struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->mosi, bit);
@@ -52,7 +61,8 @@ static int soft_spi_sda(struct udevice *dev, int bit)
static int soft_spi_cs_activate(struct udevice *dev)
{
- struct soft_spi_platdata *plat = dev->platdata;
+ struct udevice *bus = dev_get_parent(dev);
+ struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->cs, 0);
dm_gpio_set_value(&plat->sclk, 0);
@@ -63,7 +73,8 @@ static int soft_spi_cs_activate(struct udevice *dev)
static int soft_spi_cs_deactivate(struct udevice *dev)
{
- struct soft_spi_platdata *plat = dev->platdata;
+ struct udevice *bus = dev_get_parent(dev);
+ struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->cs, 0);
@@ -100,8 +111,9 @@ static int soft_spi_release_bus(struct udevice *dev)
static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
- struct soft_spi_priv *priv = dev_get_priv(dev);
- struct soft_spi_platdata *plat = dev->platdata;
+ struct udevice *bus = dev_get_parent(dev);
+ struct soft_spi_priv *priv = dev_get_priv(bus);
+ struct soft_spi_platdata *plat = dev_get_platdata(bus);
uchar tmpdin = 0;
uchar tmpdout = 0;
const u8 *txd = dout;
@@ -134,14 +146,16 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
if (!cpha)
soft_spi_scl(dev, 0);
- soft_spi_sda(dev, tmpdout & 0x80);
+ if ((plat->flags & SPI_MASTER_NO_TX) == 0)
+ soft_spi_sda(dev, !!(tmpdout & 0x80));
udelay(plat->spi_delay_us);
if (cpha)
soft_spi_scl(dev, 0);
else
soft_spi_scl(dev, 1);
tmpdin <<= 1;
- tmpdin |= dm_gpio_get_value(&plat->miso);
+ if ((plat->flags & SPI_MASTER_NO_RX) == 0)
+ tmpdin |= dm_gpio_get_value(&plat->miso);
tmpdout <<= 1;
udelay(plat->spi_delay_us);
if (cpha)
@@ -202,25 +216,50 @@ static int soft_spi_probe(struct udevice *dev)
{
struct spi_slave *slave = dev_get_parent_priv(dev);
struct soft_spi_platdata *plat = dev->platdata;
+ ulong driver_data = dev_get_driver_data(dev);
int cs_flags, clk_flags;
+ int ret;
cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;
- if (gpio_request_by_name(dev, "cs-gpio", 0, &plat->cs,
- GPIOD_IS_OUT | cs_flags) ||
- gpio_request_by_name(dev, "sclk-gpio", 0, &plat->sclk,
- GPIOD_IS_OUT | clk_flags) ||
- gpio_request_by_name(dev, "mosi-gpio", 0, &plat->mosi,
- GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE) ||
- gpio_request_by_name(dev, "miso-gpio", 0, &plat->miso,
- GPIOD_IS_IN))
- return -EINVAL;
+ if (driver_data & UBOOT_COMPAT) {
+ if (gpio_request_by_name(dev, "cs-gpio", 0, &plat->cs,
+ GPIOD_IS_OUT | cs_flags) ||
+ gpio_request_by_name(dev, "sclk-gpio", 0, &plat->sclk,
+ GPIOD_IS_OUT | clk_flags) ||
+ gpio_request_by_name(dev, "mosi-gpio", 0, &plat->mosi,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE) ||
+ gpio_request_by_name(dev, "miso-gpio", 0, &plat->miso,
+ GPIOD_IS_IN))
+ return -EINVAL;
+ } else if (driver_data & LINUX_COMPAT) {
+ if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
+ GPIOD_IS_OUT | cs_flags) ||
+ gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
+ GPIOD_IS_OUT | clk_flags))
+ return -EINVAL;
+
+ ret = gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ if (ret)
+ plat->flags |= SPI_MASTER_NO_TX;
+
+ ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
+ GPIOD_IS_IN);
+ if (ret)
+ plat->flags |= SPI_MASTER_NO_RX;
+
+ if ((plat->flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX)) ==
+ (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX))
+ return -EINVAL;
+ }
return 0;
}
static const struct udevice_id soft_spi_ids[] = {
- { .compatible = "u-boot,soft-spi" },
+ { .compatible = "u-boot,soft-spi", .data = UBOOT_COMPAT },
+ { .compatible = "spi-gpio", .data = LINUX_COMPAT },
{ }
};
--
2.6.2
next reply other threads:[~2016-03-21 8:29 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-21 8:29 Peng Fan [this message]
2016-03-21 8:29 ` [U-Boot] [PATCH 2/2] dm: gpio: introduce 74x164 driver Peng Fan
2016-04-09 18:33 ` Simon Glass
2016-04-11 5:44 ` Peng Fan
2016-04-09 18:33 ` [U-Boot] [PATCH 1/2] dm: spi: soft_spi: support linux way and bug fix Simon Glass
2016-04-11 5:45 ` Peng Fan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1458548978-8741-1-git-send-email-van.freenix@gmail.com \
--to=van.freenix@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.