spi: Fix handling of cs_change in core implementation

Message ID 1396139265-28900-1-git-send-email-broonie@kernel.org
State New
Headers show

Commit Message

Mark Brown March 30, 2014, 12:27 a.m.
From: Mark Brown <broonie@linaro.org>

The core implementation of cs_change didn't follow the documentation
which says that cs_change in the middle of the transfer means to briefly
deassert chip select, instead it followed buggy drivers which change the
polarity of chip select.  Use a delay of 10us between deassert and
reassert simply from pulling numbers out of a hat.

Reported-by: Gerhard Sittig <gsi@denx.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
---

Compile tested only.

 drivers/spi/spi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Gerhard Sittig March 31, 2014, 7:45 a.m. | #1
On Sun, 2014-03-30 at 00:27 +0000, Mark Brown wrote:
> 
> From: Mark Brown <broonie@linaro.org>
> 
> The core implementation of cs_change didn't follow the documentation
> which says that cs_change in the middle of the transfer means to briefly
> deassert chip select, instead it followed buggy drivers which change the
> polarity of chip select.  Use a delay of 10us between deassert and
> reassert simply from pulling numbers out of a hat.
> 
> Reported-by: Gerhard Sittig <gsi@denx.de>
> Signed-off-by: Mark Brown <broonie@linaro.org>

The change looks good to me.  The resulting behaviour now is what
the documentation suggests (brief deassertion of the CS signal).
The previous inversion was unexpected.

The delay between deassertion and re-assertion looks good, too.
It allows for propagation of the change through the hardware.
Those who need longer pauses still can construct individual
messages.  There's probably no need to change the boolean
"cs_change" into a numerical "deassertion pause length" spec.


virtually yours
Gerhard Sittig
Mark Brown March 31, 2014, 5:17 p.m. | #2
On Mon, Mar 31, 2014 at 09:45:29AM +0200, Gerhard Sittig wrote:

> The delay between deassertion and re-assertion looks good, too.
> It allows for propagation of the change through the hardware.
> Those who need longer pauses still can construct individual
> messages.  There's probably no need to change the boolean
> "cs_change" into a numerical "deassertion pause length" spec.

I'm more worried about board specific requirements to increase the delay
there than I am about devices, or about devices that wish to lower the
delay.  But I do think it's likely to be OK in practice, someone who
actually runs into problems can worry about enhancements.

Patch hide | download patch | download mbox

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 121c43b..4eb9bf0 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -754,7 +754,6 @@  static int spi_transfer_one_message(struct spi_master *master,
 				    struct spi_message *msg)
 {
 	struct spi_transfer *xfer;
-	bool cur_cs = true;
 	bool keep_cs = false;
 	int ret = 0;
 	int ms = 1;
@@ -800,8 +799,9 @@  static int spi_transfer_one_message(struct spi_master *master,
 					 &msg->transfers)) {
 				keep_cs = true;
 			} else {
-				cur_cs = !cur_cs;
-				spi_set_cs(msg->spi, cur_cs);
+				spi_set_cs(msg->spi, false);
+				udelay(10);
+				spi_set_cs(msg->spi, true);
 			}
 		}