.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Cadence SPI controller driver (master mode only) |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2008 - 2014 Xilinx, Inc. |
---|
5 | 6 | * |
---|
6 | 7 | * based on Blackfin On-Chip SPI Driver (spi_bfin5xx.c) |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it under |
---|
9 | | - * the terms of the GNU General Public License version 2 as published by the |
---|
10 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
11 | | - * option) any later version. |
---|
12 | 8 | */ |
---|
13 | 9 | |
---|
14 | 10 | #include <linux/clk.h> |
---|
15 | 11 | #include <linux/delay.h> |
---|
16 | | -#include <linux/gpio.h> |
---|
| 12 | +#include <linux/gpio/consumer.h> |
---|
17 | 13 | #include <linux/interrupt.h> |
---|
18 | 14 | #include <linux/io.h> |
---|
19 | 15 | #include <linux/module.h> |
---|
.. | .. |
---|
127 | 123 | int rx_bytes; |
---|
128 | 124 | u8 dev_busy; |
---|
129 | 125 | u32 is_decoded_cs; |
---|
130 | | -}; |
---|
131 | | - |
---|
132 | | -struct cdns_spi_device_data { |
---|
133 | | - bool gpio_requested; |
---|
134 | 126 | }; |
---|
135 | 127 | |
---|
136 | 128 | /* Macros for the SPI controller read/write */ |
---|
.. | .. |
---|
427 | 419 | xspi->rx_bytes = transfer->len; |
---|
428 | 420 | |
---|
429 | 421 | cdns_spi_setup_transfer(spi, transfer); |
---|
430 | | - |
---|
431 | 422 | cdns_spi_fill_tx_fifo(xspi); |
---|
| 423 | + spi_transfer_delay_exec(transfer); |
---|
432 | 424 | |
---|
433 | 425 | cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT); |
---|
434 | 426 | return transfer->len; |
---|
.. | .. |
---|
470 | 462 | return 0; |
---|
471 | 463 | } |
---|
472 | 464 | |
---|
473 | | -static int cdns_spi_setup(struct spi_device *spi) |
---|
474 | | -{ |
---|
475 | | - |
---|
476 | | - int ret = -EINVAL; |
---|
477 | | - struct cdns_spi_device_data *cdns_spi_data = spi_get_ctldata(spi); |
---|
478 | | - |
---|
479 | | - /* this is a pin managed by the controller, leave it alone */ |
---|
480 | | - if (spi->cs_gpio == -ENOENT) |
---|
481 | | - return 0; |
---|
482 | | - |
---|
483 | | - /* this seems to be the first time we're here */ |
---|
484 | | - if (!cdns_spi_data) { |
---|
485 | | - cdns_spi_data = kzalloc(sizeof(*cdns_spi_data), GFP_KERNEL); |
---|
486 | | - if (!cdns_spi_data) |
---|
487 | | - return -ENOMEM; |
---|
488 | | - cdns_spi_data->gpio_requested = false; |
---|
489 | | - spi_set_ctldata(spi, cdns_spi_data); |
---|
490 | | - } |
---|
491 | | - |
---|
492 | | - /* if we haven't done so, grab the gpio */ |
---|
493 | | - if (!cdns_spi_data->gpio_requested && gpio_is_valid(spi->cs_gpio)) { |
---|
494 | | - ret = gpio_request_one(spi->cs_gpio, |
---|
495 | | - (spi->mode & SPI_CS_HIGH) ? |
---|
496 | | - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, |
---|
497 | | - dev_name(&spi->dev)); |
---|
498 | | - if (ret) |
---|
499 | | - dev_err(&spi->dev, "can't request chipselect gpio %d\n", |
---|
500 | | - spi->cs_gpio); |
---|
501 | | - else |
---|
502 | | - cdns_spi_data->gpio_requested = true; |
---|
503 | | - } else { |
---|
504 | | - if (gpio_is_valid(spi->cs_gpio)) { |
---|
505 | | - int mode = ((spi->mode & SPI_CS_HIGH) ? |
---|
506 | | - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH); |
---|
507 | | - |
---|
508 | | - ret = gpio_direction_output(spi->cs_gpio, mode); |
---|
509 | | - if (ret) |
---|
510 | | - dev_err(&spi->dev, "chipselect gpio %d setup failed (%d)\n", |
---|
511 | | - spi->cs_gpio, ret); |
---|
512 | | - } |
---|
513 | | - } |
---|
514 | | - |
---|
515 | | - return ret; |
---|
516 | | -} |
---|
517 | | - |
---|
518 | | -static void cdns_spi_cleanup(struct spi_device *spi) |
---|
519 | | -{ |
---|
520 | | - struct cdns_spi_device_data *cdns_spi_data = spi_get_ctldata(spi); |
---|
521 | | - |
---|
522 | | - if (cdns_spi_data) { |
---|
523 | | - if (cdns_spi_data->gpio_requested) |
---|
524 | | - gpio_free(spi->cs_gpio); |
---|
525 | | - kfree(cdns_spi_data); |
---|
526 | | - spi_set_ctldata(spi, NULL); |
---|
527 | | - } |
---|
528 | | - |
---|
529 | | -} |
---|
530 | | - |
---|
531 | 465 | /** |
---|
532 | 466 | * cdns_spi_probe - Probe method for the SPI driver |
---|
533 | 467 | * @pdev: Pointer to the platform_device structure |
---|
.. | .. |
---|
541 | 475 | int ret = 0, irq; |
---|
542 | 476 | struct spi_master *master; |
---|
543 | 477 | struct cdns_spi *xspi; |
---|
544 | | - struct resource *res; |
---|
545 | 478 | u32 num_cs; |
---|
546 | 479 | |
---|
547 | 480 | master = spi_alloc_master(&pdev->dev, sizeof(*xspi)); |
---|
.. | .. |
---|
552 | 485 | master->dev.of_node = pdev->dev.of_node; |
---|
553 | 486 | platform_set_drvdata(pdev, master); |
---|
554 | 487 | |
---|
555 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
556 | | - xspi->regs = devm_ioremap_resource(&pdev->dev, res); |
---|
| 488 | + xspi->regs = devm_platform_ioremap_resource(pdev, 0); |
---|
557 | 489 | if (IS_ERR(xspi->regs)) { |
---|
558 | 490 | ret = PTR_ERR(xspi->regs); |
---|
559 | 491 | goto remove_master; |
---|
.. | .. |
---|
608 | 540 | irq = platform_get_irq(pdev, 0); |
---|
609 | 541 | if (irq <= 0) { |
---|
610 | 542 | ret = -ENXIO; |
---|
611 | | - dev_err(&pdev->dev, "irq number is invalid\n"); |
---|
612 | 543 | goto clk_dis_all; |
---|
613 | 544 | } |
---|
614 | 545 | |
---|
.. | .. |
---|
620 | 551 | goto clk_dis_all; |
---|
621 | 552 | } |
---|
622 | 553 | |
---|
| 554 | + master->use_gpio_descriptors = true; |
---|
623 | 555 | master->prepare_transfer_hardware = cdns_prepare_transfer_hardware; |
---|
624 | 556 | master->prepare_message = cdns_prepare_message; |
---|
625 | 557 | master->transfer_one = cdns_transfer_one; |
---|
626 | 558 | master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; |
---|
627 | 559 | master->set_cs = cdns_spi_chipselect; |
---|
628 | | - master->setup = cdns_spi_setup; |
---|
629 | | - master->cleanup = cdns_spi_cleanup; |
---|
630 | 560 | master->auto_runtime_pm = true; |
---|
631 | | - master->mode_bits = SPI_CPOL | SPI_CPHA; |
---|
| 561 | + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
---|
632 | 562 | |
---|
633 | 563 | xspi->clk_rate = clk_get_rate(xspi->ref_clk); |
---|
634 | 564 | /* Set to default valid value */ |
---|