]>
Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
3558fe90 MR |
2 | /* |
3 | * Copyright (C) 2012 - 2014 Allwinner Tech | |
4 | * Pan Nan <pannan@allwinnertech.com> | |
5 | * | |
6 | * Copyright (C) 2014 Maxime Ripard | |
7 | * Maxime Ripard <maxime.ripard@free-electrons.com> | |
3558fe90 MR |
8 | */ |
9 | ||
9a3ef9df | 10 | #include <linux/bitfield.h> |
3558fe90 MR |
11 | #include <linux/clk.h> |
12 | #include <linux/delay.h> | |
13 | #include <linux/device.h> | |
14 | #include <linux/interrupt.h> | |
15 | #include <linux/io.h> | |
16 | #include <linux/module.h> | |
10565dfd | 17 | #include <linux/of_device.h> |
3558fe90 MR |
18 | #include <linux/platform_device.h> |
19 | #include <linux/pm_runtime.h> | |
20 | #include <linux/reset.h> | |
3558fe90 MR |
21 | |
22 | #include <linux/spi/spi.h> | |
23 | ||
24 | #define SUN6I_FIFO_DEPTH 128 | |
10565dfd | 25 | #define SUN8I_FIFO_DEPTH 64 |
3558fe90 MR |
26 | |
27 | #define SUN6I_GBL_CTL_REG 0x04 | |
28 | #define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) | |
29 | #define SUN6I_GBL_CTL_MASTER BIT(1) | |
30 | #define SUN6I_GBL_CTL_TP BIT(7) | |
31 | #define SUN6I_GBL_CTL_RST BIT(31) | |
32 | ||
33 | #define SUN6I_TFR_CTL_REG 0x08 | |
34 | #define SUN6I_TFR_CTL_CPHA BIT(0) | |
35 | #define SUN6I_TFR_CTL_CPOL BIT(1) | |
36 | #define SUN6I_TFR_CTL_SPOL BIT(2) | |
d31ad46f AL |
37 | #define SUN6I_TFR_CTL_CS_MASK 0x30 |
38 | #define SUN6I_TFR_CTL_CS(cs) (((cs) << 4) & SUN6I_TFR_CTL_CS_MASK) | |
3558fe90 MR |
39 | #define SUN6I_TFR_CTL_CS_MANUAL BIT(6) |
40 | #define SUN6I_TFR_CTL_CS_LEVEL BIT(7) | |
41 | #define SUN6I_TFR_CTL_DHB BIT(8) | |
42 | #define SUN6I_TFR_CTL_FBS BIT(12) | |
43 | #define SUN6I_TFR_CTL_XCH BIT(31) | |
44 | ||
45 | #define SUN6I_INT_CTL_REG 0x10 | |
913f536c IZ |
46 | #define SUN6I_INT_CTL_RF_RDY BIT(0) |
47 | #define SUN6I_INT_CTL_TF_ERQ BIT(4) | |
3558fe90 MR |
48 | #define SUN6I_INT_CTL_RF_OVF BIT(8) |
49 | #define SUN6I_INT_CTL_TC BIT(12) | |
50 | ||
51 | #define SUN6I_INT_STA_REG 0x14 | |
52 | ||
53 | #define SUN6I_FIFO_CTL_REG 0x18 | |
913f536c IZ |
54 | #define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_MASK 0xff |
55 | #define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS 0 | |
3558fe90 | 56 | #define SUN6I_FIFO_CTL_RF_RST BIT(15) |
913f536c IZ |
57 | #define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_MASK 0xff |
58 | #define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS 16 | |
3558fe90 MR |
59 | #define SUN6I_FIFO_CTL_TF_RST BIT(31) |
60 | ||
61 | #define SUN6I_FIFO_STA_REG 0x1c | |
5197da03 | 62 | #define SUN6I_FIFO_STA_RF_CNT_MASK GENMASK(7, 0) |
9a3ef9df | 63 | #define SUN6I_FIFO_STA_TF_CNT_MASK GENMASK(23, 16) |
3558fe90 MR |
64 | |
65 | #define SUN6I_CLK_CTL_REG 0x24 | |
66 | #define SUN6I_CLK_CTL_CDR2_MASK 0xff | |
67 | #define SUN6I_CLK_CTL_CDR2(div) (((div) & SUN6I_CLK_CTL_CDR2_MASK) << 0) | |
68 | #define SUN6I_CLK_CTL_CDR1_MASK 0xf | |
69 | #define SUN6I_CLK_CTL_CDR1(div) (((div) & SUN6I_CLK_CTL_CDR1_MASK) << 8) | |
70 | #define SUN6I_CLK_CTL_DRS BIT(12) | |
71 | ||
913f536c IZ |
72 | #define SUN6I_MAX_XFER_SIZE 0xffffff |
73 | ||
3558fe90 | 74 | #define SUN6I_BURST_CNT_REG 0x30 |
3558fe90 MR |
75 | |
76 | #define SUN6I_XMIT_CNT_REG 0x34 | |
3558fe90 MR |
77 | |
78 | #define SUN6I_BURST_CTL_CNT_REG 0x38 | |
3558fe90 MR |
79 | |
80 | #define SUN6I_TXDATA_REG 0x200 | |
81 | #define SUN6I_RXDATA_REG 0x300 | |
82 | ||
83 | struct sun6i_spi { | |
84 | struct spi_master *master; | |
85 | void __iomem *base_addr; | |
86 | struct clk *hclk; | |
87 | struct clk *mclk; | |
88 | struct reset_control *rstc; | |
89 | ||
90 | struct completion done; | |
91 | ||
92 | const u8 *tx_buf; | |
93 | u8 *rx_buf; | |
94 | int len; | |
10565dfd | 95 | unsigned long fifo_depth; |
3558fe90 MR |
96 | }; |
97 | ||
98 | static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) | |
99 | { | |
100 | return readl(sspi->base_addr + reg); | |
101 | } | |
102 | ||
103 | static inline void sun6i_spi_write(struct sun6i_spi *sspi, u32 reg, u32 value) | |
104 | { | |
105 | writel(value, sspi->base_addr + reg); | |
106 | } | |
107 | ||
5197da03 MKB |
108 | static inline u32 sun6i_spi_get_rx_fifo_count(struct sun6i_spi *sspi) |
109 | { | |
110 | u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG); | |
111 | ||
112 | return FIELD_GET(SUN6I_FIFO_STA_RF_CNT_MASK, reg); | |
113 | } | |
114 | ||
913f536c IZ |
115 | static inline u32 sun6i_spi_get_tx_fifo_count(struct sun6i_spi *sspi) |
116 | { | |
117 | u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG); | |
118 | ||
9a3ef9df | 119 | return FIELD_GET(SUN6I_FIFO_STA_TF_CNT_MASK, reg); |
913f536c IZ |
120 | } |
121 | ||
913f536c IZ |
122 | static inline void sun6i_spi_disable_interrupt(struct sun6i_spi *sspi, u32 mask) |
123 | { | |
124 | u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG); | |
125 | ||
126 | reg &= ~mask; | |
127 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg); | |
128 | } | |
129 | ||
92a52ee8 | 130 | static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi) |
3558fe90 | 131 | { |
92a52ee8 | 132 | u32 len; |
3558fe90 MR |
133 | u8 byte; |
134 | ||
135 | /* See how much data is available */ | |
92a52ee8 | 136 | len = sun6i_spi_get_rx_fifo_count(sspi); |
3558fe90 MR |
137 | |
138 | while (len--) { | |
139 | byte = readb(sspi->base_addr + SUN6I_RXDATA_REG); | |
140 | if (sspi->rx_buf) | |
141 | *sspi->rx_buf++ = byte; | |
142 | } | |
143 | } | |
144 | ||
e4e8ca3f | 145 | static inline void sun6i_spi_fill_fifo(struct sun6i_spi *sspi) |
3558fe90 | 146 | { |
913f536c | 147 | u32 cnt; |
e4e8ca3f | 148 | int len; |
3558fe90 MR |
149 | u8 byte; |
150 | ||
913f536c IZ |
151 | /* See how much data we can fit */ |
152 | cnt = sspi->fifo_depth - sun6i_spi_get_tx_fifo_count(sspi); | |
153 | ||
e4e8ca3f | 154 | len = min((int)cnt, sspi->len); |
3558fe90 MR |
155 | |
156 | while (len--) { | |
157 | byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; | |
158 | writeb(byte, sspi->base_addr + SUN6I_TXDATA_REG); | |
159 | sspi->len--; | |
160 | } | |
161 | } | |
162 | ||
163 | static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) | |
164 | { | |
165 | struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); | |
166 | u32 reg; | |
167 | ||
168 | reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); | |
169 | reg &= ~SUN6I_TFR_CTL_CS_MASK; | |
170 | reg |= SUN6I_TFR_CTL_CS(spi->chip_select); | |
171 | ||
172 | if (enable) | |
173 | reg |= SUN6I_TFR_CTL_CS_LEVEL; | |
174 | else | |
175 | reg &= ~SUN6I_TFR_CTL_CS_LEVEL; | |
176 | ||
177 | sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); | |
178 | } | |
179 | ||
794912cf MS |
180 | static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) |
181 | { | |
3288d5cb | 182 | return SUN6I_MAX_XFER_SIZE - 1; |
794912cf | 183 | } |
3558fe90 MR |
184 | |
185 | static int sun6i_spi_transfer_one(struct spi_master *master, | |
186 | struct spi_device *spi, | |
187 | struct spi_transfer *tfr) | |
188 | { | |
189 | struct sun6i_spi *sspi = spi_master_get_devdata(master); | |
ed7815db | 190 | unsigned int mclk_rate, div, div_cdr1, div_cdr2, timeout; |
719bd654 | 191 | unsigned int start, end, tx_time; |
913f536c | 192 | unsigned int trig_level; |
7716fa80 | 193 | unsigned int tx_len = 0, rx_len = 0; |
3558fe90 MR |
194 | int ret = 0; |
195 | u32 reg; | |
196 | ||
913f536c | 197 | if (tfr->len > SUN6I_MAX_XFER_SIZE) |
3558fe90 MR |
198 | return -EINVAL; |
199 | ||
200 | reinit_completion(&sspi->done); | |
201 | sspi->tx_buf = tfr->tx_buf; | |
202 | sspi->rx_buf = tfr->rx_buf; | |
203 | sspi->len = tfr->len; | |
204 | ||
205 | /* Clear pending interrupts */ | |
206 | sun6i_spi_write(sspi, SUN6I_INT_STA_REG, ~0); | |
207 | ||
208 | /* Reset FIFO */ | |
209 | sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, | |
210 | SUN6I_FIFO_CTL_RF_RST | SUN6I_FIFO_CTL_TF_RST); | |
211 | ||
913f536c IZ |
212 | /* |
213 | * Setup FIFO interrupt trigger level | |
214 | * Here we choose 3/4 of the full fifo depth, as it's the hardcoded | |
215 | * value used in old generation of Allwinner SPI controller. | |
216 | * (See spi-sun4i.c) | |
217 | */ | |
218 | trig_level = sspi->fifo_depth / 4 * 3; | |
219 | sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, | |
220 | (trig_level << SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS) | | |
221 | (trig_level << SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS)); | |
222 | ||
3558fe90 MR |
223 | /* |
224 | * Setup the transfer control register: Chip Select, | |
225 | * polarities, etc. | |
226 | */ | |
227 | reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); | |
228 | ||
229 | if (spi->mode & SPI_CPOL) | |
230 | reg |= SUN6I_TFR_CTL_CPOL; | |
231 | else | |
232 | reg &= ~SUN6I_TFR_CTL_CPOL; | |
233 | ||
234 | if (spi->mode & SPI_CPHA) | |
235 | reg |= SUN6I_TFR_CTL_CPHA; | |
236 | else | |
237 | reg &= ~SUN6I_TFR_CTL_CPHA; | |
238 | ||
239 | if (spi->mode & SPI_LSB_FIRST) | |
240 | reg |= SUN6I_TFR_CTL_FBS; | |
241 | else | |
242 | reg &= ~SUN6I_TFR_CTL_FBS; | |
243 | ||
244 | /* | |
245 | * If it's a TX only transfer, we don't want to fill the RX | |
246 | * FIFO with bogus data | |
247 | */ | |
7716fa80 | 248 | if (sspi->rx_buf) { |
3558fe90 | 249 | reg &= ~SUN6I_TFR_CTL_DHB; |
7716fa80 MKB |
250 | rx_len = tfr->len; |
251 | } else { | |
3558fe90 | 252 | reg |= SUN6I_TFR_CTL_DHB; |
7716fa80 | 253 | } |
3558fe90 MR |
254 | |
255 | /* We want to control the chip select manually */ | |
256 | reg |= SUN6I_TFR_CTL_CS_MANUAL; | |
257 | ||
258 | sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); | |
259 | ||
260 | /* Ensure that we have a parent clock fast enough */ | |
261 | mclk_rate = clk_get_rate(sspi->mclk); | |
47284e3e MW |
262 | if (mclk_rate < (2 * tfr->speed_hz)) { |
263 | clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); | |
3558fe90 MR |
264 | mclk_rate = clk_get_rate(sspi->mclk); |
265 | } | |
266 | ||
267 | /* | |
268 | * Setup clock divider. | |
269 | * | |
270 | * We have two choices there. Either we can use the clock | |
271 | * divide rate 1, which is calculated thanks to this formula: | |
272 | * SPI_CLK = MOD_CLK / (2 ^ cdr) | |
273 | * Or we can use CDR2, which is calculated with the formula: | |
274 | * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) | |
275 | * Wether we use the former or the latter is set through the | |
276 | * DRS bit. | |
277 | * | |
278 | * First try CDR2, and if we can't reach the expected | |
279 | * frequency, fall back to CDR1. | |
280 | */ | |
ed7815db MKB |
281 | div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz); |
282 | div_cdr2 = DIV_ROUND_UP(div_cdr1, 2); | |
283 | if (div_cdr2 <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { | |
284 | reg = SUN6I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN6I_CLK_CTL_DRS; | |
0bc7b8a2 | 285 | tfr->effective_speed_hz = mclk_rate / (2 * div_cdr2); |
3558fe90 | 286 | } else { |
ed7815db | 287 | div = min(SUN6I_CLK_CTL_CDR1_MASK, order_base_2(div_cdr1)); |
3558fe90 | 288 | reg = SUN6I_CLK_CTL_CDR1(div); |
0bc7b8a2 | 289 | tfr->effective_speed_hz = mclk_rate / (1 << div); |
3558fe90 MR |
290 | } |
291 | ||
292 | sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); | |
293 | ||
294 | /* Setup the transfer now... */ | |
295 | if (sspi->tx_buf) | |
296 | tx_len = tfr->len; | |
297 | ||
298 | /* Setup the counters */ | |
2130be57 MKB |
299 | sun6i_spi_write(sspi, SUN6I_BURST_CNT_REG, tfr->len); |
300 | sun6i_spi_write(sspi, SUN6I_XMIT_CNT_REG, tx_len); | |
301 | sun6i_spi_write(sspi, SUN6I_BURST_CTL_CNT_REG, tx_len); | |
3558fe90 MR |
302 | |
303 | /* Fill the TX FIFO */ | |
e4e8ca3f | 304 | sun6i_spi_fill_fifo(sspi); |
3558fe90 MR |
305 | |
306 | /* Enable the interrupts */ | |
7716fa80 | 307 | reg = SUN6I_INT_CTL_TC; |
4e7390e9 | 308 | |
7716fa80 MKB |
309 | if (rx_len > sspi->fifo_depth) |
310 | reg |= SUN6I_INT_CTL_RF_RDY; | |
913f536c | 311 | if (tx_len > sspi->fifo_depth) |
4e7390e9 MKB |
312 | reg |= SUN6I_INT_CTL_TF_ERQ; |
313 | ||
314 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg); | |
3558fe90 MR |
315 | |
316 | /* Start the transfer */ | |
317 | reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); | |
318 | sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); | |
319 | ||
719bd654 MS |
320 | tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); |
321 | start = jiffies; | |
3558fe90 | 322 | timeout = wait_for_completion_timeout(&sspi->done, |
719bd654 MS |
323 | msecs_to_jiffies(tx_time)); |
324 | end = jiffies; | |
3558fe90 | 325 | if (!timeout) { |
719bd654 MS |
326 | dev_warn(&master->dev, |
327 | "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", | |
328 | dev_name(&spi->dev), tfr->len, tfr->speed_hz, | |
329 | jiffies_to_msecs(end - start), tx_time); | |
3558fe90 | 330 | ret = -ETIMEDOUT; |
3558fe90 MR |
331 | } |
332 | ||
3558fe90 MR |
333 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); |
334 | ||
335 | return ret; | |
336 | } | |
337 | ||
338 | static irqreturn_t sun6i_spi_handler(int irq, void *dev_id) | |
339 | { | |
340 | struct sun6i_spi *sspi = dev_id; | |
341 | u32 status = sun6i_spi_read(sspi, SUN6I_INT_STA_REG); | |
342 | ||
343 | /* Transfer complete */ | |
344 | if (status & SUN6I_INT_CTL_TC) { | |
345 | sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); | |
92a52ee8 | 346 | sun6i_spi_drain_fifo(sspi); |
3558fe90 MR |
347 | complete(&sspi->done); |
348 | return IRQ_HANDLED; | |
349 | } | |
350 | ||
913f536c IZ |
351 | /* Receive FIFO 3/4 full */ |
352 | if (status & SUN6I_INT_CTL_RF_RDY) { | |
92a52ee8 | 353 | sun6i_spi_drain_fifo(sspi); |
913f536c IZ |
354 | /* Only clear the interrupt _after_ draining the FIFO */ |
355 | sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_RF_RDY); | |
356 | return IRQ_HANDLED; | |
357 | } | |
358 | ||
359 | /* Transmit FIFO 3/4 empty */ | |
360 | if (status & SUN6I_INT_CTL_TF_ERQ) { | |
e4e8ca3f | 361 | sun6i_spi_fill_fifo(sspi); |
913f536c IZ |
362 | |
363 | if (!sspi->len) | |
364 | /* nothing left to transmit */ | |
365 | sun6i_spi_disable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ); | |
366 | ||
367 | /* Only clear the interrupt _after_ re-seeding the FIFO */ | |
368 | sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TF_ERQ); | |
369 | ||
370 | return IRQ_HANDLED; | |
371 | } | |
372 | ||
3558fe90 MR |
373 | return IRQ_NONE; |
374 | } | |
375 | ||
376 | static int sun6i_spi_runtime_resume(struct device *dev) | |
377 | { | |
378 | struct spi_master *master = dev_get_drvdata(dev); | |
379 | struct sun6i_spi *sspi = spi_master_get_devdata(master); | |
380 | int ret; | |
381 | ||
382 | ret = clk_prepare_enable(sspi->hclk); | |
383 | if (ret) { | |
384 | dev_err(dev, "Couldn't enable AHB clock\n"); | |
385 | goto out; | |
386 | } | |
387 | ||
388 | ret = clk_prepare_enable(sspi->mclk); | |
389 | if (ret) { | |
390 | dev_err(dev, "Couldn't enable module clock\n"); | |
391 | goto err; | |
392 | } | |
393 | ||
394 | ret = reset_control_deassert(sspi->rstc); | |
395 | if (ret) { | |
396 | dev_err(dev, "Couldn't deassert the device from reset\n"); | |
397 | goto err2; | |
398 | } | |
399 | ||
400 | sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, | |
401 | SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); | |
402 | ||
403 | return 0; | |
404 | ||
405 | err2: | |
406 | clk_disable_unprepare(sspi->mclk); | |
407 | err: | |
408 | clk_disable_unprepare(sspi->hclk); | |
409 | out: | |
410 | return ret; | |
411 | } | |
412 | ||
413 | static int sun6i_spi_runtime_suspend(struct device *dev) | |
414 | { | |
415 | struct spi_master *master = dev_get_drvdata(dev); | |
416 | struct sun6i_spi *sspi = spi_master_get_devdata(master); | |
417 | ||
418 | reset_control_assert(sspi->rstc); | |
419 | clk_disable_unprepare(sspi->mclk); | |
420 | clk_disable_unprepare(sspi->hclk); | |
421 | ||
422 | return 0; | |
423 | } | |
424 | ||
425 | static int sun6i_spi_probe(struct platform_device *pdev) | |
426 | { | |
427 | struct spi_master *master; | |
428 | struct sun6i_spi *sspi; | |
3558fe90 MR |
429 | int ret = 0, irq; |
430 | ||
431 | master = spi_alloc_master(&pdev->dev, sizeof(struct sun6i_spi)); | |
432 | if (!master) { | |
433 | dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); | |
434 | return -ENOMEM; | |
435 | } | |
436 | ||
437 | platform_set_drvdata(pdev, master); | |
438 | sspi = spi_master_get_devdata(master); | |
439 | ||
7c7c31f7 | 440 | sspi->base_addr = devm_platform_ioremap_resource(pdev, 0); |
3558fe90 MR |
441 | if (IS_ERR(sspi->base_addr)) { |
442 | ret = PTR_ERR(sspi->base_addr); | |
443 | goto err_free_master; | |
444 | } | |
445 | ||
446 | irq = platform_get_irq(pdev, 0); | |
447 | if (irq < 0) { | |
3558fe90 MR |
448 | ret = -ENXIO; |
449 | goto err_free_master; | |
450 | } | |
451 | ||
452 | ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler, | |
453 | 0, "sun6i-spi", sspi); | |
454 | if (ret) { | |
455 | dev_err(&pdev->dev, "Cannot request IRQ\n"); | |
456 | goto err_free_master; | |
457 | } | |
458 | ||
459 | sspi->master = master; | |
10565dfd MK |
460 | sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev); |
461 | ||
0b06d8cf MS |
462 | master->max_speed_hz = 100 * 1000 * 1000; |
463 | master->min_speed_hz = 3 * 1000; | |
74750e06 | 464 | master->use_gpio_descriptors = true; |
3558fe90 MR |
465 | master->set_cs = sun6i_spi_set_cs; |
466 | master->transfer_one = sun6i_spi_transfer_one; | |
467 | master->num_chipselect = 4; | |
468 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; | |
743a46b8 | 469 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
3558fe90 MR |
470 | master->dev.of_node = pdev->dev.of_node; |
471 | master->auto_runtime_pm = true; | |
794912cf | 472 | master->max_transfer_size = sun6i_spi_max_transfer_size; |
3558fe90 MR |
473 | |
474 | sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); | |
475 | if (IS_ERR(sspi->hclk)) { | |
476 | dev_err(&pdev->dev, "Unable to acquire AHB clock\n"); | |
477 | ret = PTR_ERR(sspi->hclk); | |
478 | goto err_free_master; | |
479 | } | |
480 | ||
481 | sspi->mclk = devm_clk_get(&pdev->dev, "mod"); | |
482 | if (IS_ERR(sspi->mclk)) { | |
483 | dev_err(&pdev->dev, "Unable to acquire module clock\n"); | |
484 | ret = PTR_ERR(sspi->mclk); | |
485 | goto err_free_master; | |
486 | } | |
487 | ||
488 | init_completion(&sspi->done); | |
489 | ||
36bc7491 | 490 | sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
3558fe90 MR |
491 | if (IS_ERR(sspi->rstc)) { |
492 | dev_err(&pdev->dev, "Couldn't get reset controller\n"); | |
493 | ret = PTR_ERR(sspi->rstc); | |
494 | goto err_free_master; | |
495 | } | |
496 | ||
497 | /* | |
498 | * This wake-up/shutdown pattern is to be able to have the | |
499 | * device woken up, even if runtime_pm is disabled | |
500 | */ | |
501 | ret = sun6i_spi_runtime_resume(&pdev->dev); | |
502 | if (ret) { | |
503 | dev_err(&pdev->dev, "Couldn't resume the device\n"); | |
504 | goto err_free_master; | |
505 | } | |
506 | ||
507 | pm_runtime_set_active(&pdev->dev); | |
508 | pm_runtime_enable(&pdev->dev); | |
509 | pm_runtime_idle(&pdev->dev); | |
510 | ||
511 | ret = devm_spi_register_master(&pdev->dev, master); | |
512 | if (ret) { | |
513 | dev_err(&pdev->dev, "cannot register SPI master\n"); | |
514 | goto err_pm_disable; | |
515 | } | |
516 | ||
517 | return 0; | |
518 | ||
519 | err_pm_disable: | |
520 | pm_runtime_disable(&pdev->dev); | |
521 | sun6i_spi_runtime_suspend(&pdev->dev); | |
522 | err_free_master: | |
523 | spi_master_put(master); | |
524 | return ret; | |
525 | } | |
526 | ||
527 | static int sun6i_spi_remove(struct platform_device *pdev) | |
528 | { | |
2d9bbd02 | 529 | pm_runtime_force_suspend(&pdev->dev); |
3558fe90 MR |
530 | |
531 | return 0; | |
532 | } | |
533 | ||
534 | static const struct of_device_id sun6i_spi_match[] = { | |
10565dfd MK |
535 | { .compatible = "allwinner,sun6i-a31-spi", .data = (void *)SUN6I_FIFO_DEPTH }, |
536 | { .compatible = "allwinner,sun8i-h3-spi", .data = (void *)SUN8I_FIFO_DEPTH }, | |
3558fe90 MR |
537 | {} |
538 | }; | |
539 | MODULE_DEVICE_TABLE(of, sun6i_spi_match); | |
540 | ||
541 | static const struct dev_pm_ops sun6i_spi_pm_ops = { | |
542 | .runtime_resume = sun6i_spi_runtime_resume, | |
543 | .runtime_suspend = sun6i_spi_runtime_suspend, | |
544 | }; | |
545 | ||
546 | static struct platform_driver sun6i_spi_driver = { | |
547 | .probe = sun6i_spi_probe, | |
548 | .remove = sun6i_spi_remove, | |
549 | .driver = { | |
550 | .name = "sun6i-spi", | |
3558fe90 MR |
551 | .of_match_table = sun6i_spi_match, |
552 | .pm = &sun6i_spi_pm_ops, | |
553 | }, | |
554 | }; | |
555 | module_platform_driver(sun6i_spi_driver); | |
556 | ||
557 | MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>"); | |
558 | MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); | |
559 | MODULE_DESCRIPTION("Allwinner A31 SPI controller driver"); | |
560 | MODULE_LICENSE("GPL"); |