All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] dm: spi: fix CPHA and implement CPOL for soft-spi
@ 2020-03-30  8:28 J. Holland
  0 siblings, 0 replies; only message in thread
From: J. Holland @ 2020-03-30  8:28 UTC (permalink / raw)
  To: u-boot

Implement SPI modes for CPOL/CPHA in the soft-spi driver. Previously, 
CPOL=1 was
hard-coded and CPHA was implemented inversely (defaulting to CPHA=1).

Signed-off-by: Johannes Holland <joh.ho@gmx.de>
---
 ?drivers/spi/soft_spi.c | 56 ++++++++++++++++++++++++++++++++----------
 ?1 file changed, 43 insertions(+), 13 deletions(-)

diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
index b80f810bd1..5932ce8c5c 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -58,10 +58,12 @@ static int soft_spi_sda(struct udevice *dev, int bit)
 ?static int soft_spi_cs_activate(struct udevice *dev)
 ?{
 ???? 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);
+??? int cidle = !!(priv->mode & SPI_CPOL);

 ???? dm_gpio_set_value(&plat->cs, 0);
-??? dm_gpio_set_value(&plat->sclk, 0);
+??? dm_gpio_set_value(&plat->sclk, cidle); /* to idle */
 ???? dm_gpio_set_value(&plat->cs, 1);

 ???? return 0;
@@ -79,11 +81,14 @@ static int soft_spi_cs_deactivate(struct udevice *dev)

 ?static int soft_spi_claim_bus(struct udevice *dev)
 ?{
+??? struct udevice *bus = dev_get_parent(dev);
+??? struct soft_spi_priv *priv = dev_get_priv(bus);
+??? int cidle = !!(priv->mode & SPI_CPOL);
 ???? /*
 ????? * Make sure the SPI clock is in idle state as defined for
 ????? * this slave.
 ????? */
-??? return soft_spi_scl(dev, 0);
+??? return soft_spi_scl(dev, cidle);
 ?}

 ?static int soft_spi_release_bus(struct udevice *dev)
@@ -114,15 +119,18 @@ static int soft_spi_xfer(struct udevice *dev, 
unsigned int bitlen,
 ???? uchar??????? tmpdout = 0;
 ???? const u8??? *txd = dout;
 ???? u8??????? *rxd = din;
-??? int??????? cpha = priv->mode & SPI_CPHA;
+??? int??????? cpha = !!(priv->mode & SPI_CPHA);
+??? int??????? cidle = !!(priv->mode & SPI_CPOL);
 ???? unsigned int??? j;

 ???? debug("spi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
 ?????????? dev->parent->name, dev->name, *(uint *)txd, *(uint *)rxd,
 ?????????? bitlen);

-??? if (flags & SPI_XFER_BEGIN)
+??? if (flags & SPI_XFER_BEGIN) {
 ???????? soft_spi_cs_activate(dev);
+??????? udelay(plat->spi_delay_us);
+??? }

 ???? for (j = 0; j < bitlen; j++) {
 ???????? /*
@@ -140,22 +148,42 @@ static int soft_spi_xfer(struct udevice *dev, 
unsigned int bitlen,
 ???????????? tmpdin? = 0;
 ???????? }

-??????? if (!cpha)
-??????????? soft_spi_scl(dev, 0);
+??????? /*
+???????? * CPOL 0: idle is low (0), active is high (1)
+???????? * CPOL 1: idle is high (1), active is low (0)
+???????? */
+
+??????? /*
+???????? * drive bit
+???????? *? CPHA 1: CLK from idle to active
+???????? */
+??????? if (cpha)
+??????????? soft_spi_scl(dev, !cidle);
 ???????? 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);
+
+??????? /*
+???????? * sample bit
+???????? *? CPHA 0: CLK from idle to active
+???????? *? CPHA 1: CLK from active to idle
+???????? */
+??????? if (!cpha)
+??????????? soft_spi_scl(dev, !cidle);
 ???????? else
-??????????? soft_spi_scl(dev, 1);
+??????????? soft_spi_scl(dev, cidle);
 ???????? tmpdin??? <<= 1;
 ???????? if ((plat->flags & SPI_MASTER_NO_RX) == 0)
 ???????????? tmpdin??? |= dm_gpio_get_value(&plat->miso);
 ???????? tmpdout??? <<= 1;
 ???????? udelay(plat->spi_delay_us);
-??????? if (cpha)
-??????????? soft_spi_scl(dev, 1);
+
+??????? /*
+???????? * drive bit
+???????? *? CPHA 0: CLK from active to idle
+???????? */
+??????? if (!cpha)
+??????????? soft_spi_scl(dev, cidle);
 ???? }
 ???? /*
 ????? * If the number of bits isn't a multiple of 8, shift the last
@@ -168,15 +196,17 @@ static int soft_spi_xfer(struct udevice *dev, 
unsigned int bitlen,
 ???????? *rxd++ = tmpdin;
 ???? }

-??? if (flags & SPI_XFER_END)
+??? if (flags & SPI_XFER_END) {
+??????? udelay(plat->spi_delay_us);
 ???????? soft_spi_cs_deactivate(dev);
+??? }

 ???? return 0;
 ?}

 ?static int soft_spi_set_speed(struct udevice *dev, unsigned int speed)
 ?{
-??? /* Accept any speed */
+??? /* Ignore any speed settings. Speed is implemented via 
"spi-delay-us" */
 ???? return 0;
 ?}

--
2.26.0

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-03-30  8:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-30  8:28 [PATCH] dm: spi: fix CPHA and implement CPOL for soft-spi J. Holland

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.