diff options
author | Alexander Shiyan <shc_work@mail.ru> | 2014-02-02 01:59:49 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-02-03 13:24:45 -0500 |
commit | 8dda9d9a48baa4a4e0ff6ac9d8f1672f3bf6dfa5 (patch) | |
tree | e192025fcf46c3bbd915172b27ccee653745bb88 /drivers/spi/spi-clps711x.c | |
parent | c7a26f121df611caa47576a169627bfd1c3d1b38 (diff) |
spi: clps711x: Add support for 1-8 BPW transfers
This patch adds support for 1 to 8 BPW to driver and removes
excess BPW validation since this is already checked by SPI core.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-clps711x.c')
-rw-r--r-- | drivers/spi/spi-clps711x.c | 39 |
1 files changed, 16 insertions, 23 deletions
diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 89e5ea843fd0..89fef4712e9b 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c | |||
@@ -32,6 +32,7 @@ struct spi_clps711x_data { | |||
32 | 32 | ||
33 | u8 *tx_buf; | 33 | u8 *tx_buf; |
34 | u8 *rx_buf; | 34 | u8 *rx_buf; |
35 | unsigned int bpw; | ||
35 | int len; | 36 | int len; |
36 | 37 | ||
37 | int chipselect[0]; | 38 | int chipselect[0]; |
@@ -57,18 +58,12 @@ static void spi_clps711x_setup_mode(struct spi_device *spi) | |||
57 | clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); | 58 | clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); |
58 | } | 59 | } |
59 | 60 | ||
60 | static int spi_clps711x_setup_xfer(struct spi_device *spi, | 61 | static void spi_clps711x_setup_xfer(struct spi_device *spi, |
61 | struct spi_transfer *xfer) | 62 | struct spi_transfer *xfer) |
62 | { | 63 | { |
63 | u32 speed = xfer->speed_hz ? : spi->max_speed_hz; | 64 | u32 speed = xfer->speed_hz ? : spi->max_speed_hz; |
64 | u8 bpw = xfer->bits_per_word; | ||
65 | struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); | 65 | struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); |
66 | 66 | ||
67 | if (bpw != 8) { | ||
68 | dev_err(&spi->dev, "Unsupported master bus width %i\n", bpw); | ||
69 | return -EINVAL; | ||
70 | } | ||
71 | |||
72 | /* Setup SPI frequency divider */ | 67 | /* Setup SPI frequency divider */ |
73 | if (!speed || (speed >= hw->max_speed_hz)) | 68 | if (!speed || (speed >= hw->max_speed_hz)) |
74 | clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | | 69 | clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | |
@@ -82,38 +77,36 @@ static int spi_clps711x_setup_xfer(struct spi_device *spi, | |||
82 | else | 77 | else |
83 | clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | | 78 | clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | |
84 | SYSCON1_ADCKSEL(0), SYSCON1); | 79 | SYSCON1_ADCKSEL(0), SYSCON1); |
85 | |||
86 | return 0; | ||
87 | } | 80 | } |
88 | 81 | ||
89 | static int spi_clps711x_transfer_one_message(struct spi_master *master, | 82 | static int spi_clps711x_transfer_one_message(struct spi_master *master, |
90 | struct spi_message *msg) | 83 | struct spi_message *msg) |
91 | { | 84 | { |
92 | struct spi_clps711x_data *hw = spi_master_get_devdata(master); | 85 | struct spi_clps711x_data *hw = spi_master_get_devdata(master); |
86 | struct spi_device *spi = msg->spi; | ||
93 | struct spi_transfer *xfer; | 87 | struct spi_transfer *xfer; |
94 | int status = 0, cs = hw->chipselect[msg->spi->chip_select]; | 88 | int cs = hw->chipselect[spi->chip_select]; |
95 | 89 | ||
96 | spi_clps711x_setup_mode(msg->spi); | 90 | spi_clps711x_setup_mode(spi); |
97 | 91 | ||
98 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 92 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
99 | u8 data; | 93 | u8 data; |
100 | 94 | ||
101 | if (spi_clps711x_setup_xfer(msg->spi, xfer)) { | 95 | spi_clps711x_setup_xfer(spi, xfer); |
102 | status = -EINVAL; | ||
103 | goto out_xfr; | ||
104 | } | ||
105 | 96 | ||
106 | gpio_set_value(cs, !!(msg->spi->mode & SPI_CS_HIGH)); | 97 | gpio_set_value(cs, !!(spi->mode & SPI_CS_HIGH)); |
107 | 98 | ||
108 | reinit_completion(&hw->done); | 99 | reinit_completion(&hw->done); |
109 | 100 | ||
110 | hw->len = xfer->len; | 101 | hw->len = xfer->len; |
102 | hw->bpw = xfer->bits_per_word ? : spi->bits_per_word; | ||
111 | hw->tx_buf = (u8 *)xfer->tx_buf; | 103 | hw->tx_buf = (u8 *)xfer->tx_buf; |
112 | hw->rx_buf = (u8 *)xfer->rx_buf; | 104 | hw->rx_buf = (u8 *)xfer->rx_buf; |
113 | 105 | ||
114 | /* Initiate transfer */ | 106 | /* Initiate transfer */ |
115 | data = hw->tx_buf ? *hw->tx_buf++ : 0; | 107 | data = hw->tx_buf ? *hw->tx_buf++ : 0; |
116 | clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); | 108 | clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, |
109 | SYNCIO); | ||
117 | 110 | ||
118 | wait_for_completion(&hw->done); | 111 | wait_for_completion(&hw->done); |
119 | 112 | ||
@@ -122,13 +115,12 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, | |||
122 | 115 | ||
123 | if (xfer->cs_change || | 116 | if (xfer->cs_change || |
124 | list_is_last(&xfer->transfer_list, &msg->transfers)) | 117 | list_is_last(&xfer->transfer_list, &msg->transfers)) |
125 | gpio_set_value(cs, !(msg->spi->mode & SPI_CS_HIGH)); | 118 | gpio_set_value(cs, !(spi->mode & SPI_CS_HIGH)); |
126 | 119 | ||
127 | msg->actual_length += xfer->len; | 120 | msg->actual_length += xfer->len; |
128 | } | 121 | } |
129 | 122 | ||
130 | out_xfr: | 123 | msg->status = 0; |
131 | msg->status = status; | ||
132 | spi_finalize_current_message(master); | 124 | spi_finalize_current_message(master); |
133 | 125 | ||
134 | return 0; | 126 | return 0; |
@@ -147,7 +139,8 @@ static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) | |||
147 | /* Handle TX */ | 139 | /* Handle TX */ |
148 | if (--hw->len > 0) { | 140 | if (--hw->len > 0) { |
149 | data = hw->tx_buf ? *hw->tx_buf++ : 0; | 141 | data = hw->tx_buf ? *hw->tx_buf++ : 0; |
150 | clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); | 142 | clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, |
143 | SYNCIO); | ||
151 | } else | 144 | } else |
152 | complete(&hw->done); | 145 | complete(&hw->done); |
153 | 146 | ||
@@ -181,7 +174,7 @@ static int spi_clps711x_probe(struct platform_device *pdev) | |||
181 | 174 | ||
182 | master->bus_num = pdev->id; | 175 | master->bus_num = pdev->id; |
183 | master->mode_bits = SPI_CPHA | SPI_CS_HIGH; | 176 | master->mode_bits = SPI_CPHA | SPI_CS_HIGH; |
184 | master->bits_per_word_mask = SPI_BPW_MASK(8); | 177 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 8); |
185 | master->num_chipselect = pdata->num_chipselect; | 178 | master->num_chipselect = pdata->num_chipselect; |
186 | master->setup = spi_clps711x_setup; | 179 | master->setup = spi_clps711x_setup; |
187 | master->transfer_one_message = spi_clps711x_transfer_one_message; | 180 | master->transfer_one_message = spi_clps711x_transfer_one_message; |