Unverified Commit 9ee448f9 authored by Mark Brown's avatar Mark Brown
Browse files

Improve SPI support for Ingenic SoCs.

Merge series from 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>:

1.Add support for using GPIOs as chip select lines on Ingenic SoCs.
2.Add support for probing the spi-ingenic driver on the JZ4775 SoC,
  the X1000 SoC, and the X2000 SoC.
3.Modify annotation texts to be more in line with the current state.
parents b0ceb621 6d72b114
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ properties:
    oneOf:
      - enum:
          - ingenic,jz4750-spi
          - ingenic,jz4775-spi
          - ingenic,jz4780-spi
          - ingenic,x1000-spi
          - ingenic,x2000-spi
      - items:
          - enum:
              - ingenic,jz4760-spi
+2 −2
Original line number Diff line number Diff line
@@ -419,10 +419,10 @@ config SPI_IMX
	  This enables support for the Freescale i.MX SPI controllers.

config SPI_INGENIC
	tristate "Ingenic JZ47xx SoCs SPI controller"
	tristate "Ingenic SoCs SPI controller"
	depends on MACH_INGENIC || COMPILE_TEST
	help
	  This enables support for the Ingenic JZ47xx SoCs SPI controller.
	  This enables support for the Ingenic SoCs SPI controller.

	  To compile this driver as a module, choose M here: the module
	  will be called spi-ingenic.
+42 −5
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * SPI bus driver for the Ingenic JZ47xx SoCs
 * SPI bus driver for the Ingenic SoCs
 * Copyright (c) 2017-2021 Artur Rojek <contact@artur-rojek.eu>
 * Copyright (c) 2017-2021 Paul Cercueil <paul@crapouillou.net>
 * Copyright (c) 2022 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
 */

#include <linux/clk.h>
@@ -52,6 +53,9 @@ struct jz_soc_info {
	u32 bits_per_word_mask;
	struct reg_field flen_field;
	bool has_trendian;

	unsigned int max_speed_hz;
	unsigned int max_native_cs;
};

struct ingenic_spi {
@@ -380,7 +384,7 @@ static int spi_ingenic_probe(struct platform_device *pdev)
	struct spi_controller *ctlr;
	struct ingenic_spi *priv;
	void __iomem *base;
	int ret;
	int num_cs, ret;

	pdata = of_device_get_match_data(dev);
	if (!pdata) {
@@ -416,6 +420,9 @@ static int spi_ingenic_probe(struct platform_device *pdev)
	if (IS_ERR(priv->flen_field))
		return PTR_ERR(priv->flen_field);

	if (device_property_read_u32(dev, "num-cs", &num_cs))
		num_cs = pdata->max_native_cs;

	platform_set_drvdata(pdev, ctlr);

	ctlr->prepare_transfer_hardware = spi_ingenic_prepare_hardware;
@@ -428,8 +435,10 @@ static int spi_ingenic_probe(struct platform_device *pdev)
	ctlr->max_dma_len = SPI_INGENIC_FIFO_SIZE;
	ctlr->bits_per_word_mask = pdata->bits_per_word_mask;
	ctlr->min_speed_hz = 7200;
	ctlr->max_speed_hz = 54000000;
	ctlr->num_chipselect = 2;
	ctlr->max_speed_hz = pdata->max_speed_hz;
	ctlr->use_gpio_descriptors = true;
	ctlr->max_native_cs = pdata->max_native_cs;
	ctlr->num_chipselect = num_cs;
	ctlr->dev.of_node = pdev->dev.of_node;

	if (spi_ingenic_request_dma(ctlr, dev))
@@ -452,17 +461,44 @@ static const struct jz_soc_info jz4750_soc_info = {
	.bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 17),
	.flen_field = REG_FIELD(REG_SSICR1, 4, 7),
	.has_trendian = false,

	.max_speed_hz = 54000000,
	.max_native_cs = 2,
};

static const struct jz_soc_info jz4780_soc_info = {
	.bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 32),
	.flen_field = REG_FIELD(REG_SSICR1, 3, 7),
	.has_trendian = true,

	.max_speed_hz = 54000000,
	.max_native_cs = 2,
};

static const struct jz_soc_info x1000_soc_info = {
	.bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 32),
	.flen_field = REG_FIELD(REG_SSICR1, 3, 7),
	.has_trendian = true,

	.max_speed_hz = 50000000,
	.max_native_cs = 2,
};

static const struct jz_soc_info x2000_soc_info = {
	.bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 32),
	.flen_field = REG_FIELD(REG_SSICR1, 3, 7),
	.has_trendian = true,

	.max_speed_hz = 50000000,
	.max_native_cs = 1,
};

static const struct of_device_id spi_ingenic_of_match[] = {
	{ .compatible = "ingenic,jz4750-spi", .data = &jz4750_soc_info },
	{ .compatible = "ingenic,jz4775-spi", .data = &jz4780_soc_info },
	{ .compatible = "ingenic,jz4780-spi", .data = &jz4780_soc_info },
	{ .compatible = "ingenic,x1000-spi", .data = &x1000_soc_info },
	{ .compatible = "ingenic,x2000-spi", .data = &x2000_soc_info },
	{}
};
MODULE_DEVICE_TABLE(of, spi_ingenic_of_match);
@@ -476,7 +512,8 @@ static struct platform_driver spi_ingenic_driver = {
};

module_platform_driver(spi_ingenic_driver);
MODULE_DESCRIPTION("SPI bus driver for the Ingenic JZ47xx SoCs");
MODULE_DESCRIPTION("SPI bus driver for the Ingenic SoCs");
MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>");
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
MODULE_AUTHOR("周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>");
MODULE_LICENSE("GPL");