[U-Boot] [PATCH v1 1/1] spi: lpc32xx_ssp: DM conversion

Jagan Teki jagan at amarulasolutions.com
Tue Sep 4 06:33:16 UTC 2018


On Wed, May 9, 2018 at 12:37 PM, Akash Gajjar <gajjar04akash at gmail.com> wrote:
> From: Akash Gajjar <gajjar04akash at gmail.com>
>
> This patch adds support for DM to the LPC32xx SSP SPI driver.
>
> Some TODOs are left over for later, These would be enhancements to the
> original functionality, and can come later. The legacy functionality is
> removed in this version.
>
> Signed-off-by: Akash Gajjar <akash at openedev.com>
> ---
>  drivers/spi/Kconfig                        |  10 +-
>  drivers/spi/lpc32xx_ssp.c                  | 145 +++++++++++++++--------------
>  include/dm/platform_data/spi_lpc32xx_ssp.h |  15 +++
>  3 files changed, 93 insertions(+), 77 deletions(-)
>  create mode 100644 include/dm/platform_data/spi_lpc32xx_ssp.h
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index ec92b84..2297d4a 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -99,6 +99,11 @@ config ICH_SPI
>           access the SPI NOR flash on platforms embedding this Intel
>           ICH IP core.
>
> +config LPC32XX_SSP
> +       bool "LPC32XX SPI Driver"
> +       help
> +         Enable support for SPI on LPC32xx
> +
>  config MVEBU_A3700_SPI
>         bool "Marvell Armada 3700 SPI driver"
>         help
> @@ -277,11 +282,6 @@ config KIRKWOOD_SPI
>           Enable support for SPI on various Marvell SoCs, such as
>           Kirkwood and Armada 375.
>
> -config LPC32XX_SSP
> -       bool "LPC32XX SPI Driver"
> -       help
> -         Enable support for SPI on LPC32xx
> -
>  config MPC8XX_SPI
>         bool "MPC8XX SPI Driver"
>         depends on MPC8xx
> diff --git a/drivers/spi/lpc32xx_ssp.c b/drivers/spi/lpc32xx_ssp.c
> index e2a593b..ae41b57 100644
> --- a/drivers/spi/lpc32xx_ssp.c
> +++ b/drivers/spi/lpc32xx_ssp.c
> @@ -4,6 +4,9 @@
>   * (C) Copyright 2014  DENX Software Engineering GmbH
>   * Written-by: Albert ARIBAUD <albert.aribaud at 3adev.fr>
>   *
> + * Support for device model:
> + * Copyright (C) 2018 Akash Gajjar <akash at openedev.com>
> + *
>   * SPDX-License-Identifier:     GPL-2.0+
>   */
>
> @@ -13,6 +16,8 @@
>  #include <malloc.h>
>  #include <spi.h>
>  #include <asm/arch/clk.h>
> +#include <dm.h>
> +#include <dm/platform_data/spi_lpc32xx_ssp.h>
>
>  /* SSP chip registers */
>  struct ssp_regs {
> @@ -36,90 +41,36 @@ struct ssp_regs {
>  /* SSP status RX FIFO not empty bit */
>  #define SSP_SR_RNE 0x0004
>
> -/* lpc32xx spi slave */
> -struct lpc32xx_spi_slave {
> -       struct spi_slave slave;
> +struct lpc32xx_ssp_spi_priv {
>         struct ssp_regs *regs;
>  };
>
> -static inline struct lpc32xx_spi_slave *to_lpc32xx_spi_slave(
> -       struct spi_slave *slave)
> +static int lpc32xx_ssp_spi_claim_bus(struct udevice *dev)
>  {
> -       return container_of(slave, struct lpc32xx_spi_slave, slave);
> -}
> -
> -/* spi_init is called during boot when CONFIG_CMD_SPI is defined */
> -void spi_init(void)
> -{
> -       /*
> -        *  nothing to do: clocking was enabled in lpc32xx_ssp_enable()
> -        * and configuration will be done in spi_setup_slave()
> -       */
> +       return 0;
>  }
>
> -/* the following is called in sequence by do_spi_xfer() */
> -
> -struct spi_slave *spi_setup_slave(uint bus, uint cs, uint max_hz, uint mode)
> +static int lpc32xx_ssp_spi_release_bus(struct udevice *dev)
>  {
> -       struct lpc32xx_spi_slave *lslave;
> -
> -       /* we only set up SSP0 for now, so ignore bus */
> -
> -       if (mode & SPI_3WIRE) {
> -               pr_err("3-wire mode not supported");
> -               return NULL;
> -       }
> -
> -       if (mode & SPI_SLAVE) {
> -               pr_err("slave mode not supported\n");
> -               return NULL;
> -       }
> -
> -       if (mode & SPI_PREAMBLE) {
> -               pr_err("preamble byte skipping not supported\n");
> -               return NULL;
> -       }
> -
> -       lslave = spi_alloc_slave(struct lpc32xx_spi_slave, bus, cs);
> -       if (!lslave) {
> -               printf("SPI_error: Fail to allocate lpc32xx_spi_slave\n");
> -               return NULL;
> -       }
> -
> -       lslave->regs = (struct ssp_regs *)SSP0_BASE;
> -
> -       /*
> -        * 8 bit frame, SPI fmt, 500kbps -> clock divider is 26.
> -        * Set SCR to 0 and CPSDVSR to 26.
> -        */
> -
> -       writel(0x7, &lslave->regs->cr0); /* 8-bit chunks, SPI, 1 clk/bit */
> -       writel(26, &lslave->regs->cpsr); /* SSP clock = HCLK/26 = 500kbps */
> -       writel(0, &lslave->regs->imsc); /* do not raise any interrupts */
> -       writel(0, &lslave->regs->icr); /* clear any pending interrupt */
> -       writel(0, &lslave->regs->dmacr); /* do not do DMAs */
> -       writel(SSP_CR1_SSP_ENABLE, &lslave->regs->cr1); /* enable SSP0 */
> -       return &lslave->slave;
> +       return 0;
>  }
>
> -void spi_free_slave(struct spi_slave *slave)
> +static int lpc32xx_ssp_spi_set_speed(struct udevice *bus, uint hz)
>  {
> -       struct lpc32xx_spi_slave *lslave = to_lpc32xx_spi_slave(slave);
> -
> -       debug("(lpc32xx) spi_free_slave: 0x%08x\n", (u32)lslave);
> -       free(lslave);
> +       return 0;
>  }
>
> -int spi_claim_bus(struct spi_slave *slave)
> +static int lpc32xx_ssp_spi_set_mode(struct udevice *bus, uint mode)
>  {
> -       /* only one bus and slave so far, always available */
>         return 0;
>  }
>
> -int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
> -       const void *dout, void *din, unsigned long flags)
> +static int lpc32xx_ssp_spi_xfer(struct udevice *dev, uint bitlen,
> +                               const void *dout, void *din, ulong flags)
>  {
> -       struct lpc32xx_spi_slave *lslave = to_lpc32xx_spi_slave(slave);
> +       struct udevice *bus = dev->parent;
> +       struct lpc32xx_ssp_priv *priv = dev_get_priv(bus);
> +       struct ssp_regs *regs = priv->regs;
>         int bytelen = bitlen >> 3;
>         int idx_out = 0;
>         int idx_in = 0;
> @@ -127,18 +78,68 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
>
>         start_time = get_timer(0);
>         while ((idx_out < bytelen) || (idx_in < bytelen)) {
> -               int status = readl(&lslave->regs->sr);
> +               int status = readl(&regs->sr);
>                 if ((idx_out < bytelen) && (status & SSP_SR_TNF))
> -                       writel(((u8 *)dout)[idx_out++], &lslave->regs->data);
> +                       writel(((u8 *)dout)[idx_out++], &regs->data);
>                 if ((idx_in < bytelen) && (status & status & SSP_SR_RNE))
> -                       ((u8 *)din)[idx_in++] = readl(&lslave->regs->data);
> +                       ((u8 *)din)[idx_in++] = readl(&regs->data);
>                 if (get_timer(start_time) >= CONFIG_LPC32XX_SSP_TIMEOUT)
>                         return -1;
>         }
> +
> +       return 0;
> +}
> +
> +static int lpc32xx_ssp_spi_probe(struct udevice *bus)
> +{
> +       struct lpc32xx_ssp_spi_platdata *plat = bus->platdata;
> +       struct lpc32xx_ssp_spi_priv = dev_get_priv(bus);
> +
> +       priv->regs = plat->regs;
> +
>         return 0;
>  }
>
> -void spi_release_bus(struct spi_slave *slave)
> +static const struct dm_spi_ops lpc32xx_ssp_spi_ops = {
> +       .claim_bus      = lpc32xx_ssp_spi_claim_bus,
> +       .release_bus    = lpc32xx_ssp_spi_release_bus,
> +       .xfer           = lpc32xx_ssp_spi_xfer,
> +       .set_speed      = lpc32xx_ssp_spi_set_speed,
> +       .set_mode       = lpc32xx_ssp_spi_set_mode,
> +};
> +
> +#if CONFIG_IS_ENABLED(OF_CONTROL)
> +static int lpc32xx_ssp_spi_ofdata_to_platadata(struct udevice *bus)
>  {
> -       /* do nothing */
> +       struct lpc32xx_ssp_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 struct ssp_regs *)addr;
> +
> +       return 0;
>  }
> +
> +/* TODO: update compatibel device tree */
> +static const struct udevice_id lpc32xx_ssp_spi_ids[] = {
> +       { .compatible = "" },

Don't we have DTS for this platform on Linux?


More information about the U-Boot mailing list