| .. | .. |
|---|
| 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 */ |
|---|