1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2008-2014 STMicroelectronics Limited |
4 | * |
5 | * Author: Angus Clark <Angus.Clark@st.com> |
6 | * Patrice Chotard <patrice.chotard@st.com> |
7 | * Lee Jones <lee.jones@linaro.org> |
8 | * |
9 | * SPI host mode controller driver, used in STMicroelectronics devices. |
10 | */ |
11 | |
12 | #include <linux/clk.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/interrupt.h> |
15 | #include <linux/io.h> |
16 | #include <linux/module.h> |
17 | #include <linux/pinctrl/consumer.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/of.h> |
20 | #include <linux/of_irq.h> |
21 | #include <linux/pm_runtime.h> |
22 | #include <linux/spi/spi.h> |
23 | #include <linux/spi/spi_bitbang.h> |
24 | |
25 | /* SSC registers */ |
26 | #define SSC_BRG 0x000 |
27 | #define SSC_TBUF 0x004 |
28 | #define SSC_RBUF 0x008 |
29 | #define SSC_CTL 0x00C |
30 | #define SSC_IEN 0x010 |
31 | #define SSC_I2C 0x018 |
32 | |
33 | /* SSC Control */ |
34 | #define SSC_CTL_DATA_WIDTH_9 0x8 |
35 | #define SSC_CTL_DATA_WIDTH_MSK 0xf |
36 | #define SSC_CTL_BM 0xf |
37 | #define SSC_CTL_HB BIT(4) |
38 | #define SSC_CTL_PH BIT(5) |
39 | #define SSC_CTL_PO BIT(6) |
40 | #define SSC_CTL_SR BIT(7) |
41 | #define SSC_CTL_MS BIT(8) |
42 | #define SSC_CTL_EN BIT(9) |
43 | #define SSC_CTL_LPB BIT(10) |
44 | #define SSC_CTL_EN_TX_FIFO BIT(11) |
45 | #define SSC_CTL_EN_RX_FIFO BIT(12) |
46 | #define SSC_CTL_EN_CLST_RX BIT(13) |
47 | |
48 | /* SSC Interrupt Enable */ |
49 | #define SSC_IEN_TEEN BIT(2) |
50 | |
51 | #define FIFO_SIZE 8 |
52 | |
53 | struct spi_st { |
54 | /* SSC SPI Controller */ |
55 | void __iomem *base; |
56 | struct clk *clk; |
57 | struct device *dev; |
58 | |
59 | /* SSC SPI current transaction */ |
60 | const u8 *tx_ptr; |
61 | u8 *rx_ptr; |
62 | u16 bytes_per_word; |
63 | unsigned int words_remaining; |
64 | unsigned int baud; |
65 | struct completion done; |
66 | }; |
67 | |
68 | /* Load the TX FIFO */ |
69 | static void ssc_write_tx_fifo(struct spi_st *spi_st) |
70 | { |
71 | unsigned int count, i; |
72 | uint32_t word = 0; |
73 | |
74 | if (spi_st->words_remaining > FIFO_SIZE) |
75 | count = FIFO_SIZE; |
76 | else |
77 | count = spi_st->words_remaining; |
78 | |
79 | for (i = 0; i < count; i++) { |
80 | if (spi_st->tx_ptr) { |
81 | if (spi_st->bytes_per_word == 1) { |
82 | word = *spi_st->tx_ptr++; |
83 | } else { |
84 | word = *spi_st->tx_ptr++; |
85 | word = *spi_st->tx_ptr++ | (word << 8); |
86 | } |
87 | } |
88 | writel_relaxed(word, spi_st->base + SSC_TBUF); |
89 | } |
90 | } |
91 | |
92 | /* Read the RX FIFO */ |
93 | static void ssc_read_rx_fifo(struct spi_st *spi_st) |
94 | { |
95 | unsigned int count, i; |
96 | uint32_t word = 0; |
97 | |
98 | if (spi_st->words_remaining > FIFO_SIZE) |
99 | count = FIFO_SIZE; |
100 | else |
101 | count = spi_st->words_remaining; |
102 | |
103 | for (i = 0; i < count; i++) { |
104 | word = readl_relaxed(spi_st->base + SSC_RBUF); |
105 | |
106 | if (spi_st->rx_ptr) { |
107 | if (spi_st->bytes_per_word == 1) { |
108 | *spi_st->rx_ptr++ = (uint8_t)word; |
109 | } else { |
110 | *spi_st->rx_ptr++ = (word >> 8); |
111 | *spi_st->rx_ptr++ = word & 0xff; |
112 | } |
113 | } |
114 | } |
115 | spi_st->words_remaining -= count; |
116 | } |
117 | |
118 | static int spi_st_transfer_one(struct spi_controller *host, |
119 | struct spi_device *spi, struct spi_transfer *t) |
120 | { |
121 | struct spi_st *spi_st = spi_controller_get_devdata(ctlr: host); |
122 | uint32_t ctl = 0; |
123 | |
124 | /* Setup transfer */ |
125 | spi_st->tx_ptr = t->tx_buf; |
126 | spi_st->rx_ptr = t->rx_buf; |
127 | |
128 | if (spi->bits_per_word > 8) { |
129 | /* |
130 | * Anything greater than 8 bits-per-word requires 2 |
131 | * bytes-per-word in the RX/TX buffers |
132 | */ |
133 | spi_st->bytes_per_word = 2; |
134 | spi_st->words_remaining = t->len / 2; |
135 | |
136 | } else if (spi->bits_per_word == 8 && !(t->len & 0x1)) { |
137 | /* |
138 | * If transfer is even-length, and 8 bits-per-word, then |
139 | * implement as half-length 16 bits-per-word transfer |
140 | */ |
141 | spi_st->bytes_per_word = 2; |
142 | spi_st->words_remaining = t->len / 2; |
143 | |
144 | /* Set SSC_CTL to 16 bits-per-word */ |
145 | ctl = readl_relaxed(spi_st->base + SSC_CTL); |
146 | writel_relaxed((ctl | 0xf), spi_st->base + SSC_CTL); |
147 | |
148 | readl_relaxed(spi_st->base + SSC_RBUF); |
149 | |
150 | } else { |
151 | spi_st->bytes_per_word = 1; |
152 | spi_st->words_remaining = t->len; |
153 | } |
154 | |
155 | reinit_completion(x: &spi_st->done); |
156 | |
157 | /* Start transfer by writing to the TX FIFO */ |
158 | ssc_write_tx_fifo(spi_st); |
159 | writel_relaxed(SSC_IEN_TEEN, spi_st->base + SSC_IEN); |
160 | |
161 | /* Wait for transfer to complete */ |
162 | wait_for_completion(&spi_st->done); |
163 | |
164 | /* Restore SSC_CTL if necessary */ |
165 | if (ctl) |
166 | writel_relaxed(ctl, spi_st->base + SSC_CTL); |
167 | |
168 | spi_finalize_current_transfer(ctlr: spi->controller); |
169 | |
170 | return t->len; |
171 | } |
172 | |
173 | /* the spi->mode bits understood by this driver: */ |
174 | #define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH) |
175 | static int spi_st_setup(struct spi_device *spi) |
176 | { |
177 | struct spi_st *spi_st = spi_controller_get_devdata(ctlr: spi->controller); |
178 | u32 spi_st_clk, sscbrg, var; |
179 | u32 hz = spi->max_speed_hz; |
180 | |
181 | if (!hz) { |
182 | dev_err(&spi->dev, "max_speed_hz unspecified\n" ); |
183 | return -EINVAL; |
184 | } |
185 | |
186 | if (!spi_get_csgpiod(spi, idx: 0)) { |
187 | dev_err(&spi->dev, "no valid gpio assigned\n" ); |
188 | return -EINVAL; |
189 | } |
190 | |
191 | spi_st_clk = clk_get_rate(clk: spi_st->clk); |
192 | |
193 | /* Set SSC_BRF */ |
194 | sscbrg = spi_st_clk / (2 * hz); |
195 | if (sscbrg < 0x07 || sscbrg > BIT(16)) { |
196 | dev_err(&spi->dev, |
197 | "baudrate %d outside valid range %d\n" , sscbrg, hz); |
198 | return -EINVAL; |
199 | } |
200 | |
201 | spi_st->baud = spi_st_clk / (2 * sscbrg); |
202 | if (sscbrg == BIT(16)) /* 16-bit counter wraps */ |
203 | sscbrg = 0x0; |
204 | |
205 | writel_relaxed(sscbrg, spi_st->base + SSC_BRG); |
206 | |
207 | dev_dbg(&spi->dev, |
208 | "setting baudrate:target= %u hz, actual= %u hz, sscbrg= %u\n" , |
209 | hz, spi_st->baud, sscbrg); |
210 | |
211 | /* Set SSC_CTL and enable SSC */ |
212 | var = readl_relaxed(spi_st->base + SSC_CTL); |
213 | var |= SSC_CTL_MS; |
214 | |
215 | if (spi->mode & SPI_CPOL) |
216 | var |= SSC_CTL_PO; |
217 | else |
218 | var &= ~SSC_CTL_PO; |
219 | |
220 | if (spi->mode & SPI_CPHA) |
221 | var |= SSC_CTL_PH; |
222 | else |
223 | var &= ~SSC_CTL_PH; |
224 | |
225 | if ((spi->mode & SPI_LSB_FIRST) == 0) |
226 | var |= SSC_CTL_HB; |
227 | else |
228 | var &= ~SSC_CTL_HB; |
229 | |
230 | if (spi->mode & SPI_LOOP) |
231 | var |= SSC_CTL_LPB; |
232 | else |
233 | var &= ~SSC_CTL_LPB; |
234 | |
235 | var &= ~SSC_CTL_DATA_WIDTH_MSK; |
236 | var |= (spi->bits_per_word - 1); |
237 | |
238 | var |= SSC_CTL_EN_TX_FIFO | SSC_CTL_EN_RX_FIFO; |
239 | var |= SSC_CTL_EN; |
240 | |
241 | writel_relaxed(var, spi_st->base + SSC_CTL); |
242 | |
243 | /* Clear the status register */ |
244 | readl_relaxed(spi_st->base + SSC_RBUF); |
245 | |
246 | return 0; |
247 | } |
248 | |
249 | /* Interrupt fired when TX shift register becomes empty */ |
250 | static irqreturn_t spi_st_irq(int irq, void *dev_id) |
251 | { |
252 | struct spi_st *spi_st = (struct spi_st *)dev_id; |
253 | |
254 | /* Read RX FIFO */ |
255 | ssc_read_rx_fifo(spi_st); |
256 | |
257 | /* Fill TX FIFO */ |
258 | if (spi_st->words_remaining) { |
259 | ssc_write_tx_fifo(spi_st); |
260 | } else { |
261 | /* TX/RX complete */ |
262 | writel_relaxed(0x0, spi_st->base + SSC_IEN); |
263 | /* |
264 | * read SSC_IEN to ensure that this bit is set |
265 | * before re-enabling interrupt |
266 | */ |
267 | readl(addr: spi_st->base + SSC_IEN); |
268 | complete(&spi_st->done); |
269 | } |
270 | |
271 | return IRQ_HANDLED; |
272 | } |
273 | |
274 | static int spi_st_probe(struct platform_device *pdev) |
275 | { |
276 | struct device_node *np = pdev->dev.of_node; |
277 | struct spi_controller *host; |
278 | struct spi_st *spi_st; |
279 | int irq, ret = 0; |
280 | u32 var; |
281 | |
282 | host = spi_alloc_host(dev: &pdev->dev, size: sizeof(*spi_st)); |
283 | if (!host) |
284 | return -ENOMEM; |
285 | |
286 | host->dev.of_node = np; |
287 | host->mode_bits = MODEBITS; |
288 | host->setup = spi_st_setup; |
289 | host->transfer_one = spi_st_transfer_one; |
290 | host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); |
291 | host->auto_runtime_pm = true; |
292 | host->bus_num = pdev->id; |
293 | host->use_gpio_descriptors = true; |
294 | spi_st = spi_controller_get_devdata(ctlr: host); |
295 | |
296 | spi_st->clk = devm_clk_get(dev: &pdev->dev, id: "ssc" ); |
297 | if (IS_ERR(ptr: spi_st->clk)) { |
298 | dev_err(&pdev->dev, "Unable to request clock\n" ); |
299 | ret = PTR_ERR(ptr: spi_st->clk); |
300 | goto put_host; |
301 | } |
302 | |
303 | ret = clk_prepare_enable(clk: spi_st->clk); |
304 | if (ret) |
305 | goto put_host; |
306 | |
307 | init_completion(x: &spi_st->done); |
308 | |
309 | /* Get resources */ |
310 | spi_st->base = devm_platform_ioremap_resource(pdev, index: 0); |
311 | if (IS_ERR(ptr: spi_st->base)) { |
312 | ret = PTR_ERR(ptr: spi_st->base); |
313 | goto clk_disable; |
314 | } |
315 | |
316 | /* Disable I2C and Reset SSC */ |
317 | writel_relaxed(0x0, spi_st->base + SSC_I2C); |
318 | var = readw_relaxed(spi_st->base + SSC_CTL); |
319 | var |= SSC_CTL_SR; |
320 | writel_relaxed(var, spi_st->base + SSC_CTL); |
321 | |
322 | udelay(1); |
323 | var = readl_relaxed(spi_st->base + SSC_CTL); |
324 | var &= ~SSC_CTL_SR; |
325 | writel_relaxed(var, spi_st->base + SSC_CTL); |
326 | |
327 | /* Set SSC into target mode before reconfiguring PIO pins */ |
328 | var = readl_relaxed(spi_st->base + SSC_CTL); |
329 | var &= ~SSC_CTL_MS; |
330 | writel_relaxed(var, spi_st->base + SSC_CTL); |
331 | |
332 | irq = irq_of_parse_and_map(node: np, index: 0); |
333 | if (!irq) { |
334 | dev_err(&pdev->dev, "IRQ missing or invalid\n" ); |
335 | ret = -EINVAL; |
336 | goto clk_disable; |
337 | } |
338 | |
339 | ret = devm_request_irq(dev: &pdev->dev, irq, handler: spi_st_irq, irqflags: 0, |
340 | devname: pdev->name, dev_id: spi_st); |
341 | if (ret) { |
342 | dev_err(&pdev->dev, "Failed to request irq %d\n" , irq); |
343 | goto clk_disable; |
344 | } |
345 | |
346 | /* by default the device is on */ |
347 | pm_runtime_set_active(dev: &pdev->dev); |
348 | pm_runtime_enable(dev: &pdev->dev); |
349 | |
350 | platform_set_drvdata(pdev, data: host); |
351 | |
352 | ret = devm_spi_register_controller(dev: &pdev->dev, ctlr: host); |
353 | if (ret) { |
354 | dev_err(&pdev->dev, "Failed to register host\n" ); |
355 | goto rpm_disable; |
356 | } |
357 | |
358 | return 0; |
359 | |
360 | rpm_disable: |
361 | pm_runtime_disable(dev: &pdev->dev); |
362 | clk_disable: |
363 | clk_disable_unprepare(clk: spi_st->clk); |
364 | put_host: |
365 | spi_controller_put(ctlr: host); |
366 | return ret; |
367 | } |
368 | |
369 | static void spi_st_remove(struct platform_device *pdev) |
370 | { |
371 | struct spi_controller *host = platform_get_drvdata(pdev); |
372 | struct spi_st *spi_st = spi_controller_get_devdata(ctlr: host); |
373 | |
374 | pm_runtime_disable(dev: &pdev->dev); |
375 | |
376 | clk_disable_unprepare(clk: spi_st->clk); |
377 | |
378 | pinctrl_pm_select_sleep_state(dev: &pdev->dev); |
379 | } |
380 | |
381 | #ifdef CONFIG_PM |
382 | static int spi_st_runtime_suspend(struct device *dev) |
383 | { |
384 | struct spi_controller *host = dev_get_drvdata(dev); |
385 | struct spi_st *spi_st = spi_controller_get_devdata(ctlr: host); |
386 | |
387 | writel_relaxed(0, spi_st->base + SSC_IEN); |
388 | pinctrl_pm_select_sleep_state(dev); |
389 | |
390 | clk_disable_unprepare(clk: spi_st->clk); |
391 | |
392 | return 0; |
393 | } |
394 | |
395 | static int spi_st_runtime_resume(struct device *dev) |
396 | { |
397 | struct spi_controller *host = dev_get_drvdata(dev); |
398 | struct spi_st *spi_st = spi_controller_get_devdata(ctlr: host); |
399 | int ret; |
400 | |
401 | ret = clk_prepare_enable(clk: spi_st->clk); |
402 | pinctrl_pm_select_default_state(dev); |
403 | |
404 | return ret; |
405 | } |
406 | #endif |
407 | |
408 | #ifdef CONFIG_PM_SLEEP |
409 | static int spi_st_suspend(struct device *dev) |
410 | { |
411 | struct spi_controller *host = dev_get_drvdata(dev); |
412 | int ret; |
413 | |
414 | ret = spi_controller_suspend(ctlr: host); |
415 | if (ret) |
416 | return ret; |
417 | |
418 | return pm_runtime_force_suspend(dev); |
419 | } |
420 | |
421 | static int spi_st_resume(struct device *dev) |
422 | { |
423 | struct spi_controller *host = dev_get_drvdata(dev); |
424 | int ret; |
425 | |
426 | ret = spi_controller_resume(ctlr: host); |
427 | if (ret) |
428 | return ret; |
429 | |
430 | return pm_runtime_force_resume(dev); |
431 | } |
432 | #endif |
433 | |
434 | static const struct dev_pm_ops spi_st_pm = { |
435 | SET_SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume) |
436 | SET_RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL) |
437 | }; |
438 | |
439 | static const struct of_device_id stm_spi_match[] = { |
440 | { .compatible = "st,comms-ssc4-spi" , }, |
441 | {}, |
442 | }; |
443 | MODULE_DEVICE_TABLE(of, stm_spi_match); |
444 | |
445 | static struct platform_driver spi_st_driver = { |
446 | .driver = { |
447 | .name = "spi-st" , |
448 | .pm = &spi_st_pm, |
449 | .of_match_table = of_match_ptr(stm_spi_match), |
450 | }, |
451 | .probe = spi_st_probe, |
452 | .remove_new = spi_st_remove, |
453 | }; |
454 | module_platform_driver(spi_st_driver); |
455 | |
456 | MODULE_AUTHOR("Patrice Chotard <patrice.chotard@st.com>" ); |
457 | MODULE_DESCRIPTION("STM SSC SPI driver" ); |
458 | MODULE_LICENSE("GPL v2" ); |
459 | |