summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-06-16 02:38:40 +0300
committerMark Brown <broonie@kernel.org>2020-06-16 02:38:40 +0300
commit731f1e71f2655caf611540d43bfee3bb0b481f4e (patch)
tree1b1bb28129a953c9b1a7c82607b0a02812d8476c /drivers/spi
parente8510d43f219beff1f426080049a5462148afd2f (diff)
parent1fccd182a4694a848f2d6f3b1820d6fc71d9c99d (diff)
downloadlinux-731f1e71f2655caf611540d43bfee3bb0b481f4e.tar.xz
Merge series "Add more configuration and regmap support for spi-altera" from Xu Yilun <yilun.xu@intel.com>:
This patchset adds platform_data for spi-altera, to enable more IP configurations, and creating specific spi client devices. It also adds regmap support, to enable the indirect access to this IP. We have a PCIE based FPGA platform which integrates this IP to communicate with a BMC chip (Intel MAX10) over SPI. The IP is configured as 32bit data width. There is also an indirect access interface in FPGA for host to access the registers of this IP. This patchset enables this use case. Matthew Gerlach (1): spi: altera: fix size mismatch on 64 bit processors Xu Yilun (5): spi: altera: add 32bit data width transfer support. spi: altera: add SPI core parameters support via platform data. spi: altera: add platform data for slave information. spi: altera: use regmap instead of direct mmio register access spi: altera: move driver name string to header file drivers/spi/Kconfig | 1 + drivers/spi/spi-altera.c | 161 +++++++++++++++++++++++++++++++++++++-------- include/linux/spi/altera.h | 37 +++++++++++ 3 files changed, 171 insertions(+), 28 deletions(-) create mode 100644 include/linux/spi/altera.h -- 2.7.4
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-altera.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c
index 41d71ba7fd32..aa9d1a257433 100644
--- a/drivers/spi/spi-altera.c
+++ b/drivers/spi/spi-altera.c
@@ -14,6 +14,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/spi/altera.h>
#include <linux/spi/spi.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -40,6 +41,8 @@
#define ALTERA_SPI_CONTROL_IE_MSK 0x100
#define ALTERA_SPI_CONTROL_SSO_MSK 0x400
+#define ALTERA_SPI_MAX_CS 32
+
struct altera_spi {
void __iomem *base;
int irq;
@@ -86,6 +89,13 @@ static void altera_spi_tx_word(struct altera_spi *hw)
txd = (hw->tx[hw->count * 2]
| (hw->tx[hw->count * 2 + 1] << 8));
break;
+ case 4:
+ txd = (hw->tx[hw->count * 4]
+ | (hw->tx[hw->count * 4 + 1] << 8)
+ | (hw->tx[hw->count * 4 + 2] << 16)
+ | (hw->tx[hw->count * 4 + 3] << 24));
+ break;
+
}
}
@@ -106,6 +116,13 @@ static void altera_spi_rx_word(struct altera_spi *hw)
hw->rx[hw->count * 2] = rxd;
hw->rx[hw->count * 2 + 1] = rxd >> 8;
break;
+ case 4:
+ hw->rx[hw->count * 4] = rxd;
+ hw->rx[hw->count * 4 + 1] = rxd >> 8;
+ hw->rx[hw->count * 4 + 2] = rxd >> 16;
+ hw->rx[hw->count * 4 + 3] = rxd >> 24;
+ break;
+
}
}
@@ -168,9 +185,11 @@ static irqreturn_t altera_spi_irq(int irq, void *dev)
static int altera_spi_probe(struct platform_device *pdev)
{
+ struct altera_spi_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct altera_spi *hw;
struct spi_master *master;
int err = -ENODEV;
+ u16 i;
master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi));
if (!master)
@@ -178,9 +197,24 @@ static int altera_spi_probe(struct platform_device *pdev)
/* setup the master state. */
master->bus_num = pdev->id;
- master->num_chipselect = 16;
- master->mode_bits = SPI_CS_HIGH;
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
+
+ if (pdata) {
+ if (pdata->num_chipselect > ALTERA_SPI_MAX_CS) {
+ dev_err(&pdev->dev,
+ "Invalid number of chipselect: %hu\n",
+ pdata->num_chipselect);
+ return -EINVAL;
+ }
+
+ master->num_chipselect = pdata->num_chipselect;
+ master->mode_bits = pdata->mode_bits;
+ master->bits_per_word_mask = pdata->bits_per_word_mask;
+ } else {
+ master->num_chipselect = 16;
+ master->mode_bits = SPI_CS_HIGH;
+ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
+ }
+
master->dev.of_node = pdev->dev.of_node;
master->transfer_one = altera_spi_txrx;
master->set_cs = altera_spi_set_cs;
@@ -211,6 +245,16 @@ static int altera_spi_probe(struct platform_device *pdev)
err = devm_spi_register_master(&pdev->dev, master);
if (err)
goto exit;
+
+ if (pdata) {
+ for (i = 0; i < pdata->num_devices; i++) {
+ if (!spi_new_device(master, pdata->devices + i))
+ dev_warn(&pdev->dev,
+ "unable to create SPI device: %s\n",
+ pdata->devices[i].modalias);
+ }
+ }
+
dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);
return 0;