diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 21:42:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 21:42:06 -0400 |
commit | b18cae4224bde7e5a332c19bc99247b2098ea232 (patch) | |
tree | 2ffa750e6a043a1dcfccd71588b7d6cfdcad440a /drivers/spi | |
parent | 4833c16dea61cb30d6f77dfec3067a08ba79b361 (diff) | |
parent | f41649e040b1f63e809fb2adb78ed2f3c3ebbcd0 (diff) |
Merge branch 'for-next' of git://android.git.kernel.org/kernel/tegra
* 'for-next' of git://android.git.kernel.org/kernel/tegra:
spi: tegra: fix error setting on timeout
spi: add spi_tegra driver
tegra: harmony: enable PCI Express
tegra: add PCI Express support
tegra: add PCI Express clocks
[ARM] tegra: Add APB DMA support
[ARM] tegra: Add cpufreq support
[ARM] tegra: common: Update common clock init table
[ARM] tegra: clock: Add dvfs support, bug fixes, and cleanups
[ARM] tegra: Add support for reading fuses
[ARM] tegra: gpio: Add suspend and wake support
[ARM] tegra: pinmux: add safe values, move tegra2, add suspend
[ARM] tegra: add suspend and mirror irqs to legacy controller
[ARM] tegra: Add legacy irq support
[ARM] tegra: update iomap
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 7 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/spi_tegra.c | 618 |
3 files changed, 626 insertions, 0 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4b9eec68fad6..78f9fd02c1b2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -329,6 +329,13 @@ config SPI_STMP3XXX | |||
329 | help | 329 | help |
330 | SPI driver for Freescale STMP37xx/378x SoC SSP interface | 330 | SPI driver for Freescale STMP37xx/378x SoC SSP interface |
331 | 331 | ||
332 | config SPI_TEGRA | ||
333 | tristate "Nvidia Tegra SPI controller" | ||
334 | depends on ARCH_TEGRA | ||
335 | select TEGRA_SYSTEM_DMA | ||
336 | help | ||
337 | SPI driver for NVidia Tegra SoCs | ||
338 | |||
332 | config SPI_TOPCLIFF_PCH | 339 | config SPI_TOPCLIFF_PCH |
333 | tristate "Topcliff PCH SPI Controller" | 340 | tristate "Topcliff PCH SPI Controller" |
334 | depends on PCI | 341 | depends on PCI |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 557aaadf56b2..8bc1a5abac1f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -39,6 +39,7 @@ obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o | |||
39 | obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o | 39 | obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o |
40 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o | 40 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o |
41 | obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o | 41 | obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o |
42 | obj-$(CONFIG_SPI_TEGRA) += spi_tegra.o | ||
42 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o | 43 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o |
43 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o | 44 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o |
44 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o | 45 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o |
diff --git a/drivers/spi/spi_tegra.c b/drivers/spi/spi_tegra.c new file mode 100644 index 000000000000..bb7df02a5472 --- /dev/null +++ b/drivers/spi/spi_tegra.c | |||
@@ -0,0 +1,618 @@ | |||
1 | /* | ||
2 | * Driver for Nvidia TEGRA spi controller. | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * | ||
6 | * Author: | ||
7 | * Erik Gilling <konkers@android.com> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | #include <linux/dmapool.h> | ||
27 | #include <linux/clk.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/delay.h> | ||
30 | |||
31 | #include <linux/spi/spi.h> | ||
32 | |||
33 | #include <mach/dma.h> | ||
34 | |||
35 | #define SLINK_COMMAND 0x000 | ||
36 | #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) | ||
37 | #define SLINK_WORD_SIZE(x) (((x) & 0x1f) << 5) | ||
38 | #define SLINK_BOTH_EN (1 << 10) | ||
39 | #define SLINK_CS_SW (1 << 11) | ||
40 | #define SLINK_CS_VALUE (1 << 12) | ||
41 | #define SLINK_CS_POLARITY (1 << 13) | ||
42 | #define SLINK_IDLE_SDA_DRIVE_LOW (0 << 16) | ||
43 | #define SLINK_IDLE_SDA_DRIVE_HIGH (1 << 16) | ||
44 | #define SLINK_IDLE_SDA_PULL_LOW (2 << 16) | ||
45 | #define SLINK_IDLE_SDA_PULL_HIGH (3 << 16) | ||
46 | #define SLINK_IDLE_SDA_MASK (3 << 16) | ||
47 | #define SLINK_CS_POLARITY1 (1 << 20) | ||
48 | #define SLINK_CK_SDA (1 << 21) | ||
49 | #define SLINK_CS_POLARITY2 (1 << 22) | ||
50 | #define SLINK_CS_POLARITY3 (1 << 23) | ||
51 | #define SLINK_IDLE_SCLK_DRIVE_LOW (0 << 24) | ||
52 | #define SLINK_IDLE_SCLK_DRIVE_HIGH (1 << 24) | ||
53 | #define SLINK_IDLE_SCLK_PULL_LOW (2 << 24) | ||
54 | #define SLINK_IDLE_SCLK_PULL_HIGH (3 << 24) | ||
55 | #define SLINK_IDLE_SCLK_MASK (3 << 24) | ||
56 | #define SLINK_M_S (1 << 28) | ||
57 | #define SLINK_WAIT (1 << 29) | ||
58 | #define SLINK_GO (1 << 30) | ||
59 | #define SLINK_ENB (1 << 31) | ||
60 | |||
61 | #define SLINK_COMMAND2 0x004 | ||
62 | #define SLINK_LSBFE (1 << 0) | ||
63 | #define SLINK_SSOE (1 << 1) | ||
64 | #define SLINK_SPIE (1 << 4) | ||
65 | #define SLINK_BIDIROE (1 << 6) | ||
66 | #define SLINK_MODFEN (1 << 7) | ||
67 | #define SLINK_INT_SIZE(x) (((x) & 0x1f) << 8) | ||
68 | #define SLINK_CS_ACTIVE_BETWEEN (1 << 17) | ||
69 | #define SLINK_SS_EN_CS(x) (((x) & 0x3) << 18) | ||
70 | #define SLINK_SS_SETUP(x) (((x) & 0x3) << 20) | ||
71 | #define SLINK_FIFO_REFILLS_0 (0 << 22) | ||
72 | #define SLINK_FIFO_REFILLS_1 (1 << 22) | ||
73 | #define SLINK_FIFO_REFILLS_2 (2 << 22) | ||
74 | #define SLINK_FIFO_REFILLS_3 (3 << 22) | ||
75 | #define SLINK_FIFO_REFILLS_MASK (3 << 22) | ||
76 | #define SLINK_WAIT_PACK_INT(x) (((x) & 0x7) << 26) | ||
77 | #define SLINK_SPC0 (1 << 29) | ||
78 | #define SLINK_TXEN (1 << 30) | ||
79 | #define SLINK_RXEN (1 << 31) | ||
80 | |||
81 | #define SLINK_STATUS 0x008 | ||
82 | #define SLINK_COUNT(val) (((val) >> 0) & 0x1f) | ||
83 | #define SLINK_WORD(val) (((val) >> 5) & 0x1f) | ||
84 | #define SLINK_BLK_CNT(val) (((val) >> 0) & 0xffff) | ||
85 | #define SLINK_MODF (1 << 16) | ||
86 | #define SLINK_RX_UNF (1 << 18) | ||
87 | #define SLINK_TX_OVF (1 << 19) | ||
88 | #define SLINK_TX_FULL (1 << 20) | ||
89 | #define SLINK_TX_EMPTY (1 << 21) | ||
90 | #define SLINK_RX_FULL (1 << 22) | ||
91 | #define SLINK_RX_EMPTY (1 << 23) | ||
92 | #define SLINK_TX_UNF (1 << 24) | ||
93 | #define SLINK_RX_OVF (1 << 25) | ||
94 | #define SLINK_TX_FLUSH (1 << 26) | ||
95 | #define SLINK_RX_FLUSH (1 << 27) | ||
96 | #define SLINK_SCLK (1 << 28) | ||
97 | #define SLINK_ERR (1 << 29) | ||
98 | #define SLINK_RDY (1 << 30) | ||
99 | #define SLINK_BSY (1 << 31) | ||
100 | |||
101 | #define SLINK_MAS_DATA 0x010 | ||
102 | #define SLINK_SLAVE_DATA 0x014 | ||
103 | |||
104 | #define SLINK_DMA_CTL 0x018 | ||
105 | #define SLINK_DMA_BLOCK_SIZE(x) (((x) & 0xffff) << 0) | ||
106 | #define SLINK_TX_TRIG_1 (0 << 16) | ||
107 | #define SLINK_TX_TRIG_4 (1 << 16) | ||
108 | #define SLINK_TX_TRIG_8 (2 << 16) | ||
109 | #define SLINK_TX_TRIG_16 (3 << 16) | ||
110 | #define SLINK_TX_TRIG_MASK (3 << 16) | ||
111 | #define SLINK_RX_TRIG_1 (0 << 18) | ||
112 | #define SLINK_RX_TRIG_4 (1 << 18) | ||
113 | #define SLINK_RX_TRIG_8 (2 << 18) | ||
114 | #define SLINK_RX_TRIG_16 (3 << 18) | ||
115 | #define SLINK_RX_TRIG_MASK (3 << 18) | ||
116 | #define SLINK_PACKED (1 << 20) | ||
117 | #define SLINK_PACK_SIZE_4 (0 << 21) | ||
118 | #define SLINK_PACK_SIZE_8 (1 << 21) | ||
119 | #define SLINK_PACK_SIZE_16 (2 << 21) | ||
120 | #define SLINK_PACK_SIZE_32 (3 << 21) | ||
121 | #define SLINK_PACK_SIZE_MASK (3 << 21) | ||
122 | #define SLINK_IE_TXC (1 << 26) | ||
123 | #define SLINK_IE_RXC (1 << 27) | ||
124 | #define SLINK_DMA_EN (1 << 31) | ||
125 | |||
126 | #define SLINK_STATUS2 0x01c | ||
127 | #define SLINK_TX_FIFO_EMPTY_COUNT(val) (((val) & 0x3f) >> 0) | ||
128 | #define SLINK_RX_FIFO_FULL_COUNT(val) (((val) & 0x3f) >> 16) | ||
129 | |||
130 | #define SLINK_TX_FIFO 0x100 | ||
131 | #define SLINK_RX_FIFO 0x180 | ||
132 | |||
133 | static const unsigned long spi_tegra_req_sels[] = { | ||
134 | TEGRA_DMA_REQ_SEL_SL2B1, | ||
135 | TEGRA_DMA_REQ_SEL_SL2B2, | ||
136 | TEGRA_DMA_REQ_SEL_SL2B3, | ||
137 | TEGRA_DMA_REQ_SEL_SL2B4, | ||
138 | }; | ||
139 | |||
140 | #define BB_LEN 32 | ||
141 | |||
142 | struct spi_tegra_data { | ||
143 | struct spi_master *master; | ||
144 | struct platform_device *pdev; | ||
145 | spinlock_t lock; | ||
146 | |||
147 | struct clk *clk; | ||
148 | void __iomem *base; | ||
149 | unsigned long phys; | ||
150 | |||
151 | u32 cur_speed; | ||
152 | |||
153 | struct list_head queue; | ||
154 | struct spi_transfer *cur; | ||
155 | unsigned cur_pos; | ||
156 | unsigned cur_len; | ||
157 | unsigned cur_bytes_per_word; | ||
158 | |||
159 | /* The tegra spi controller has a bug which causes the first word | ||
160 | * in PIO transactions to be garbage. Since packed DMA transactions | ||
161 | * require transfers to be 4 byte aligned we need a bounce buffer | ||
162 | * for the generic case. | ||
163 | */ | ||
164 | struct tegra_dma_req rx_dma_req; | ||
165 | struct tegra_dma_channel *rx_dma; | ||
166 | u32 *rx_bb; | ||
167 | dma_addr_t rx_bb_phys; | ||
168 | }; | ||
169 | |||
170 | |||
171 | static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, | ||
172 | unsigned long reg) | ||
173 | { | ||
174 | return readl(tspi->base + reg); | ||
175 | } | ||
176 | |||
177 | static inline void spi_tegra_writel(struct spi_tegra_data *tspi, | ||
178 | unsigned long val, | ||
179 | unsigned long reg) | ||
180 | { | ||
181 | writel(val, tspi->base + reg); | ||
182 | } | ||
183 | |||
184 | static void spi_tegra_go(struct spi_tegra_data *tspi) | ||
185 | { | ||
186 | unsigned long val; | ||
187 | |||
188 | wmb(); | ||
189 | |||
190 | val = spi_tegra_readl(tspi, SLINK_DMA_CTL); | ||
191 | val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN; | ||
192 | val |= SLINK_DMA_BLOCK_SIZE(tspi->rx_dma_req.size / 4 - 1); | ||
193 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | ||
194 | |||
195 | tegra_dma_enqueue_req(tspi->rx_dma, &tspi->rx_dma_req); | ||
196 | |||
197 | val |= SLINK_DMA_EN; | ||
198 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | ||
199 | } | ||
200 | |||
201 | static unsigned spi_tegra_fill_tx_fifo(struct spi_tegra_data *tspi, | ||
202 | struct spi_transfer *t) | ||
203 | { | ||
204 | unsigned len = min(t->len - tspi->cur_pos, BB_LEN * | ||
205 | tspi->cur_bytes_per_word); | ||
206 | u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_pos; | ||
207 | int i, j; | ||
208 | unsigned long val; | ||
209 | |||
210 | val = spi_tegra_readl(tspi, SLINK_COMMAND); | ||
211 | val &= ~SLINK_WORD_SIZE(~0); | ||
212 | val |= SLINK_WORD_SIZE(len / tspi->cur_bytes_per_word - 1); | ||
213 | spi_tegra_writel(tspi, val, SLINK_COMMAND); | ||
214 | |||
215 | for (i = 0; i < len; i += tspi->cur_bytes_per_word) { | ||
216 | val = 0; | ||
217 | for (j = 0; j < tspi->cur_bytes_per_word; j++) | ||
218 | val |= tx_buf[i + j] << j * 8; | ||
219 | |||
220 | spi_tegra_writel(tspi, val, SLINK_TX_FIFO); | ||
221 | } | ||
222 | |||
223 | tspi->rx_dma_req.size = len / tspi->cur_bytes_per_word * 4; | ||
224 | |||
225 | return len; | ||
226 | } | ||
227 | |||
228 | static unsigned spi_tegra_drain_rx_fifo(struct spi_tegra_data *tspi, | ||
229 | struct spi_transfer *t) | ||
230 | { | ||
231 | unsigned len = tspi->cur_len; | ||
232 | u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_pos; | ||
233 | int i, j; | ||
234 | unsigned long val; | ||
235 | |||
236 | for (i = 0; i < len; i += tspi->cur_bytes_per_word) { | ||
237 | val = tspi->rx_bb[i / tspi->cur_bytes_per_word]; | ||
238 | for (j = 0; j < tspi->cur_bytes_per_word; j++) | ||
239 | rx_buf[i + j] = (val >> (j * 8)) & 0xff; | ||
240 | } | ||
241 | |||
242 | return len; | ||
243 | } | ||
244 | |||
245 | static void spi_tegra_start_transfer(struct spi_device *spi, | ||
246 | struct spi_transfer *t) | ||
247 | { | ||
248 | struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); | ||
249 | u32 speed; | ||
250 | u8 bits_per_word; | ||
251 | unsigned long val; | ||
252 | |||
253 | speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz; | ||
254 | bits_per_word = t->bits_per_word ? t->bits_per_word : | ||
255 | spi->bits_per_word; | ||
256 | |||
257 | tspi->cur_bytes_per_word = (bits_per_word - 1) / 8 + 1; | ||
258 | |||
259 | if (speed != tspi->cur_speed) | ||
260 | clk_set_rate(tspi->clk, speed); | ||
261 | |||
262 | if (tspi->cur_speed == 0) | ||
263 | clk_enable(tspi->clk); | ||
264 | |||
265 | tspi->cur_speed = speed; | ||
266 | |||
267 | val = spi_tegra_readl(tspi, SLINK_COMMAND2); | ||
268 | val &= ~SLINK_SS_EN_CS(~0) | SLINK_RXEN | SLINK_TXEN; | ||
269 | if (t->rx_buf) | ||
270 | val |= SLINK_RXEN; | ||
271 | if (t->tx_buf) | ||
272 | val |= SLINK_TXEN; | ||
273 | val |= SLINK_SS_EN_CS(spi->chip_select); | ||
274 | val |= SLINK_SPIE; | ||
275 | spi_tegra_writel(tspi, val, SLINK_COMMAND2); | ||
276 | |||
277 | val = spi_tegra_readl(tspi, SLINK_COMMAND); | ||
278 | val &= ~SLINK_BIT_LENGTH(~0); | ||
279 | val |= SLINK_BIT_LENGTH(bits_per_word - 1); | ||
280 | |||
281 | /* FIXME: should probably control CS manually so that we can be sure | ||
282 | * it does not go low between transfer and to support delay_usecs | ||
283 | * correctly. | ||
284 | */ | ||
285 | val &= ~SLINK_IDLE_SCLK_MASK & ~SLINK_CK_SDA & ~SLINK_CS_SW; | ||
286 | |||
287 | if (spi->mode & SPI_CPHA) | ||
288 | val |= SLINK_CK_SDA; | ||
289 | |||
290 | if (spi->mode & SPI_CPOL) | ||
291 | val |= SLINK_IDLE_SCLK_DRIVE_HIGH; | ||
292 | else | ||
293 | val |= SLINK_IDLE_SCLK_DRIVE_LOW; | ||
294 | |||
295 | val |= SLINK_M_S; | ||
296 | |||
297 | spi_tegra_writel(tspi, val, SLINK_COMMAND); | ||
298 | |||
299 | spi_tegra_writel(tspi, SLINK_RX_FLUSH | SLINK_TX_FLUSH, SLINK_STATUS); | ||
300 | |||
301 | tspi->cur = t; | ||
302 | tspi->cur_pos = 0; | ||
303 | tspi->cur_len = spi_tegra_fill_tx_fifo(tspi, t); | ||
304 | |||
305 | spi_tegra_go(tspi); | ||
306 | } | ||
307 | |||
308 | static void spi_tegra_start_message(struct spi_device *spi, | ||
309 | struct spi_message *m) | ||
310 | { | ||
311 | struct spi_transfer *t; | ||
312 | |||
313 | m->actual_length = 0; | ||
314 | m->status = 0; | ||
315 | |||
316 | t = list_first_entry(&m->transfers, struct spi_transfer, transfer_list); | ||
317 | spi_tegra_start_transfer(spi, t); | ||
318 | } | ||
319 | |||
320 | static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req) | ||
321 | { | ||
322 | struct spi_tegra_data *tspi = req->dev; | ||
323 | unsigned long flags; | ||
324 | struct spi_message *m; | ||
325 | struct spi_device *spi; | ||
326 | int timeout = 0; | ||
327 | unsigned long val; | ||
328 | |||
329 | /* the SPI controller may come back with both the BSY and RDY bits | ||
330 | * set. In this case we need to wait for the BSY bit to clear so | ||
331 | * that we are sure the DMA is finished. 1000 reads was empirically | ||
332 | * determined to be long enough. | ||
333 | */ | ||
334 | while (timeout++ < 1000) { | ||
335 | if (!(spi_tegra_readl(tspi, SLINK_STATUS) & SLINK_BSY)) | ||
336 | break; | ||
337 | } | ||
338 | |||
339 | spin_lock_irqsave(&tspi->lock, flags); | ||
340 | |||
341 | val = spi_tegra_readl(tspi, SLINK_STATUS); | ||
342 | val |= SLINK_RDY; | ||
343 | spi_tegra_writel(tspi, val, SLINK_STATUS); | ||
344 | |||
345 | m = list_first_entry(&tspi->queue, struct spi_message, queue); | ||
346 | |||
347 | if (timeout >= 1000) | ||
348 | m->status = -EIO; | ||
349 | |||
350 | spi = m->state; | ||
351 | |||
352 | tspi->cur_pos += spi_tegra_drain_rx_fifo(tspi, tspi->cur); | ||
353 | m->actual_length += tspi->cur_pos; | ||
354 | |||
355 | if (tspi->cur_pos < tspi->cur->len) { | ||
356 | tspi->cur_len = spi_tegra_fill_tx_fifo(tspi, tspi->cur); | ||
357 | spi_tegra_go(tspi); | ||
358 | } else if (!list_is_last(&tspi->cur->transfer_list, | ||
359 | &m->transfers)) { | ||
360 | tspi->cur = list_first_entry(&tspi->cur->transfer_list, | ||
361 | struct spi_transfer, | ||
362 | transfer_list); | ||
363 | spi_tegra_start_transfer(spi, tspi->cur); | ||
364 | } else { | ||
365 | list_del(&m->queue); | ||
366 | |||
367 | m->complete(m->context); | ||
368 | |||
369 | if (!list_empty(&tspi->queue)) { | ||
370 | m = list_first_entry(&tspi->queue, struct spi_message, | ||
371 | queue); | ||
372 | spi = m->state; | ||
373 | spi_tegra_start_message(spi, m); | ||
374 | } else { | ||
375 | clk_disable(tspi->clk); | ||
376 | tspi->cur_speed = 0; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | spin_unlock_irqrestore(&tspi->lock, flags); | ||
381 | } | ||
382 | |||
383 | static int spi_tegra_setup(struct spi_device *spi) | ||
384 | { | ||
385 | struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); | ||
386 | unsigned long cs_bit; | ||
387 | unsigned long val; | ||
388 | unsigned long flags; | ||
389 | |||
390 | dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n", | ||
391 | spi->bits_per_word, | ||
392 | spi->mode & SPI_CPOL ? "" : "~", | ||
393 | spi->mode & SPI_CPHA ? "" : "~", | ||
394 | spi->max_speed_hz); | ||
395 | |||
396 | |||
397 | switch (spi->chip_select) { | ||
398 | case 0: | ||
399 | cs_bit = SLINK_CS_POLARITY; | ||
400 | break; | ||
401 | |||
402 | case 1: | ||
403 | cs_bit = SLINK_CS_POLARITY1; | ||
404 | break; | ||
405 | |||
406 | case 2: | ||
407 | cs_bit = SLINK_CS_POLARITY2; | ||
408 | break; | ||
409 | |||
410 | case 4: | ||
411 | cs_bit = SLINK_CS_POLARITY3; | ||
412 | break; | ||
413 | |||
414 | default: | ||
415 | return -EINVAL; | ||
416 | } | ||
417 | |||
418 | spin_lock_irqsave(&tspi->lock, flags); | ||
419 | |||
420 | val = spi_tegra_readl(tspi, SLINK_COMMAND); | ||
421 | if (spi->mode & SPI_CS_HIGH) | ||
422 | val |= cs_bit; | ||
423 | else | ||
424 | val &= ~cs_bit; | ||
425 | spi_tegra_writel(tspi, val, SLINK_COMMAND); | ||
426 | |||
427 | spin_unlock_irqrestore(&tspi->lock, flags); | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static int spi_tegra_transfer(struct spi_device *spi, struct spi_message *m) | ||
433 | { | ||
434 | struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); | ||
435 | struct spi_transfer *t; | ||
436 | unsigned long flags; | ||
437 | int was_empty; | ||
438 | |||
439 | if (list_empty(&m->transfers) || !m->complete) | ||
440 | return -EINVAL; | ||
441 | |||
442 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
443 | if (t->bits_per_word < 0 || t->bits_per_word > 32) | ||
444 | return -EINVAL; | ||
445 | |||
446 | if (t->len == 0) | ||
447 | return -EINVAL; | ||
448 | |||
449 | if (!t->rx_buf && !t->tx_buf) | ||
450 | return -EINVAL; | ||
451 | } | ||
452 | |||
453 | m->state = spi; | ||
454 | |||
455 | spin_lock_irqsave(&tspi->lock, flags); | ||
456 | was_empty = list_empty(&tspi->queue); | ||
457 | list_add_tail(&m->queue, &tspi->queue); | ||
458 | |||
459 | if (was_empty) | ||
460 | spi_tegra_start_message(spi, m); | ||
461 | |||
462 | spin_unlock_irqrestore(&tspi->lock, flags); | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int __init spi_tegra_probe(struct platform_device *pdev) | ||
468 | { | ||
469 | struct spi_master *master; | ||
470 | struct spi_tegra_data *tspi; | ||
471 | struct resource *r; | ||
472 | int ret; | ||
473 | |||
474 | master = spi_alloc_master(&pdev->dev, sizeof *tspi); | ||
475 | if (master == NULL) { | ||
476 | dev_err(&pdev->dev, "master allocation failed\n"); | ||
477 | return -ENOMEM; | ||
478 | } | ||
479 | |||
480 | /* the spi->mode bits understood by this driver: */ | ||
481 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | ||
482 | |||
483 | master->bus_num = pdev->id; | ||
484 | |||
485 | master->setup = spi_tegra_setup; | ||
486 | master->transfer = spi_tegra_transfer; | ||
487 | master->num_chipselect = 4; | ||
488 | |||
489 | dev_set_drvdata(&pdev->dev, master); | ||
490 | tspi = spi_master_get_devdata(master); | ||
491 | tspi->master = master; | ||
492 | tspi->pdev = pdev; | ||
493 | spin_lock_init(&tspi->lock); | ||
494 | |||
495 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
496 | if (r == NULL) { | ||
497 | ret = -ENODEV; | ||
498 | goto err0; | ||
499 | } | ||
500 | |||
501 | if (!request_mem_region(r->start, (r->end - r->start) + 1, | ||
502 | dev_name(&pdev->dev))) { | ||
503 | ret = -EBUSY; | ||
504 | goto err0; | ||
505 | } | ||
506 | |||
507 | tspi->phys = r->start; | ||
508 | tspi->base = ioremap(r->start, r->end - r->start + 1); | ||
509 | if (!tspi->base) { | ||
510 | dev_err(&pdev->dev, "can't ioremap iomem\n"); | ||
511 | ret = -ENOMEM; | ||
512 | goto err1; | ||
513 | } | ||
514 | |||
515 | tspi->clk = clk_get(&pdev->dev, NULL); | ||
516 | if (IS_ERR_OR_NULL(tspi->clk)) { | ||
517 | dev_err(&pdev->dev, "can not get clock\n"); | ||
518 | ret = PTR_ERR(tspi->clk); | ||
519 | goto err2; | ||
520 | } | ||
521 | |||
522 | INIT_LIST_HEAD(&tspi->queue); | ||
523 | |||
524 | tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT); | ||
525 | if (!tspi->rx_dma) { | ||
526 | dev_err(&pdev->dev, "can not allocate rx dma channel\n"); | ||
527 | ret = -ENODEV; | ||
528 | goto err3; | ||
529 | } | ||
530 | |||
531 | tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | ||
532 | &tspi->rx_bb_phys, GFP_KERNEL); | ||
533 | if (!tspi->rx_bb) { | ||
534 | dev_err(&pdev->dev, "can not allocate rx bounce buffer\n"); | ||
535 | ret = -ENOMEM; | ||
536 | goto err4; | ||
537 | } | ||
538 | |||
539 | tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete; | ||
540 | tspi->rx_dma_req.to_memory = 1; | ||
541 | tspi->rx_dma_req.dest_addr = tspi->rx_bb_phys; | ||
542 | tspi->rx_dma_req.dest_bus_width = 32; | ||
543 | tspi->rx_dma_req.source_addr = tspi->phys + SLINK_RX_FIFO; | ||
544 | tspi->rx_dma_req.source_bus_width = 32; | ||
545 | tspi->rx_dma_req.source_wrap = 4; | ||
546 | tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id]; | ||
547 | tspi->rx_dma_req.dev = tspi; | ||
548 | |||
549 | ret = spi_register_master(master); | ||
550 | |||
551 | if (ret < 0) | ||
552 | goto err5; | ||
553 | |||
554 | return ret; | ||
555 | |||
556 | err5: | ||
557 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | ||
558 | tspi->rx_bb, tspi->rx_bb_phys); | ||
559 | err4: | ||
560 | tegra_dma_free_channel(tspi->rx_dma); | ||
561 | err3: | ||
562 | clk_put(tspi->clk); | ||
563 | err2: | ||
564 | iounmap(tspi->base); | ||
565 | err1: | ||
566 | release_mem_region(r->start, (r->end - r->start) + 1); | ||
567 | err0: | ||
568 | spi_master_put(master); | ||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | static int __devexit spi_tegra_remove(struct platform_device *pdev) | ||
573 | { | ||
574 | struct spi_master *master; | ||
575 | struct spi_tegra_data *tspi; | ||
576 | struct resource *r; | ||
577 | |||
578 | master = dev_get_drvdata(&pdev->dev); | ||
579 | tspi = spi_master_get_devdata(master); | ||
580 | |||
581 | tegra_dma_free_channel(tspi->rx_dma); | ||
582 | |||
583 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | ||
584 | tspi->rx_bb, tspi->rx_bb_phys); | ||
585 | |||
586 | clk_put(tspi->clk); | ||
587 | iounmap(tspi->base); | ||
588 | |||
589 | spi_master_put(master); | ||
590 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
591 | release_mem_region(r->start, (r->end - r->start) + 1); | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | MODULE_ALIAS("platform:spi_tegra"); | ||
597 | |||
598 | static struct platform_driver spi_tegra_driver = { | ||
599 | .driver = { | ||
600 | .name = "spi_tegra", | ||
601 | .owner = THIS_MODULE, | ||
602 | }, | ||
603 | .remove = __devexit_p(spi_tegra_remove), | ||
604 | }; | ||
605 | |||
606 | static int __init spi_tegra_init(void) | ||
607 | { | ||
608 | return platform_driver_probe(&spi_tegra_driver, spi_tegra_probe); | ||
609 | } | ||
610 | module_init(spi_tegra_init); | ||
611 | |||
612 | static void __exit spi_tegra_exit(void) | ||
613 | { | ||
614 | platform_driver_unregister(&spi_tegra_driver); | ||
615 | } | ||
616 | module_exit(spi_tegra_exit); | ||
617 | |||
618 | MODULE_LICENSE("GPL"); | ||