summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-03-14 02:48:25 -0700
committerGrant Likely <grant.likely@secretlab.ca>2012-03-15 03:41:50 -0600
commitbb9c5687e8cd02d6f8a3aea40c118b439cb09501 (patch)
treec523e187256ddde75cbd55dd5d7a79847c60ca5a /drivers/spi
parent49e599b8595f9d33276860c6a02e05f240c4ceca (diff)
downloadlinux-stable-bb9c5687e8cd02d6f8a3aea40c118b439cb09501.tar.gz
linux-stable-bb9c5687e8cd02d6f8a3aea40c118b439cb09501.tar.bz2
linux-stable-bb9c5687e8cd02d6f8a3aea40c118b439cb09501.zip
spi: sh-hspi: modify write/read method
Current sh-hspi had wrong write/read method which was not linux standard. If spi_transfer requests tx[2], rx[2] len=2, then, driver should run tx[0], rx[0], tx[1], rx[1]. But current sh-hspi runs tx[0], tx[1], rx[0], rx[1]. This patch fixes it up. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-sh-hspi.c93
1 files changed, 24 insertions, 69 deletions
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c
index 5784734d257d..934138c7b3d3 100644
--- a/drivers/spi/spi-sh-hspi.c
+++ b/drivers/spi/spi-sh-hspi.c
@@ -86,66 +86,6 @@ static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val)
return -ETIMEDOUT;
}
-static int hspi_push(struct hspi_priv *hspi, struct spi_message *msg,
- struct spi_transfer *t)
-{
- int i, ret;
- u8 *data = (u8 *)t->tx_buf;
-
- /*
- * FIXME
- * very simple, but polling transfer
- */
- for (i = 0; i < t->len; i++) {
- /* wait remains */
- ret = hspi_status_check_timeout(hspi, 0x1, 0x0);
- if (ret < 0)
- return ret;
-
- hspi_write(hspi, SPTBR, (u32)data[i]);
-
- /* wait recive */
- ret = hspi_status_check_timeout(hspi, 0x4, 0x4);
- if (ret < 0)
- return ret;
-
- /* dummy read */
- hspi_read(hspi, SPRBR);
- }
-
- return 0;
-}
-
-static int hspi_pop(struct hspi_priv *hspi, struct spi_message *msg,
- struct spi_transfer *t)
-{
- int i, ret;
- u8 *data = (u8 *)t->rx_buf;
-
- /*
- * FIXME
- * very simple, but polling receive
- */
- for (i = 0; i < t->len; i++) {
- /* wait remains */
- ret = hspi_status_check_timeout(hspi, 0x1, 0);
- if (ret < 0)
- return ret;
-
- /* dummy write */
- hspi_write(hspi, SPTBR, 0x0);
-
- /* wait recive */
- ret = hspi_status_check_timeout(hspi, 0x4, 0x4);
- if (ret < 0)
- return ret;
-
- data[i] = (u8)hspi_read(hspi, SPRBR);
- }
-
- return 0;
-}
-
/*
* spi master function
*/
@@ -223,7 +163,9 @@ static int hspi_transfer_one_message(struct spi_master *master,
{
struct hspi_priv *hspi = spi_master_get_devdata(master);
struct spi_transfer *t;
- int ret;
+ u32 tx;
+ u32 rx;
+ int ret, i;
dev_dbg(hspi->dev, "%s\n", __func__);
@@ -231,19 +173,32 @@ static int hspi_transfer_one_message(struct spi_master *master,
list_for_each_entry(t, &msg->transfers, transfer_list) {
hspi_hw_setup(hspi, msg, t);
- if (t->tx_buf) {
- ret = hspi_push(hspi, msg, t);
+ for (i = 0; i < t->len; i++) {
+
+ /* wait remains */
+ ret = hspi_status_check_timeout(hspi, 0x1, 0);
if (ret < 0)
- goto error;
- }
- if (t->rx_buf) {
- ret = hspi_pop(hspi, msg, t);
+ break;
+
+ tx = 0;
+ if (t->tx_buf)
+ tx = (u32)((u8 *)t->tx_buf)[i];
+
+ hspi_write(hspi, SPTBR, tx);
+
+ /* wait recive */
+ ret = hspi_status_check_timeout(hspi, 0x4, 0x4);
if (ret < 0)
- goto error;
+ break;
+
+ rx = hspi_read(hspi, SPRBR);
+ if (t->rx_buf)
+ ((u8 *)t->rx_buf)[i] = (u8)rx;
+
}
+
msg->actual_length += t->len;
}
-error:
msg->status = ret;
spi_finalize_current_message(master);