summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPaul Fertser <fercerpav@gmail.com>2011-08-30 10:20:23 +0400
committerSascha Hauer <s.hauer@pengutronix.de>2011-09-12 12:19:40 +0200
commit19284441cc2169d01c46819e87b4824375532899 (patch)
tree34e69b56beb6a35f549ab086479a7528cf8b4535 /drivers
parent943b27107c94f1707aa750d5a95616943d678c84 (diff)
downloadbarebox-19284441cc2169d01c46819e87b4824375532899.tar.gz
barebox-19284441cc2169d01c46819e87b4824375532899.tar.xz
imx_spi: rework transfer according to the API, fix compatibility with spi_write_then_read()
This code was tested barely with m25p80 driver, reading jedec id and some data from the chip worked fine. Signed-off-by: Paul Fertser <fercerpav@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/imx_spi.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 6dc41b92f5..0d21fb3da1 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -310,23 +310,56 @@ static void cspi_2_3_init(struct imx_spi *imx)
}
#endif
+static void imx_spi_do_transfer(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
+ unsigned i;
+
+ if (spi->bits_per_word <= 8) {
+ const u8 *tx_buf = t->tx_buf;
+ u8 *rx_buf = t->rx_buf;
+ u8 rx_val;
+
+ for (i = 0; i < t->len; i++) {
+ rx_val = imx->xchg_single(imx, tx_buf ? tx_buf[i] : 0);
+ if (rx_buf)
+ rx_buf[i] = rx_val;
+ }
+ } else if (spi->bits_per_word <= 16) {
+ const u16 *tx_buf = t->tx_buf;
+ u16 *rx_buf = t->rx_buf;
+ u16 rx_val;
+
+ for (i = 0; i < t->len >> 1; i++) {
+ rx_val = imx->xchg_single(imx, tx_buf ? tx_buf[i] : 0);
+ if (rx_buf)
+ rx_buf[i] = rx_val;
+ }
+ } else if (spi->bits_per_word <= 32) {
+ const u32 *tx_buf = t->tx_buf;
+ u32 *rx_buf = t->rx_buf;
+ u32 rx_val;
+
+ for (i = 0; i < t->len >> 2; i++) {
+ rx_val = imx->xchg_single(imx, tx_buf ? tx_buf[i] : 0);
+ if (rx_buf)
+ rx_buf[i] = rx_val;
+ }
+ }
+}
+
static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
{
- struct spi_master *master = spi->master;
- struct imx_spi *imx = container_of(master, struct imx_spi, master);
- struct spi_transfer *t = NULL;
+ struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
+ struct spi_transfer *t = NULL;
imx->chipselect(spi, 1);
- list_for_each_entry (t, &mesg->transfers, transfer_list) {
- const u32 *txbuf = t->tx_buf;
- u32 *rxbuf = t->rx_buf;
- int i = 0;
+ mesg->actual_length = 0;
- while(i < t->len >> 2) {
- rxbuf[i] = imx->xchg_single(imx, txbuf[i]);
- i++;
- }
+ list_for_each_entry(t, &mesg->transfers, transfer_list) {
+ imx_spi_do_transfer(spi, t);
+ mesg->actual_length += t->len;
}
imx->chipselect(spi, 0);