aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-sun4i.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2014-02-22 16:35:53 -0500
committerMark Brown <broonie@linaro.org>2014-02-22 21:14:46 -0500
commitb5f6517948cce50bde9aa441b4f00b63518f6421 (patch)
treec7a186b7fde8ff8b41f52e23db38ad24377b4297 /drivers/spi/spi-sun4i.c
parentd31ad46f58e89fdb9f5b902aa7cc29689e123dde (diff)
spi: sunxi: Add Allwinner A10 SPI controller driver
The older Allwinner SoCs (A10, A13, A10s and A20) all have the same SPI controller. Unfortunately, this SPI controller, even though quite similar, is significantly different from the recently supported A31 SPI controller (different registers offset, split/merged registers, etc.). Supporting both controllers in a single driver would be unreasonable, hence the addition of a new driver. Like its more recent counterpart, it supports DMA, but the driver only does PIO until we have a dmaengine driver for this platform. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-sun4i.c')
-rw-r--r--drivers/spi/spi-sun4i.c477
1 files changed, 477 insertions, 0 deletions
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
new file mode 100644
index 000000000000..3f82705d0a27
--- /dev/null
+++ b/drivers/spi/spi-sun4i.c
@@ -0,0 +1,477 @@
1/*
2 * Copyright (C) 2012 - 2014 Allwinner Tech
3 * Pan Nan <pannan@allwinnertech.com>
4 *
5 * Copyright (C) 2014 Maxime Ripard
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/workqueue.h>
23
24#include <linux/spi/spi.h>
25
26#define SUN4I_FIFO_DEPTH 64
27
28#define SUN4I_RXDATA_REG 0x00
29
30#define SUN4I_TXDATA_REG 0x04
31
32#define SUN4I_CTL_REG 0x08
33#define SUN4I_CTL_ENABLE BIT(0)
34#define SUN4I_CTL_MASTER BIT(1)
35#define SUN4I_CTL_CPHA BIT(2)
36#define SUN4I_CTL_CPOL BIT(3)
37#define SUN4I_CTL_CS_ACTIVE_LOW BIT(4)
38#define SUN4I_CTL_LMTF BIT(6)
39#define SUN4I_CTL_TF_RST BIT(8)
40#define SUN4I_CTL_RF_RST BIT(9)
41#define SUN4I_CTL_XCH BIT(10)
42#define SUN4I_CTL_CS_MASK 0x3000
43#define SUN4I_CTL_CS(cs) (((cs) << 12) & SUN4I_CTL_CS_MASK)
44#define SUN4I_CTL_DHB BIT(15)
45#define SUN4I_CTL_CS_MANUAL BIT(16)
46#define SUN4I_CTL_CS_LEVEL BIT(17)
47#define SUN4I_CTL_TP BIT(18)
48
49#define SUN4I_INT_CTL_REG 0x0c
50#define SUN4I_INT_CTL_TC BIT(16)
51
52#define SUN4I_INT_STA_REG 0x10
53
54#define SUN4I_DMA_CTL_REG 0x14
55
56#define SUN4I_WAIT_REG 0x18
57
58#define SUN4I_CLK_CTL_REG 0x1c
59#define SUN4I_CLK_CTL_CDR2_MASK 0xff
60#define SUN4I_CLK_CTL_CDR2(div) ((div) & SUN4I_CLK_CTL_CDR2_MASK)
61#define SUN4I_CLK_CTL_CDR1_MASK 0xf
62#define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
63#define SUN4I_CLK_CTL_DRS BIT(12)
64
65#define SUN4I_BURST_CNT_REG 0x20
66#define SUN4I_BURST_CNT(cnt) ((cnt) & 0xffffff)
67
68#define SUN4I_XMIT_CNT_REG 0x24
69#define SUN4I_XMIT_CNT(cnt) ((cnt) & 0xffffff)
70
71#define SUN4I_FIFO_STA_REG 0x28
72#define SUN4I_FIFO_STA_RF_CNT_MASK 0x7f
73#define SUN4I_FIFO_STA_RF_CNT_BITS 0
74#define SUN4I_FIFO_STA_TF_CNT_MASK 0x7f
75#define SUN4I_FIFO_STA_TF_CNT_BITS 16
76
77struct sun4i_spi {
78 struct spi_master *master;
79 void __iomem *base_addr;
80 struct clk *hclk;
81 struct clk *mclk;
82
83 struct completion done;
84
85 const u8 *tx_buf;
86 u8 *rx_buf;
87 int len;
88};
89
90static inline u32 sun4i_spi_read(struct sun4i_spi *sspi, u32 reg)
91{
92 return readl(sspi->base_addr + reg);
93}
94
95static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value)
96{
97 writel(value, sspi->base_addr + reg);
98}
99
100static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len)
101{
102 u32 reg, cnt;
103 u8 byte;
104
105 /* See how much data is available */
106 reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG);
107 reg &= SUN4I_FIFO_STA_RF_CNT_MASK;
108 cnt = reg >> SUN4I_FIFO_STA_RF_CNT_BITS;
109
110 if (len > cnt)
111 len = cnt;
112
113 while (len--) {
114 byte = readb(sspi->base_addr + SUN4I_RXDATA_REG);
115 if (sspi->rx_buf)
116 *sspi->rx_buf++ = byte;
117 }
118}
119
120static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len)
121{
122 u8 byte;
123
124 if (len > sspi->len)
125 len = sspi->len;
126
127 while (len--) {
128 byte = sspi->tx_buf ? *sspi->tx_buf++ : 0;
129 writeb(byte, sspi->base_addr + SUN4I_TXDATA_REG);
130 sspi->len--;
131 }
132}
133
134static void sun4i_spi_set_cs(struct spi_device *spi, bool enable)
135{
136 struct sun4i_spi *sspi = spi_master_get_devdata(spi->master);
137 u32 reg;
138
139 reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
140
141 reg &= ~SUN4I_CTL_CS_MASK;
142 reg |= SUN4I_CTL_CS(spi->chip_select);
143
144 if (enable)
145 reg |= SUN4I_CTL_CS_LEVEL;
146 else
147 reg &= ~SUN4I_CTL_CS_LEVEL;
148
149 /*
150 * Even though this looks irrelevant since we are supposed to
151 * be controlling the chip select manually, this bit also
152 * controls the levels of the chip select for inactive
153 * devices.
154 *
155 * If we don't set it, the chip select level will go low by
156 * default when the device is idle, which is not really
157 * expected in the common case where the chip select is active
158 * low.
159 */
160 if (spi->mode & SPI_CS_HIGH)
161 reg &= ~SUN4I_CTL_CS_ACTIVE_LOW;
162 else
163 reg |= SUN4I_CTL_CS_ACTIVE_LOW;
164
165 sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
166}
167
168static int sun4i_spi_transfer_one(struct spi_master *master,
169 struct spi_device *spi,
170 struct spi_transfer *tfr)
171{
172 struct sun4i_spi *sspi = spi_master_get_devdata(master);
173 unsigned int mclk_rate, div, timeout;
174 unsigned int tx_len = 0;
175 int ret = 0;
176 u32 reg;
177
178 /* We don't support transfer larger than the FIFO */
179 if (tfr->len > SUN4I_FIFO_DEPTH)
180 return -EINVAL;
181
182 reinit_completion(&sspi->done);
183 sspi->tx_buf = tfr->tx_buf;
184 sspi->rx_buf = tfr->rx_buf;
185 sspi->len = tfr->len;
186
187 /* Clear pending interrupts */
188 sun4i_spi_write(sspi, SUN4I_INT_STA_REG, ~0);
189
190
191 reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
192
193 /* Reset FIFOs */
194 sun4i_spi_write(sspi, SUN4I_CTL_REG,
195 reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST);
196
197 /*
198 * Setup the transfer control register: Chip Select,
199 * polarities, etc.
200 */
201 if (spi->mode & SPI_CPOL)
202 reg |= SUN4I_CTL_CPOL;
203 else
204 reg &= ~SUN4I_CTL_CPOL;
205
206 if (spi->mode & SPI_CPHA)
207 reg |= SUN4I_CTL_CPHA;
208 else
209 reg &= ~SUN4I_CTL_CPHA;
210
211 if (spi->mode & SPI_LSB_FIRST)
212 reg |= SUN4I_CTL_LMTF;
213 else
214 reg &= ~SUN4I_CTL_LMTF;
215
216
217 /*
218 * If it's a TX only transfer, we don't want to fill the RX
219 * FIFO with bogus data
220 */
221 if (sspi->rx_buf)
222 reg &= ~SUN4I_CTL_DHB;
223 else
224 reg |= SUN4I_CTL_DHB;
225
226 /* We want to control the chip select manually */
227 reg |= SUN4I_CTL_CS_MANUAL;
228
229 sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
230
231 /* Ensure that we have a parent clock fast enough */
232 mclk_rate = clk_get_rate(sspi->mclk);
233 if (mclk_rate < (2 * spi->max_speed_hz)) {
234 clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
235 mclk_rate = clk_get_rate(sspi->mclk);
236 }
237
238 /*
239 * Setup clock divider.
240 *
241 * We have two choices there. Either we can use the clock
242 * divide rate 1, which is calculated thanks to this formula:
243 * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1))
244 * Or we can use CDR2, which is calculated with the formula:
245 * SPI_CLK = MOD_CLK / (2 * (cdr + 1))
246 * Wether we use the former or the latter is set through the
247 * DRS bit.
248 *
249 * First try CDR2, and if we can't reach the expected
250 * frequency, fall back to CDR1.
251 */
252 div = mclk_rate / (2 * spi->max_speed_hz);
253 if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
254 if (div > 0)
255 div--;
256
257 reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
258 } else {
259 div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
260 reg = SUN4I_CLK_CTL_CDR1(div);
261 }
262
263 sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg);
264
265 /* Setup the transfer now... */
266 if (sspi->tx_buf)
267 tx_len = tfr->len;
268
269 /* Setup the counters */
270 sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
271 sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
272
273 /* Fill the TX FIFO */
274 sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
275
276 /* Enable the interrupts */
277 sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
278
279 /* Start the transfer */
280 reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
281 sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
282
283 timeout = wait_for_completion_timeout(&sspi->done,
284 msecs_to_jiffies(1000));
285 if (!timeout) {
286 ret = -ETIMEDOUT;
287 goto out;
288 }
289
290 sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
291
292out:
293 sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
294
295 return ret;
296}
297
298static irqreturn_t sun4i_spi_handler(int irq, void *dev_id)
299{
300 struct sun4i_spi *sspi = dev_id;
301 u32 status = sun4i_spi_read(sspi, SUN4I_INT_STA_REG);
302
303 /* Transfer complete */
304 if (status & SUN4I_INT_CTL_TC) {
305 sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC);
306 complete(&sspi->done);
307 return IRQ_HANDLED;
308 }
309
310 return IRQ_NONE;
311}
312
313static int sun4i_spi_runtime_resume(struct device *dev)
314{
315 struct spi_master *master = dev_get_drvdata(dev);
316 struct sun4i_spi *sspi = spi_master_get_devdata(master);
317 int ret;
318
319 ret = clk_prepare_enable(sspi->hclk);
320 if (ret) {
321 dev_err(dev, "Couldn't enable AHB clock\n");
322 goto out;
323 }
324
325 ret = clk_prepare_enable(sspi->mclk);
326 if (ret) {
327 dev_err(dev, "Couldn't enable module clock\n");
328 goto err;
329 }
330
331 sun4i_spi_write(sspi, SUN4I_CTL_REG,
332 SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP);
333
334 return 0;
335
336err:
337 clk_disable_unprepare(sspi->hclk);
338out:
339 return ret;
340}
341
342static int sun4i_spi_runtime_suspend(struct device *dev)
343{
344 struct spi_master *master = dev_get_drvdata(dev);
345 struct sun4i_spi *sspi = spi_master_get_devdata(master);
346
347 clk_disable_unprepare(sspi->mclk);
348 clk_disable_unprepare(sspi->hclk);
349
350 return 0;
351}
352
353static int sun4i_spi_probe(struct platform_device *pdev)
354{
355 struct spi_master *master;
356 struct sun4i_spi *sspi;
357 struct resource *res;
358 int ret = 0, irq;
359
360 master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi));
361 if (!master) {
362 dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
363 return -ENOMEM;
364 }
365
366 platform_set_drvdata(pdev, master);
367 sspi = spi_master_get_devdata(master);
368
369 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
370 sspi->base_addr = devm_ioremap_resource(&pdev->dev, res);
371 if (IS_ERR(sspi->base_addr)) {
372 ret = PTR_ERR(sspi->base_addr);
373 goto err_free_master;
374 }
375
376 irq = platform_get_irq(pdev, 0);
377 if (irq < 0) {
378 dev_err(&pdev->dev, "No spi IRQ specified\n");
379 ret = -ENXIO;
380 goto err_free_master;
381 }
382
383 ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler,
384 0, "sun4i-spi", sspi);
385 if (ret) {
386 dev_err(&pdev->dev, "Cannot request IRQ\n");
387 goto err_free_master;
388 }
389
390 sspi->master = master;
391 master->set_cs = sun4i_spi_set_cs;
392 master->transfer_one = sun4i_spi_transfer_one;
393 master->num_chipselect = 4;
394 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
395 master->dev.of_node = pdev->dev.of_node;
396 master->auto_runtime_pm = true;
397
398 sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
399 if (IS_ERR(sspi->hclk)) {
400 dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
401 ret = PTR_ERR(sspi->hclk);
402 goto err_free_master;
403 }
404
405 sspi->mclk = devm_clk_get(&pdev->dev, "mod");
406 if (IS_ERR(sspi->mclk)) {
407 dev_err(&pdev->dev, "Unable to acquire module clock\n");
408 ret = PTR_ERR(sspi->mclk);
409 goto err_free_master;
410 }
411
412 init_completion(&sspi->done);
413
414 /*
415 * This wake-up/shutdown pattern is to be able to have the
416 * device woken up, even if runtime_pm is disabled
417 */
418 ret = sun4i_spi_runtime_resume(&pdev->dev);
419 if (ret) {
420 dev_err(&pdev->dev, "Couldn't resume the device\n");
421 goto err_free_master;
422 }
423
424 pm_runtime_set_active(&pdev->dev);
425 pm_runtime_enable(&pdev->dev);
426 pm_runtime_idle(&pdev->dev);
427
428 ret = devm_spi_register_master(&pdev->dev, master);
429 if (ret) {
430 dev_err(&pdev->dev, "cannot register SPI master\n");
431 goto err_pm_disable;
432 }
433
434 return 0;
435
436err_pm_disable:
437 pm_runtime_disable(&pdev->dev);
438 sun4i_spi_runtime_suspend(&pdev->dev);
439err_free_master:
440 spi_master_put(master);
441 return ret;
442}
443
444static int sun4i_spi_remove(struct platform_device *pdev)
445{
446 pm_runtime_disable(&pdev->dev);
447
448 return 0;
449}
450
451static const struct of_device_id sun4i_spi_match[] = {
452 { .compatible = "allwinner,sun4i-a10-spi", },
453 {}
454};
455MODULE_DEVICE_TABLE(of, sun4i_spi_match);
456
457static const struct dev_pm_ops sun4i_spi_pm_ops = {
458 .runtime_resume = sun4i_spi_runtime_resume,
459 .runtime_suspend = sun4i_spi_runtime_suspend,
460};
461
462static struct platform_driver sun4i_spi_driver = {
463 .probe = sun4i_spi_probe,
464 .remove = sun4i_spi_remove,
465 .driver = {
466 .name = "sun4i-spi",
467 .owner = THIS_MODULE,
468 .of_match_table = sun4i_spi_match,
469 .pm = &sun4i_spi_pm_ops,
470 },
471};
472module_platform_driver(sun4i_spi_driver);
473
474MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>");
475MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
476MODULE_DESCRIPTION("Allwinner A1X/A20 SPI controller driver");
477MODULE_LICENSE("GPL");