.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * OpenCores tiny SPI master driver |
---|
3 | 4 | * |
---|
4 | | - * http://opencores.org/project,tiny_spi |
---|
| 5 | + * https://opencores.org/project,tiny_spi |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright (C) 2011 Thomas Chou <thomas@wytron.com.tw> |
---|
7 | 8 | * |
---|
.. | .. |
---|
9 | 10 | * Copyright (c) 2006 Ben Dooks |
---|
10 | 11 | * Copyright (c) 2006 Simtec Electronics |
---|
11 | 12 | * Ben Dooks <ben@simtec.co.uk> |
---|
12 | | - * |
---|
13 | | - * This program is free software; you can redistribute it and/or modify |
---|
14 | | - * it under the terms of the GNU General Public License version 2 as |
---|
15 | | - * published by the Free Software Foundation. |
---|
16 | 13 | */ |
---|
17 | 14 | |
---|
18 | 15 | #include <linux/interrupt.h> |
---|
.. | .. |
---|
23 | 20 | #include <linux/spi/spi_bitbang.h> |
---|
24 | 21 | #include <linux/spi/spi_oc_tiny.h> |
---|
25 | 22 | #include <linux/io.h> |
---|
26 | | -#include <linux/gpio.h> |
---|
27 | 23 | #include <linux/of.h> |
---|
28 | 24 | |
---|
29 | 25 | #define DRV_NAME "spi_oc_tiny" |
---|
.. | .. |
---|
53 | 49 | unsigned int txc, rxc; |
---|
54 | 50 | const u8 *txp; |
---|
55 | 51 | u8 *rxp; |
---|
56 | | - int gpio_cs_count; |
---|
57 | | - int *gpio_cs; |
---|
58 | 52 | }; |
---|
59 | 53 | |
---|
60 | 54 | static inline struct tiny_spi *tiny_spi_to_hw(struct spi_device *sdev) |
---|
.. | .. |
---|
67 | 61 | struct tiny_spi *hw = tiny_spi_to_hw(spi); |
---|
68 | 62 | |
---|
69 | 63 | return min(DIV_ROUND_UP(hw->freq, hz * 2), (1U << hw->baudwidth)) - 1; |
---|
70 | | -} |
---|
71 | | - |
---|
72 | | -static void tiny_spi_chipselect(struct spi_device *spi, int is_active) |
---|
73 | | -{ |
---|
74 | | - struct tiny_spi *hw = tiny_spi_to_hw(spi); |
---|
75 | | - |
---|
76 | | - if (hw->gpio_cs_count > 0) { |
---|
77 | | - gpio_set_value(hw->gpio_cs[spi->chip_select], |
---|
78 | | - (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); |
---|
79 | | - } |
---|
80 | 64 | } |
---|
81 | 65 | |
---|
82 | 66 | static int tiny_spi_setup_transfer(struct spi_device *spi, |
---|
.. | .. |
---|
206 | 190 | { |
---|
207 | 191 | struct tiny_spi *hw = platform_get_drvdata(pdev); |
---|
208 | 192 | struct device_node *np = pdev->dev.of_node; |
---|
209 | | - unsigned int i; |
---|
210 | 193 | u32 val; |
---|
211 | 194 | |
---|
212 | 195 | if (!np) |
---|
213 | 196 | return 0; |
---|
214 | | - hw->gpio_cs_count = of_gpio_count(np); |
---|
215 | | - if (hw->gpio_cs_count > 0) { |
---|
216 | | - hw->gpio_cs = devm_kcalloc(&pdev->dev, |
---|
217 | | - hw->gpio_cs_count, sizeof(unsigned int), |
---|
218 | | - GFP_KERNEL); |
---|
219 | | - if (!hw->gpio_cs) |
---|
220 | | - return -ENOMEM; |
---|
221 | | - } |
---|
222 | | - for (i = 0; i < hw->gpio_cs_count; i++) { |
---|
223 | | - hw->gpio_cs[i] = of_get_gpio_flags(np, i, NULL); |
---|
224 | | - if (hw->gpio_cs[i] < 0) |
---|
225 | | - return -ENODEV; |
---|
226 | | - } |
---|
227 | 197 | hw->bitbang.master->dev.of_node = pdev->dev.of_node; |
---|
228 | 198 | if (!of_property_read_u32(np, "clock-frequency", &val)) |
---|
229 | 199 | hw->freq = val; |
---|
.. | .. |
---|
243 | 213 | struct tiny_spi_platform_data *platp = dev_get_platdata(&pdev->dev); |
---|
244 | 214 | struct tiny_spi *hw; |
---|
245 | 215 | struct spi_master *master; |
---|
246 | | - struct resource *res; |
---|
247 | | - unsigned int i; |
---|
248 | 216 | int err = -ENODEV; |
---|
249 | 217 | |
---|
250 | 218 | master = spi_alloc_master(&pdev->dev, sizeof(struct tiny_spi)); |
---|
.. | .. |
---|
253 | 221 | |
---|
254 | 222 | /* setup the master state. */ |
---|
255 | 223 | master->bus_num = pdev->id; |
---|
256 | | - master->num_chipselect = 255; |
---|
257 | 224 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
---|
258 | 225 | master->setup = tiny_spi_setup; |
---|
| 226 | + master->use_gpio_descriptors = true; |
---|
259 | 227 | |
---|
260 | 228 | hw = spi_master_get_devdata(master); |
---|
261 | 229 | platform_set_drvdata(pdev, hw); |
---|
.. | .. |
---|
263 | 231 | /* setup the state for the bitbang driver */ |
---|
264 | 232 | hw->bitbang.master = master; |
---|
265 | 233 | hw->bitbang.setup_transfer = tiny_spi_setup_transfer; |
---|
266 | | - hw->bitbang.chipselect = tiny_spi_chipselect; |
---|
267 | 234 | hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs; |
---|
268 | 235 | |
---|
269 | 236 | /* find and map our resources */ |
---|
270 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
271 | | - hw->base = devm_ioremap_resource(&pdev->dev, res); |
---|
| 237 | + hw->base = devm_platform_ioremap_resource(pdev, 0); |
---|
272 | 238 | if (IS_ERR(hw->base)) { |
---|
273 | 239 | err = PTR_ERR(hw->base); |
---|
274 | 240 | goto exit; |
---|
.. | .. |
---|
284 | 250 | } |
---|
285 | 251 | /* find platform data */ |
---|
286 | 252 | if (platp) { |
---|
287 | | - hw->gpio_cs_count = platp->gpio_cs_count; |
---|
288 | | - hw->gpio_cs = platp->gpio_cs; |
---|
289 | | - if (platp->gpio_cs_count && !platp->gpio_cs) { |
---|
290 | | - err = -EBUSY; |
---|
291 | | - goto exit; |
---|
292 | | - } |
---|
293 | 253 | hw->freq = platp->freq; |
---|
294 | 254 | hw->baudwidth = platp->baudwidth; |
---|
295 | 255 | } else { |
---|
.. | .. |
---|
297 | 257 | if (err) |
---|
298 | 258 | goto exit; |
---|
299 | 259 | } |
---|
300 | | - for (i = 0; i < hw->gpio_cs_count; i++) { |
---|
301 | | - err = gpio_request(hw->gpio_cs[i], dev_name(&pdev->dev)); |
---|
302 | | - if (err) |
---|
303 | | - goto exit_gpio; |
---|
304 | | - gpio_direction_output(hw->gpio_cs[i], 1); |
---|
305 | | - } |
---|
306 | | - hw->bitbang.master->num_chipselect = max(1, hw->gpio_cs_count); |
---|
307 | 260 | |
---|
308 | 261 | /* register our spi controller */ |
---|
309 | 262 | err = spi_bitbang_start(&hw->bitbang); |
---|
.. | .. |
---|
313 | 266 | |
---|
314 | 267 | return 0; |
---|
315 | 268 | |
---|
316 | | -exit_gpio: |
---|
317 | | - while (i-- > 0) |
---|
318 | | - gpio_free(hw->gpio_cs[i]); |
---|
319 | 269 | exit: |
---|
320 | 270 | spi_master_put(master); |
---|
321 | 271 | return err; |
---|
.. | .. |
---|
325 | 275 | { |
---|
326 | 276 | struct tiny_spi *hw = platform_get_drvdata(pdev); |
---|
327 | 277 | struct spi_master *master = hw->bitbang.master; |
---|
328 | | - unsigned int i; |
---|
329 | 278 | |
---|
330 | 279 | spi_bitbang_stop(&hw->bitbang); |
---|
331 | | - for (i = 0; i < hw->gpio_cs_count; i++) |
---|
332 | | - gpio_free(hw->gpio_cs[i]); |
---|
333 | 280 | spi_master_put(master); |
---|
334 | 281 | return 0; |
---|
335 | 282 | } |
---|