[U-Boot] [PATCH RFC] spi: mxs spi: DM conversion

Akash Gajjar gajjar04akash at gmail.com
Tue Apr 10 13:15:11 UTC 2018


This is to announce that I have started working on DM driver support for
mxs spi driver that adds basic skeleton of DM driver functionality along with
legacy driver support.

This is compilation tested only.

Signed-off-by: Akash Gajjar <gajjar04akash at gmail.com>
---
 drivers/spi/mxs_spi.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index 790db78..ef970c0 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -20,6 +20,9 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/mach-imx/dma.h>
+#ifdef CONFIG_DM_SPI
+#include <dm.h>
+#endif
 
 #define	MXS_SPI_MAX_TIMEOUT	1000000
 #define	MXS_SPI_PORT_OFFSET	0x2000
@@ -361,3 +364,144 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 		return mxs_spi_xfer_dma(mxs_slave, data, len, write, flags);
 	}
 }
+
+#ifdef CONFIG_DM_SPI
+struct mxs_spi_priv {
+	struct spi_slave	slave;
+	uint32_t		max_khz;
+	uint32_t		mode;
+	struct mxs_ssp_regs	*regs;
+};
+
+struct mxs_spi_platdata {
+	struct spi_slave    slave;
+	uint32_t		bus;
+	struct mxs_ssp_regs *regs;
+};
+
+/* review */
+static int mxs_spi_claim_bus(struct udevice *dev)
+{
+	struct udevice *bus = dev->parent;
+	struct mxs_spi_platdata *plat = dev_get_platdata(bus);
+	struct mxs_ssp_regs *ssp_regs = plat->regs;
+	uint32_t reg = 0;
+
+	writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) |
+			SSP_CTRL0_BUS_WIDTH_ONE_BIT,
+			&ssp_regs->hw_ssp_ctrl0);
+
+	return 0;	
+}
+
+static int mxs_spi_release_bus(struct udevice *dev)
+{
+	return 0;
+}
+
+/* review */
+static int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen,
+			const void *dout, void *din, unsigned long flags)
+{
+	struct udevice *bus = dev->parent;
+	struct mxs_spi_platdata *plat = dev_get_platdata(bus);
+	struct mxs_ssp_regs *ssp_regs = plat->regs;
+	int len = bitlen / 8;
+	char dummy;
+	int write = 0;
+	char *data = NULL;
+	int dma = 1;
+
+	if (bitlen == 0) {
+		if (flags & SPI_XFER_END) {
+			din = (void *)&dummy;
+			len = 1;
+		} else
+			return 0;
+	}
+
+	/* Half-duplex only */
+	if (din && dout)
+		return -EINVAL;
+	/* No data */
+	if (!din && !dout)
+		return 0;
+
+	if (dout) {
+		data = (char *)dout;
+		write = 1;
+	} else if (din) {
+		data = (char *)din;
+		write = 0;
+	}
+
+	/*
+	 * Check for alignment, if the buffer is aligned, do DMA transfer,
+	 * PIO otherwise. This is a temporary workaround until proper bounce
+	 * buffer is in place.
+	 */
+	if (dma) {
+		if (((uint32_t)data) & (ARCH_DMA_MINALIGN - 1))
+			dma = 0;
+		if (((uint32_t)len) & (ARCH_DMA_MINALIGN - 1))
+			dma = 0;
+	}
+
+	if (!dma || (len < MXSSSP_SMALL_TRANSFER)) {
+		writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr);
+		return mxs_spi_xfer_pio(mxs_slave, data, len, write, flags);
+	} else {
+		writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set);
+		return mxs_spi_xfer_dma(mxs_slave, data, len, write, flags);
+	}
+
+	return 0;
+}
+
+static int mxs_spi_set_speed(struct udevice *bus, uint speed)
+{
+	struct mxs_spi_platdata *plat = dev_get_platdata(bus);
+
+	debug("%s mode %u\n", __func__, mode);
+	priv->max_khz = speed;
+
+	return 0;
+}
+
+static int mxs_spi_set_mode(struct udevice *bus, uint mode)
+{
+	struct mxs_spi_priv *priv = dev_get_priv(bus);
+
+	debug("%s mode %u\n", __func__, mode);	
+	priv->mode = mode;
+
+	return 0;
+}
+
+static int mxs_spi_probe(struct udevice *dev)
+{
+	struct mxs_spi_platdata *plat = dev_get_platdata(dev);
+	struct mxs_spi_priv *priv;
+
+
+	priv->regs = mxs_ssp_regs_by_bus(plat->bus);
+
+	return 0;	
+}
+
+static const struct dm_spi_ops mxs_spi_ops = {
+	.claim_bus      = mxs_spi_claim_bus,
+	.release_bus    = mxs_spi_release_bus,
+	.xfer           = mxs_spi_xfer,
+	.set_speed      = mxs_spi_set_speed,
+	.set_mode       = mxs_spi_set_mode,
+};
+
+U_BOOT_DRIVER(mxs_spi) = {
+	.name 	= "mxs_spi",
+	.id     = UCLASS_SPI,
+	.ops    = &mxs_spi_ops,
+	.priv_auto_alloc_size = sizeof(struct mxs_spi_priv),
+	.probe  = mxs_spi_probe,
+};
+#endif
-- 
1.9.1



More information about the U-Boot mailing list