diff mbox

[05/11] spi: spi-sh-msiof: rx_need_dummy_tx variant

Message ID 1385921962-19843-5-git-send-email-takasi-y@ops.dti.ne.jp (mailing list archive)
State Changes Requested
Headers show

Commit Message

takasi-y@ops.dti.ne.jp Dec. 1, 2013, 6:19 p.m. UTC
From: Takashi Yoshii <takasi-y@ops.dti.ne.jp>

There is a variant of MSIOF, that need dummy data transfer even when
you want only to receive.

This patch adds the option
 .rx_need_dummy_tx
to sh_msiof_spi_info.

Consult "Transmit and Receive Procedures" on HWM, if it says
 - Set SICTR.TSCKE to 1
 - Write dummy transmission data to SITFDR
to *receive*, enable this.
Ape6, Rcar-H2, and Rcar-M2 are found having this type of module.

Signed-off-by: Takashi Yoshii <takasi-y@ops.dti.ne.jp>
---
 drivers/spi/spi-sh-msiof.c   |    4 +++-
 include/linux/spi/sh_msiof.h |    1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

Comments

Mark Brown Dec. 2, 2013, 5:49 p.m. UTC | #1
On Mon, Dec 02, 2013 at 03:19:16AM +0900, takasi-y@ops.dti.ne.jp wrote:

>  	if (tx_buf)
>  		tx_fifo(p, tx_buf, words, fifo_shift);
> +	else if (rx_buf && p->info->rx_need_dummy_tx)
> +		tx_fifo(p, rx_buf, words, fifo_shift);

This is going to transmit the contents of the RX buffer.  This means
that if there's any data in there it'll get sent but the expected
behaviour would be to send all zeros.  It's possible some devices may
misbehave if this were to happen.  It would be better to allocate some
zeros with kzalloc() and send that.

Really we should have core support for this, it's not the only
controller with such limitations.
diff mbox

Patch

diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 8683732..936d8ab 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -207,7 +207,7 @@  static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,
 {
 	u32 dr2 = ((bits - 1) << 24) | ((words - 1) << 16);
 
-	if (tx_buf)
+	if (tx_buf || (rx_buf && p->info->rx_need_dummy_tx))
 		sh_msiof_write(p, TMDR2, dr2);
 	else
 		sh_msiof_write(p, TMDR2, dr2 | 1);
@@ -464,6 +464,8 @@  static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
 	/* write tx fifo */
 	if (tx_buf)
 		tx_fifo(p, tx_buf, words, fifo_shift);
+	else if (rx_buf && p->info->rx_need_dummy_tx)
+		tx_fifo(p, rx_buf, words, fifo_shift);
 
 	/* setup clock and rx/tx signals */
 	ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE);
diff --git a/include/linux/spi/sh_msiof.h b/include/linux/spi/sh_msiof.h
index 2e8db3d..cf36781 100644
--- a/include/linux/spi/sh_msiof.h
+++ b/include/linux/spi/sh_msiof.h
@@ -5,6 +5,7 @@  struct sh_msiof_spi_info {
 	int tx_fifo_override;
 	int rx_fifo_override;
 	u16 num_chipselect;
+	u16 rx_need_dummy_tx:1;
 };
 
 #endif /* __SPI_SH_MSIOF_H__ */