diff options
author | Mark Brown <broonie@linaro.org> | 2013-10-25 04:51:39 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-10-25 04:51:39 -0400 |
commit | f88df3a72c257d6071641164945ee51b379e1f44 (patch) | |
tree | bf3c26c74e060f78751c26f2b572a98ae68c8750 /drivers/spi/spi-tegra20-slink.c | |
parent | 5b380cb1522e774e2fd67392532963426a749ce8 (diff) | |
parent | f178e3dec700d5f47cc9a282dd098a2a7422d6c7 (diff) |
Merge remote-tracking branch 'spi/topic/tegra-slink' into spi-next
Diffstat (limited to 'drivers/spi/spi-tegra20-slink.c')
-rw-r--r-- | drivers/spi/spi-tegra20-slink.c | 139 |
1 files changed, 67 insertions, 72 deletions
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index c74ee87b243b..af0a67886ae8 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c | |||
@@ -278,7 +278,7 @@ static unsigned tegra_slink_calculate_curr_xfer_param( | |||
278 | { | 278 | { |
279 | unsigned remain_len = t->len - tspi->cur_pos; | 279 | unsigned remain_len = t->len - tspi->cur_pos; |
280 | unsigned max_word; | 280 | unsigned max_word; |
281 | unsigned bits_per_word ; | 281 | unsigned bits_per_word; |
282 | unsigned max_len; | 282 | unsigned max_len; |
283 | unsigned total_fifo_words; | 283 | unsigned total_fifo_words; |
284 | 284 | ||
@@ -707,8 +707,7 @@ static void tegra_slink_deinit_dma_param(struct tegra_slink_data *tspi, | |||
707 | } | 707 | } |
708 | 708 | ||
709 | static int tegra_slink_start_transfer_one(struct spi_device *spi, | 709 | static int tegra_slink_start_transfer_one(struct spi_device *spi, |
710 | struct spi_transfer *t, bool is_first_of_msg, | 710 | struct spi_transfer *t) |
711 | bool is_single_xfer) | ||
712 | { | 711 | { |
713 | struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); | 712 | struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); |
714 | u32 speed; | 713 | u32 speed; |
@@ -732,32 +731,12 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, | |||
732 | tspi->curr_xfer = t; | 731 | tspi->curr_xfer = t; |
733 | total_fifo_words = tegra_slink_calculate_curr_xfer_param(spi, tspi, t); | 732 | total_fifo_words = tegra_slink_calculate_curr_xfer_param(spi, tspi, t); |
734 | 733 | ||
735 | if (is_first_of_msg) { | 734 | command = tspi->command_reg; |
736 | tegra_slink_clear_status(tspi); | 735 | command &= ~SLINK_BIT_LENGTH(~0); |
736 | command |= SLINK_BIT_LENGTH(bits_per_word - 1); | ||
737 | 737 | ||
738 | command = tspi->def_command_reg; | 738 | command2 = tspi->command2_reg; |
739 | command |= SLINK_BIT_LENGTH(bits_per_word - 1); | 739 | command2 &= ~(SLINK_RXEN | SLINK_TXEN); |
740 | command |= SLINK_CS_SW | SLINK_CS_VALUE; | ||
741 | |||
742 | command2 = tspi->def_command2_reg; | ||
743 | command2 |= SLINK_SS_EN_CS(spi->chip_select); | ||
744 | |||
745 | command &= ~SLINK_MODES; | ||
746 | if (spi->mode & SPI_CPHA) | ||
747 | command |= SLINK_CK_SDA; | ||
748 | |||
749 | if (spi->mode & SPI_CPOL) | ||
750 | command |= SLINK_IDLE_SCLK_DRIVE_HIGH; | ||
751 | else | ||
752 | command |= SLINK_IDLE_SCLK_DRIVE_LOW; | ||
753 | } else { | ||
754 | command = tspi->command_reg; | ||
755 | command &= ~SLINK_BIT_LENGTH(~0); | ||
756 | command |= SLINK_BIT_LENGTH(bits_per_word - 1); | ||
757 | |||
758 | command2 = tspi->command2_reg; | ||
759 | command2 &= ~(SLINK_RXEN | SLINK_TXEN); | ||
760 | } | ||
761 | 740 | ||
762 | tegra_slink_writel(tspi, command, SLINK_COMMAND); | 741 | tegra_slink_writel(tspi, command, SLINK_COMMAND); |
763 | tspi->command_reg = command; | 742 | tspi->command_reg = command; |
@@ -824,58 +803,72 @@ static int tegra_slink_setup(struct spi_device *spi) | |||
824 | return 0; | 803 | return 0; |
825 | } | 804 | } |
826 | 805 | ||
827 | static int tegra_slink_transfer_one_message(struct spi_master *master, | 806 | static int tegra_slink_prepare_message(struct spi_master *master, |
828 | struct spi_message *msg) | 807 | struct spi_message *msg) |
829 | { | 808 | { |
830 | bool is_first_msg = true; | ||
831 | int single_xfer; | ||
832 | struct tegra_slink_data *tspi = spi_master_get_devdata(master); | 809 | struct tegra_slink_data *tspi = spi_master_get_devdata(master); |
833 | struct spi_transfer *xfer; | ||
834 | struct spi_device *spi = msg->spi; | 810 | struct spi_device *spi = msg->spi; |
835 | int ret; | ||
836 | 811 | ||
837 | msg->status = 0; | 812 | tegra_slink_clear_status(tspi); |
838 | msg->actual_length = 0; | ||
839 | 813 | ||
840 | single_xfer = list_is_singular(&msg->transfers); | 814 | tspi->command_reg = tspi->def_command_reg; |
841 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 815 | tspi->command_reg |= SLINK_CS_SW | SLINK_CS_VALUE; |
842 | INIT_COMPLETION(tspi->xfer_completion); | ||
843 | ret = tegra_slink_start_transfer_one(spi, xfer, | ||
844 | is_first_msg, single_xfer); | ||
845 | if (ret < 0) { | ||
846 | dev_err(tspi->dev, | ||
847 | "spi can not start transfer, err %d\n", ret); | ||
848 | goto exit; | ||
849 | } | ||
850 | is_first_msg = false; | ||
851 | ret = wait_for_completion_timeout(&tspi->xfer_completion, | ||
852 | SLINK_DMA_TIMEOUT); | ||
853 | if (WARN_ON(ret == 0)) { | ||
854 | dev_err(tspi->dev, | ||
855 | "spi trasfer timeout, err %d\n", ret); | ||
856 | ret = -EIO; | ||
857 | goto exit; | ||
858 | } | ||
859 | 816 | ||
860 | if (tspi->tx_status || tspi->rx_status) { | 817 | tspi->command2_reg = tspi->def_command2_reg; |
861 | dev_err(tspi->dev, "Error in Transfer\n"); | 818 | tspi->command2_reg |= SLINK_SS_EN_CS(spi->chip_select); |
862 | ret = -EIO; | 819 | |
863 | goto exit; | 820 | tspi->command_reg &= ~SLINK_MODES; |
864 | } | 821 | if (spi->mode & SPI_CPHA) |
865 | msg->actual_length += xfer->len; | 822 | tspi->command_reg |= SLINK_CK_SDA; |
866 | if (xfer->cs_change && xfer->delay_usecs) { | 823 | |
867 | tegra_slink_writel(tspi, tspi->def_command_reg, | 824 | if (spi->mode & SPI_CPOL) |
868 | SLINK_COMMAND); | 825 | tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_HIGH; |
869 | udelay(xfer->delay_usecs); | 826 | else |
870 | } | 827 | tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_LOW; |
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | static int tegra_slink_transfer_one(struct spi_master *master, | ||
833 | struct spi_device *spi, | ||
834 | struct spi_transfer *xfer) | ||
835 | { | ||
836 | struct tegra_slink_data *tspi = spi_master_get_devdata(master); | ||
837 | int ret; | ||
838 | |||
839 | INIT_COMPLETION(tspi->xfer_completion); | ||
840 | ret = tegra_slink_start_transfer_one(spi, xfer); | ||
841 | if (ret < 0) { | ||
842 | dev_err(tspi->dev, | ||
843 | "spi can not start transfer, err %d\n", ret); | ||
844 | return ret; | ||
871 | } | 845 | } |
872 | ret = 0; | 846 | |
873 | exit: | 847 | ret = wait_for_completion_timeout(&tspi->xfer_completion, |
848 | SLINK_DMA_TIMEOUT); | ||
849 | if (WARN_ON(ret == 0)) { | ||
850 | dev_err(tspi->dev, | ||
851 | "spi trasfer timeout, err %d\n", ret); | ||
852 | return -EIO; | ||
853 | } | ||
854 | |||
855 | if (tspi->tx_status) | ||
856 | return tspi->tx_status; | ||
857 | if (tspi->rx_status) | ||
858 | return tspi->rx_status; | ||
859 | |||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | static int tegra_slink_unprepare_message(struct spi_master *master, | ||
864 | struct spi_message *msg) | ||
865 | { | ||
866 | struct tegra_slink_data *tspi = spi_master_get_devdata(master); | ||
867 | |||
874 | tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); | 868 | tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); |
875 | tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); | 869 | tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); |
876 | msg->status = ret; | 870 | |
877 | spi_finalize_current_message(master); | 871 | return 0; |
878 | return ret; | ||
879 | } | 872 | } |
880 | 873 | ||
881 | static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) | 874 | static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) |
@@ -1078,7 +1071,9 @@ static int tegra_slink_probe(struct platform_device *pdev) | |||
1078 | /* the spi->mode bits understood by this driver: */ | 1071 | /* the spi->mode bits understood by this driver: */ |
1079 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1072 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1080 | master->setup = tegra_slink_setup; | 1073 | master->setup = tegra_slink_setup; |
1081 | master->transfer_one_message = tegra_slink_transfer_one_message; | 1074 | master->prepare_message = tegra_slink_prepare_message; |
1075 | master->transfer_one = tegra_slink_transfer_one; | ||
1076 | master->unprepare_message = tegra_slink_unprepare_message; | ||
1082 | master->auto_runtime_pm = true; | 1077 | master->auto_runtime_pm = true; |
1083 | master->num_chipselect = MAX_CHIP_SELECT; | 1078 | master->num_chipselect = MAX_CHIP_SELECT; |
1084 | master->bus_num = -1; | 1079 | master->bus_num = -1; |