
v1->v2 register cs_info method remove unused function __mxs_spi_setup merged __spi_xfer function to spi_xfer printf replaced by debug
Signed-off-by: Akash Gajjar akash@openedev.com --- drivers/spi/mxs_spi.c | 169 ++++++++++++++++++++++++-------------------------- 1 file changed, 81 insertions(+), 88 deletions(-)
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c index 0af2eee..3054438 100644 --- a/drivers/spi/mxs_spi.c +++ b/drivers/spi/mxs_spi.c @@ -82,7 +82,7 @@ static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv,
if (mxs_wait_mask_set(&ssp_regs->hw_ssp_ctrl0_reg, SSP_CTRL0_RUN, MXS_SPI_MAX_TIMEOUT)) { - printf("MXS SPI: Timeout waiting for start\n"); + debug("MXS SPI: Timeout waiting for start\n"); return -ETIMEDOUT; }
@@ -94,7 +94,7 @@ static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv, if (!write) { if (mxs_wait_mask_clr(&ssp_regs->hw_ssp_status_reg, SSP_STATUS_FIFO_EMPTY, MXS_SPI_MAX_TIMEOUT)) { - printf("MXS SPI: Timeout waiting for data\n"); + debug("MXS SPI: Timeout waiting for data\n"); return -ETIMEDOUT; }
@@ -104,7 +104,7 @@ static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv,
if (mxs_wait_mask_clr(&ssp_regs->hw_ssp_ctrl0_reg, SSP_CTRL0_RUN, MXS_SPI_MAX_TIMEOUT)) { - printf("MXS SPI: Timeout waiting for finish\n"); + debug("MXS SPI: Timeout waiting for finish\n"); return -ETIMEDOUT; } } @@ -233,78 +233,6 @@ static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, return ret; }
-static int __spi_xfer(struct mxs_spi_priv *priv, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct mxs_ssp_regs *ssp_regs = priv->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(priv, data, len, write, flags); - } else { - writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set); - return mxs_spi_xfer_dma(priv, data, len, write, flags); - } -} - -static int __mxs_spi_setup(struct mxs_spi_priv *mxs_spi, uint bus) -{ - struct mxs_spi_priv *priv = mxs_spi; - int err; - - priv->max_khz = max_hz / 1000; - priv->mode = mode; - priv->regs = mxs_ssp_regs_by_bus(bus); - priv->bus = bus; - - if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->bus)) { - printf("%s: DMA init channel error %d\n", __func__, err); - return err; - } - - return 0; -} - static int mxs_spi_claim_bus(struct udevice *dev) { struct udevice *bus = dev_get_parent(dev); @@ -321,8 +249,6 @@ static int mxs_spi_claim_bus(struct udevice *dev)
static int mxs_spi_release_bus(struct udevice *dev) { - /* TODO */ - return 0; }
@@ -335,7 +261,7 @@ static int mxs_spi_set_speed(struct udevice *bus, uint speed) speed = plat->max_khz;
priv->max_khz = speed; - printf("%s speed %u\n", __func__, speed); + debug("%s speed %u\n", __func__, speed);
mxs_set_ssp_busclock(plat->bus, priv->max_khz);
@@ -348,8 +274,8 @@ static int mxs_spi_set_mode(struct udevice *bus, uint mode) struct mxs_ssp_regs *ssp_regs = priv->regs; u32 reg;
- printf("%s mode %u\n", __func__, mode); priv->mode = mode; + debug("%s mode %u\n", __func__, mode);
reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS; reg |= (priv->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0; @@ -367,24 +293,83 @@ static int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen, { struct udevice *bus = dev_get_parent(dev); struct mxs_spi_priv *priv = dev_get_priv(bus); + struct mxs_ssp_regs *ssp_regs = priv->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; + }
- return __spi_xfer(priv, bitlen, dout, din, flags); + /* + * 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(priv, data, len, write, flags); + } else { + writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set); + return mxs_spi_xfer_dma(priv, data, len, write, flags); + } +} + +static int mxs_spi_cs_info(struct udevice *bus, uint cs, + struct spi_cs_info *info) +{ + struct mxs_spi_priv *priv = dev_get_priv(bus); + + if (cs >= priv->cs) { + printf("%s: no cs %u\n", __func__, cs); + return -ENODEV; + } + + return 0; }
static int mxs_spi_probe(struct udevice *dev) { struct mxs_spi_platdata *plat = dev_get_platdata(dev); struct mxs_spi_priv *priv = dev_get_priv(bus); - struct mxs_spi_priv *priv = mxs_spi; int err;
- priv->max_khz = max_hz / 1000; - priv->mode = mode; - priv->bus = bus; - priv->regs = mxs_ssp_regs_by_bus(bus); + priv->max_khz = (plat->max_hz) / 1000; + priv->mode = plat->mode; + priv->bus = plat->bus;
- if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->bus)) { - printf("%s: DMA init channel error %d\n", __func__, err); + err = mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->bus); + if (err) { + debug("%s: DMA init channel error %d\n", __func__, err); return err; }
@@ -397,21 +382,29 @@ static const struct dm_spi_ops mxs_spi_ops = { .xfer = mxs_spi_xfer, .set_speed = mxs_spi_set_speed, .set_mode = mxs_spi_set_mode, + .cs_info = mxs_spi_cs_info, };
#if CONFIG_IS_ENABLED(OF_CONTROL) static int mxs_ofdata_to_platadata(struct udevice *bus) { struct mxs_spi_platdata *plat = bus->platdata; + fdt_addr_t addr; + + addr = devfdt_get_addr(bus); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL;
+ plat->regs = (struct mxs_ssp_regs *)addr; plat->cs = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), "num-cs", 4);
return 0; }
+/* TODO: update compatible device tree */ static const struct udevice_id mxs_spi_ids[] = { - { .compatible = "fsl,mxs-spi" }, + { .compatible = " " }, { } }; #endif