aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-tegra114.c
diff options
context:
space:
mode:
authorRhyland Klein <rklein@nvidia.com>2013-09-26 13:01:43 -0400
committerMark Brown <broonie@linaro.org>2013-09-27 09:22:21 -0400
commitf4fade12d506e14867a2b0a5e2f7aaf227297d8b (patch)
tree29dd45eb4da3f6db7402fa1080e85703f19a7589 /drivers/spi/spi-tegra114.c
parent4a10c2ac2f368583138b774ca41fac4207911983 (diff)
spi/tegra114: Correct support for cs_change
The tegra114 driver wasn't currently handling the cs_change functionality. cs_change is meant to invert the decisions of whether or not to deactivate CS after each transfer. Without cs_change, after every transfer (other than the last in the message) the normal behavior is to leave CS active. For the last transfer, normally CS is deactivated when the transfer is complete. With cs_change set on a transfer (other than last one) CS would be deactivated and the next transfer would need to activate it again. If cs_change was set on the last tranfer in a message, then CS would be left active when the message compeleted. Also, this builds in logic so that if a different device tries to start a transfer while CS is active from a different device, it will abort the previous transfer and start a new one for the new device. This splits tegra_spi_start_transfer_one into 2 functions, the new one being tegra_spi_setup_transfer_one. The setup function is safe to call on all transfers, sets up for the transfer, and handles the special case of the first transfer in a message. In this special case, it needs to know whether or not it needs to activate CS. This work was based on the spi-atmel driver. Signed-off-by: Rhyland Klein <rklein@nvidia.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-tegra114.c')
-rw-r--r--drivers/spi/spi-tegra114.c85
1 files changed, 68 insertions, 17 deletions
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 145dd435483b..64ca86c806e5 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -182,6 +182,7 @@ struct tegra_spi_data {
182 u32 cur_speed; 182 u32 cur_speed;
183 183
184 struct spi_device *cur_spi; 184 struct spi_device *cur_spi;
185 struct spi_device *cs_control;
185 unsigned cur_pos; 186 unsigned cur_pos;
186 unsigned cur_len; 187 unsigned cur_len;
187 unsigned words_per_32bit; 188 unsigned words_per_32bit;
@@ -676,15 +677,12 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
676 dma_release_channel(dma_chan); 677 dma_release_channel(dma_chan);
677} 678}
678 679
679static int tegra_spi_start_transfer_one(struct spi_device *spi, 680static unsigned long tegra_spi_setup_transfer_one(struct spi_device *spi,
680 struct spi_transfer *t, bool is_first_of_msg, 681 struct spi_transfer *t, bool is_first_of_msg)
681 bool is_single_xfer)
682{ 682{
683 struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); 683 struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
684 u32 speed = t->speed_hz; 684 u32 speed = t->speed_hz;
685 u8 bits_per_word = t->bits_per_word; 685 u8 bits_per_word = t->bits_per_word;
686 unsigned total_fifo_words;
687 int ret;
688 unsigned long command1; 686 unsigned long command1;
689 int req_mode; 687 int req_mode;
690 688
@@ -698,7 +696,6 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
698 tspi->cur_rx_pos = 0; 696 tspi->cur_rx_pos = 0;
699 tspi->cur_tx_pos = 0; 697 tspi->cur_tx_pos = 0;
700 tspi->curr_xfer = t; 698 tspi->curr_xfer = t;
701 total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t);
702 699
703 if (is_first_of_msg) { 700 if (is_first_of_msg) {
704 tegra_spi_clear_status(tspi); 701 tegra_spi_clear_status(tspi);
@@ -717,7 +714,12 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
717 else if (req_mode == SPI_MODE_3) 714 else if (req_mode == SPI_MODE_3)
718 command1 |= SPI_CONTROL_MODE_3; 715 command1 |= SPI_CONTROL_MODE_3;
719 716
720 tegra_spi_writel(tspi, command1, SPI_COMMAND1); 717 if (tspi->cs_control) {
718 if (tspi->cs_control != spi)
719 tegra_spi_writel(tspi, command1, SPI_COMMAND1);
720 tspi->cs_control = NULL;
721 } else
722 tegra_spi_writel(tspi, command1, SPI_COMMAND1);
721 723
722 command1 |= SPI_CS_SW_HW; 724 command1 |= SPI_CS_SW_HW;
723 if (spi->mode & SPI_CS_HIGH) 725 if (spi->mode & SPI_CS_HIGH)
@@ -732,6 +734,18 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
732 command1 |= SPI_BIT_LENGTH(bits_per_word - 1); 734 command1 |= SPI_BIT_LENGTH(bits_per_word - 1);
733 } 735 }
734 736
737 return command1;
738}
739
740static int tegra_spi_start_transfer_one(struct spi_device *spi,
741 struct spi_transfer *t, unsigned long command1)
742{
743 struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
744 unsigned total_fifo_words;
745 int ret;
746
747 total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t);
748
735 if (tspi->is_packed) 749 if (tspi->is_packed)
736 command1 |= SPI_PACKED; 750 command1 |= SPI_PACKED;
737 751
@@ -803,29 +817,50 @@ static int tegra_spi_setup(struct spi_device *spi)
803 return 0; 817 return 0;
804} 818}
805 819
820static void tegra_spi_transfer_delay(int delay)
821{
822 if (!delay)
823 return;
824
825 if (delay >= 1000)
826 mdelay(delay / 1000);
827
828 udelay(delay % 1000);
829}
830
806static int tegra_spi_transfer_one_message(struct spi_master *master, 831static int tegra_spi_transfer_one_message(struct spi_master *master,
807 struct spi_message *msg) 832 struct spi_message *msg)
808{ 833{
809 bool is_first_msg = true; 834 bool is_first_msg = true;
810 int single_xfer;
811 struct tegra_spi_data *tspi = spi_master_get_devdata(master); 835 struct tegra_spi_data *tspi = spi_master_get_devdata(master);
812 struct spi_transfer *xfer; 836 struct spi_transfer *xfer;
813 struct spi_device *spi = msg->spi; 837 struct spi_device *spi = msg->spi;
814 int ret; 838 int ret;
839 bool skip = false;
815 840
816 msg->status = 0; 841 msg->status = 0;
817 msg->actual_length = 0; 842 msg->actual_length = 0;
818 843
819 single_xfer = list_is_singular(&msg->transfers);
820 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 844 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
845 unsigned long cmd1;
846
821 INIT_COMPLETION(tspi->xfer_completion); 847 INIT_COMPLETION(tspi->xfer_completion);
822 ret = tegra_spi_start_transfer_one(spi, xfer, 848
823 is_first_msg, single_xfer); 849 cmd1 = tegra_spi_setup_transfer_one(spi, xfer, is_first_msg);
850
851 if (!xfer->len) {
852 ret = 0;
853 skip = true;
854 goto complete_xfer;
855 }
856
857 ret = tegra_spi_start_transfer_one(spi, xfer, cmd1);
824 if (ret < 0) { 858 if (ret < 0) {
825 dev_err(tspi->dev, 859 dev_err(tspi->dev,
826 "spi can not start transfer, err %d\n", ret); 860 "spi can not start transfer, err %d\n", ret);
827 goto exit; 861 goto complete_xfer;
828 } 862 }
863
829 is_first_msg = false; 864 is_first_msg = false;
830 ret = wait_for_completion_timeout(&tspi->xfer_completion, 865 ret = wait_for_completion_timeout(&tspi->xfer_completion,
831 SPI_DMA_TIMEOUT); 866 SPI_DMA_TIMEOUT);
@@ -833,24 +868,40 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
833 dev_err(tspi->dev, 868 dev_err(tspi->dev,
834 "spi trasfer timeout, err %d\n", ret); 869 "spi trasfer timeout, err %d\n", ret);
835 ret = -EIO; 870 ret = -EIO;
836 goto exit; 871 goto complete_xfer;
837 } 872 }
838 873
839 if (tspi->tx_status || tspi->rx_status) { 874 if (tspi->tx_status || tspi->rx_status) {
840 dev_err(tspi->dev, "Error in Transfer\n"); 875 dev_err(tspi->dev, "Error in Transfer\n");
841 ret = -EIO; 876 ret = -EIO;
842 goto exit; 877 goto complete_xfer;
843 } 878 }
844 msg->actual_length += xfer->len; 879 msg->actual_length += xfer->len;
845 if (xfer->cs_change && xfer->delay_usecs) { 880
881complete_xfer:
882 if (ret < 0 || skip) {
846 tegra_spi_writel(tspi, tspi->def_command1_reg, 883 tegra_spi_writel(tspi, tspi->def_command1_reg,
847 SPI_COMMAND1); 884 SPI_COMMAND1);
848 udelay(xfer->delay_usecs); 885 tegra_spi_transfer_delay(xfer->delay_usecs);
886 goto exit;
887 } else if (msg->transfers.prev == &xfer->transfer_list) {
888 /* This is the last transfer in message */
889 if (xfer->cs_change)
890 tspi->cs_control = spi;
891 else {
892 tegra_spi_writel(tspi, tspi->def_command1_reg,
893 SPI_COMMAND1);
894 tegra_spi_transfer_delay(xfer->delay_usecs);
895 }
896 } else if (xfer->cs_change) {
897 tegra_spi_writel(tspi, tspi->def_command1_reg,
898 SPI_COMMAND1);
899 tegra_spi_transfer_delay(xfer->delay_usecs);
849 } 900 }
901
850 } 902 }
851 ret = 0; 903 ret = 0;
852exit: 904exit:
853 tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
854 msg->status = ret; 905 msg->status = ret;
855 spi_finalize_current_message(master); 906 spi_finalize_current_message(master);
856 return ret; 907 return ret;