diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2014-06-02 09:38:07 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-06-02 10:49:33 -0400 |
commit | 6837b8e91d2a080293c30d5fe42d9692390091fa (patch) | |
tree | 81a3f605a81ff224e0267364461245c47cf2d85d | |
parent | b42e03596db3d45980c976c8124fdc323f031dc4 (diff) |
spi: rspi: Extract rspi_pio_transfer()
The various PIO loops are very similar. Consolidate into a single
function rspi_pio_transfer().
Both buffer pointers can be NULL, as RSPI supports TX-only mode, and
Dual/Quad SPI Transfers are unidirectional.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/spi/spi-rspi.c | 95 |
1 files changed, 33 insertions, 62 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index ece8f6037943..fdbd46d0c570 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -438,15 +438,24 @@ static int rspi_data_in(struct rspi_data *rspi) | |||
438 | return data; | 438 | return data; |
439 | } | 439 | } |
440 | 440 | ||
441 | static int rspi_data_out_in(struct rspi_data *rspi, u8 data) | 441 | static int rspi_pio_transfer(struct rspi_data *rspi, const u8 *tx, u8 *rx, |
442 | unsigned int n) | ||
442 | { | 443 | { |
443 | int ret; | 444 | while (n-- > 0) { |
444 | 445 | if (tx) { | |
445 | ret = rspi_data_out(rspi, data); | 446 | int ret = rspi_data_out(rspi, *tx++); |
446 | if (ret < 0) | 447 | if (ret < 0) |
447 | return ret; | 448 | return ret; |
449 | } | ||
450 | if (rx) { | ||
451 | int ret = rspi_data_in(rspi); | ||
452 | if (ret < 0) | ||
453 | return ret; | ||
454 | *rx++ = ret; | ||
455 | } | ||
456 | } | ||
448 | 457 | ||
449 | return rspi_data_in(rspi); | 458 | return 0; |
450 | } | 459 | } |
451 | 460 | ||
452 | static void rspi_dma_complete(void *arg) | 461 | static void rspi_dma_complete(void *arg) |
@@ -644,13 +653,11 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t) | |||
644 | static int rspi_transfer_out_in(struct rspi_data *rspi, | 653 | static int rspi_transfer_out_in(struct rspi_data *rspi, |
645 | struct spi_transfer *xfer) | 654 | struct spi_transfer *xfer) |
646 | { | 655 | { |
647 | int remain = xfer->len, ret; | ||
648 | const u8 *tx_buf = xfer->tx_buf; | ||
649 | u8 *rx_buf = xfer->rx_buf; | ||
650 | u8 spcr; | 656 | u8 spcr; |
657 | int ret; | ||
651 | 658 | ||
652 | spcr = rspi_read8(rspi, RSPI_SPCR); | 659 | spcr = rspi_read8(rspi, RSPI_SPCR); |
653 | if (rx_buf) { | 660 | if (xfer->rx_buf) { |
654 | rspi_receive_init(rspi); | 661 | rspi_receive_init(rspi); |
655 | spcr &= ~SPCR_TXMD; | 662 | spcr &= ~SPCR_TXMD; |
656 | } else { | 663 | } else { |
@@ -658,18 +665,9 @@ static int rspi_transfer_out_in(struct rspi_data *rspi, | |||
658 | } | 665 | } |
659 | rspi_write8(rspi, spcr, RSPI_SPCR); | 666 | rspi_write8(rspi, spcr, RSPI_SPCR); |
660 | 667 | ||
661 | while (remain > 0) { | 668 | ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len); |
662 | ret = rspi_data_out(rspi, *tx_buf++); | 669 | if (ret < 0) |
663 | if (ret < 0) | 670 | return ret; |
664 | return ret; | ||
665 | if (rx_buf) { | ||
666 | ret = rspi_data_in(rspi); | ||
667 | if (ret < 0) | ||
668 | return ret; | ||
669 | *rx_buf++ = ret; | ||
670 | } | ||
671 | remain--; | ||
672 | } | ||
673 | 671 | ||
674 | /* Wait for the last transmission */ | 672 | /* Wait for the last transmission */ |
675 | rspi_wait_for_tx_empty(rspi); | 673 | rspi_wait_for_tx_empty(rspi); |
@@ -694,19 +692,13 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi, | |||
694 | static int rspi_rz_transfer_out_in(struct rspi_data *rspi, | 692 | static int rspi_rz_transfer_out_in(struct rspi_data *rspi, |
695 | struct spi_transfer *xfer) | 693 | struct spi_transfer *xfer) |
696 | { | 694 | { |
697 | int remain = xfer->len, ret; | 695 | int ret; |
698 | const u8 *tx_buf = xfer->tx_buf; | ||
699 | u8 *rx_buf = xfer->rx_buf; | ||
700 | 696 | ||
701 | rspi_rz_receive_init(rspi); | 697 | rspi_rz_receive_init(rspi); |
702 | 698 | ||
703 | while (remain > 0) { | 699 | ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len); |
704 | ret = rspi_data_out_in(rspi, *tx_buf++); | 700 | if (ret < 0) |
705 | if (ret < 0) | 701 | return ret; |
706 | return ret; | ||
707 | *rx_buf++ = ret; | ||
708 | remain--; | ||
709 | } | ||
710 | 702 | ||
711 | /* Wait for the last transmission */ | 703 | /* Wait for the last transmission */ |
712 | rspi_wait_for_tx_empty(rspi); | 704 | rspi_wait_for_tx_empty(rspi); |
@@ -726,19 +718,13 @@ static int rspi_rz_transfer_one(struct spi_master *master, | |||
726 | static int qspi_transfer_out_in(struct rspi_data *rspi, | 718 | static int qspi_transfer_out_in(struct rspi_data *rspi, |
727 | struct spi_transfer *xfer) | 719 | struct spi_transfer *xfer) |
728 | { | 720 | { |
729 | int remain = xfer->len, ret; | 721 | int ret; |
730 | const u8 *tx_buf = xfer->tx_buf; | ||
731 | u8 *rx_buf = xfer->rx_buf; | ||
732 | 722 | ||
733 | qspi_receive_init(rspi); | 723 | qspi_receive_init(rspi); |
734 | 724 | ||
735 | while (remain > 0) { | 725 | ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len); |
736 | ret = rspi_data_out_in(rspi, *tx_buf++); | 726 | if (ret < 0) |
737 | if (ret < 0) | 727 | return ret; |
738 | return ret; | ||
739 | *rx_buf++ = ret; | ||
740 | remain--; | ||
741 | } | ||
742 | 728 | ||
743 | /* Wait for the last transmission */ | 729 | /* Wait for the last transmission */ |
744 | rspi_wait_for_tx_empty(rspi); | 730 | rspi_wait_for_tx_empty(rspi); |
@@ -748,15 +734,11 @@ static int qspi_transfer_out_in(struct rspi_data *rspi, | |||
748 | 734 | ||
749 | static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) | 735 | static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) |
750 | { | 736 | { |
751 | const u8 *buf = xfer->tx_buf; | ||
752 | unsigned int i; | ||
753 | int ret; | 737 | int ret; |
754 | 738 | ||
755 | for (i = 0; i < xfer->len; i++) { | 739 | ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len); |
756 | ret = rspi_data_out(rspi, *buf++); | 740 | if (ret < 0) |
757 | if (ret < 0) | 741 | return ret; |
758 | return ret; | ||
759 | } | ||
760 | 742 | ||
761 | /* Wait for the last transmission */ | 743 | /* Wait for the last transmission */ |
762 | rspi_wait_for_tx_empty(rspi); | 744 | rspi_wait_for_tx_empty(rspi); |
@@ -766,18 +748,7 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) | |||
766 | 748 | ||
767 | static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) | 749 | static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) |
768 | { | 750 | { |
769 | u8 *buf = xfer->rx_buf; | 751 | return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len); |
770 | unsigned int i; | ||
771 | int ret; | ||
772 | |||
773 | for (i = 0; i < xfer->len; i++) { | ||
774 | ret = rspi_data_in(rspi); | ||
775 | if (ret < 0) | ||
776 | return ret; | ||
777 | *buf++ = ret; | ||
778 | } | ||
779 | |||
780 | return 0; | ||
781 | } | 752 | } |
782 | 753 | ||
783 | static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, | 754 | static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, |