diff options
author | Geert Uytterhoeven <geert+renesas@linux-m68k.org> | 2014-01-24 03:43:56 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-27 15:02:10 -0500 |
commit | 8449fd76deb9ac67a15a6fb8ead7bb4595d019d2 (patch) | |
tree | 864415240e91e054adb2fcf1e6f2caa490170891 | |
parent | eb557f75269e82dd26a79be536eca223ddc3eaf7 (diff) |
spi: rspi: Merge rspi_send_pio() and rspi_receive_pio()
rspi_send_pio() and rspi_receive_pio() are very similar:
- the former only sends data, using TX Only Mode,
- the latter sends and receives full duplex data to/from the hardware,
but uses dummy transmit data.
Merge them into rspi_transfer_out_in(), now supporting full duplex if
needed.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/spi/spi-rspi.c | 101 |
1 files changed, 46 insertions, 55 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index d837c5029308..cc90136d02c8 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -389,27 +389,6 @@ static int rspi_data_out_in(struct rspi_data *rspi, u8 data) | |||
389 | return rspi_data_in(rspi); | 389 | return rspi_data_in(rspi); |
390 | } | 390 | } |
391 | 391 | ||
392 | static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) | ||
393 | { | ||
394 | int remain = t->len, ret; | ||
395 | const u8 *data = t->tx_buf; | ||
396 | |||
397 | while (remain > 0) { | ||
398 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, | ||
399 | RSPI_SPCR); | ||
400 | |||
401 | ret = rspi_data_out(rspi, *data++); | ||
402 | if (ret < 0) | ||
403 | return ret; | ||
404 | remain--; | ||
405 | } | ||
406 | |||
407 | /* Waiting for the last transmission */ | ||
408 | rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) | 392 | static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) |
414 | { | 393 | { |
415 | int remain = t->len, ret; | 394 | int remain = t->len, ret; |
@@ -563,28 +542,6 @@ static void rspi_receive_init(const struct rspi_data *rspi) | |||
563 | RSPI_SPSR); | 542 | RSPI_SPSR); |
564 | } | 543 | } |
565 | 544 | ||
566 | static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t) | ||
567 | { | ||
568 | int remain = t->len, ret; | ||
569 | u8 *data = t->rx_buf; | ||
570 | |||
571 | rspi_receive_init(rspi); | ||
572 | |||
573 | while (remain > 0) { | ||
574 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, | ||
575 | RSPI_SPCR); | ||
576 | |||
577 | /* dummy write data for generate clock */ | ||
578 | ret = rspi_data_out_in(rspi, DUMMY_DATA); | ||
579 | if (ret < 0) | ||
580 | return ret; | ||
581 | *data++ = ret; | ||
582 | remain--; | ||
583 | } | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | static void qspi_receive_init(const struct rspi_data *rspi) | 545 | static void qspi_receive_init(const struct rspi_data *rspi) |
589 | { | 546 | { |
590 | u8 spsr; | 547 | u8 spsr; |
@@ -729,27 +686,61 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t) | |||
729 | return 0; | 686 | return 0; |
730 | } | 687 | } |
731 | 688 | ||
689 | static int rspi_transfer_out_in(struct rspi_data *rspi, | ||
690 | struct spi_transfer *xfer) | ||
691 | { | ||
692 | int remain = xfer->len, ret; | ||
693 | const u8 *tx_buf = xfer->tx_buf; | ||
694 | u8 *rx_buf = xfer->rx_buf; | ||
695 | u8 spcr, data; | ||
696 | |||
697 | rspi_receive_init(rspi); | ||
698 | |||
699 | spcr = rspi_read8(rspi, RSPI_SPCR); | ||
700 | if (rx_buf) | ||
701 | spcr &= ~SPCR_TXMD; | ||
702 | else | ||
703 | spcr |= SPCR_TXMD; | ||
704 | rspi_write8(rspi, spcr, RSPI_SPCR); | ||
705 | |||
706 | while (remain > 0) { | ||
707 | data = tx_buf ? *tx_buf++ : DUMMY_DATA; | ||
708 | ret = rspi_data_out(rspi, data); | ||
709 | if (ret < 0) | ||
710 | return ret; | ||
711 | if (rx_buf) { | ||
712 | ret = rspi_data_in(rspi); | ||
713 | if (ret < 0) | ||
714 | return ret; | ||
715 | *rx_buf++ = ret; | ||
716 | } | ||
717 | remain--; | ||
718 | } | ||
719 | |||
720 | /* Wait for the last transmission */ | ||
721 | rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); | ||
722 | |||
723 | return 0; | ||
724 | } | ||
725 | |||
732 | static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi, | 726 | static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi, |
733 | struct spi_transfer *xfer) | 727 | struct spi_transfer *xfer) |
734 | { | 728 | { |
735 | struct rspi_data *rspi = spi_master_get_devdata(master); | 729 | struct rspi_data *rspi = spi_master_get_devdata(master); |
736 | int ret = 0; | 730 | int ret; |
731 | |||
732 | if (!rspi_is_dma(rspi, xfer)) | ||
733 | return rspi_transfer_out_in(rspi, xfer); | ||
737 | 734 | ||
738 | if (xfer->tx_buf) { | 735 | if (xfer->tx_buf) { |
739 | if (rspi_is_dma(rspi, xfer)) | 736 | ret = rspi_send_dma(rspi, xfer); |
740 | ret = rspi_send_dma(rspi, xfer); | ||
741 | else | ||
742 | ret = rspi_send_pio(rspi, xfer); | ||
743 | if (ret < 0) | 737 | if (ret < 0) |
744 | return ret; | 738 | return ret; |
745 | } | 739 | } |
746 | if (xfer->rx_buf) { | 740 | if (xfer->rx_buf) |
747 | if (rspi_is_dma(rspi, xfer)) | 741 | return rspi_receive_dma(rspi, xfer); |
748 | ret = rspi_receive_dma(rspi, xfer); | 742 | |
749 | else | 743 | return 0; |
750 | ret = rspi_receive_pio(rspi, xfer); | ||
751 | } | ||
752 | return ret; | ||
753 | } | 744 | } |
754 | 745 | ||
755 | static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, | 746 | static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, |