diff mbox

[U-Boot,3/3] spi: add common spi3 controller driver

Message ID 1402037062-4133-3-git-send-email-scott.jiang.linux@gmail.com
State Superseded
Delegated to: Jagannadha Sutradharudu Teki
Headers show

Commit Message

Scott Jiang June 6, 2014, 6:44 a.m. UTC
SPI3 controller is not only used on BF609 platform. So we add a common controller
driver and leave machine specific configuration in board drivers.
Remove obsolete spi6xx.h and select new board driver in configuration file.

Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com>
---
 drivers/spi/Makefile                               |    1 +
 drivers/spi/adi_spi3.c                             |  222 ++++++++++++++++
 .../bits/spi6xx.h => drivers/spi/adi_spi3.h        |   25 +-
 drivers/spi/bfin_spi6xx.c                          |  279 ++------------------
 include/configs/bf609-ezkit.h                      |    1 +
 5 files changed, 260 insertions(+), 268 deletions(-)
 create mode 100644 drivers/spi/adi_spi3.c
 rename arch/blackfin/include/asm/mach-common/bits/spi6xx.h => drivers/spi/adi_spi3.h (96%)

Comments

Jagan Teki June 9, 2014, 8:36 a.m. UTC | #1
On Fri, Jun 6, 2014 at 12:14 PM, Scott Jiang
<scott.jiang.linux@gmail.com> wrote:
> SPI3 controller is not only used on BF609 platform. So we add a common controller
> driver and leave machine specific configuration in board drivers.
> Remove obsolete spi6xx.h and select new board driver in configuration file.
>
> Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com>
> ---
>  drivers/spi/Makefile                               |    1 +
>  drivers/spi/adi_spi3.c                             |  222 ++++++++++++++++
>  .../bits/spi6xx.h => drivers/spi/adi_spi3.h        |   25 +-
>  drivers/spi/bfin_spi6xx.c                          |  279 ++------------------
>  include/configs/bf609-ezkit.h                      |    1 +
>  5 files changed, 260 insertions(+), 268 deletions(-)
>  create mode 100644 drivers/spi/adi_spi3.c
>  rename arch/blackfin/include/asm/mach-common/bits/spi6xx.h => drivers/spi/adi_spi3.h (96%)
>
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 81b6af6..0ce6fc9 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
>  obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
>  obj-$(CONFIG_BFIN_SPI) += bfin_spi.o
>  obj-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o
> +obj-$(CONFIG_ADI_SPI3) += adi_spi3.o
>  obj-$(CONFIG_CF_SPI) += cf_spi.o
>  obj-$(CONFIG_CF_QSPI) += cf_qspi.o
>  obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
> diff --git a/drivers/spi/adi_spi3.c b/drivers/spi/adi_spi3.c
> new file mode 100644
> index 0000000..41cd36c
> --- /dev/null
> +++ b/drivers/spi/adi_spi3.c
> @@ -0,0 +1,222 @@
> +/*
> + * Analog Devices SPI3 controller driver
> + *
> + * Copyright (c) 2014 Analog Devices Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <common.h>
> +#include <malloc.h>
> +#include <spi.h>
> +#include <asm/io.h>
> +#include <asm/gpio.h>
> +#include <asm/clock.h>
> +#include "adi_spi3.h"
> +
> +#define to_adi_spi_slave(s) container_of(s, struct adi_spi_slave, slave)
> +
> +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
> +{
> +       if (is_gpio_cs(cs))
> +               return gpio_is_valid(gpio_cs(cs));
> +       else
> +               return adi_spi_cs_valid(bus, cs);
> +}
> +
> +void spi_cs_activate(struct spi_slave *slave)
> +{
> +       struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
> +
> +       if (is_gpio_cs(slave->cs)) {
> +               unsigned int cs = gpio_cs(slave->cs);
> +               gpio_set_value(cs, sdev->cs_pol);
> +       } else {
> +               u32 ssel;
> +               ssel = readl(&sdev->regs->ssel);
> +               ssel |= 1 << slave->cs;
> +               if (sdev->cs_pol)
> +                       ssel |= (1 << 8) << slave->cs;


(1 << 8) macro here!

> +               else
> +                       ssel &= ~((1 << 8) << slave->cs);

(1 << 8) macro here!

> +               writel(ssel, &sdev->regs->ssel);
> +       }
> +}
> +
> +void spi_cs_deactivate(struct spi_slave *slave)
> +{
> +       struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
> +
> +       if (is_gpio_cs(slave->cs)) {
> +               unsigned int cs = gpio_cs(slave->cs);
> +               gpio_set_value(cs, !sdev->cs_pol);
> +               gpio_set_value(cs, 1);
> +       } else {
> +               u32 ssel;
> +               ssel = readl(&sdev->regs->ssel);
> +               if (sdev->cs_pol)
> +                       ssel &= ~((1 << 8) << slave->cs);
> +               else
> +                       ssel |= (1 << 8) << slave->cs;

Change numeric to reg bit macro's

> +               /* deassert cs */
> +               writel(ssel, &sdev->regs->ssel);
> +               /* disable cs */
> +               ssel &= ~(1 << slave->cs);
> +               writel(ssel, &sdev->regs->ssel);
> +       }
> +}
> +
> +void spi_init()
> +{
> +}
> +
> +void spi_set_speed(struct spi_slave *slave, uint hz)
> +{
> +       struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
> +       u32 clock;
> +
> +       clock = get_spi_clk() / hz;
> +       if (clock)
> +               clock--;
> +       sdev->clock = clock;
> +}
> +
> +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
> +               unsigned int max_hz, unsigned int mode)
> +{
> +       struct adi_spi_slave *sdev;
> +
> +       if (!spi_cs_is_valid(bus, cs))
> +               return NULL;
> +
> +       if (max_hz > get_spi_clk())
> +               return NULL;
> +
> +       sdev = adi_spi_setup(bus, cs);
> +       if (!sdev)
> +               return NULL;
> +
> +       sdev->control = SPI_CTL_EN | SPI_CTL_MSTR;
> +       if (mode & SPI_CPHA)
> +               sdev->control |= SPI_CTL_CPHA;
> +       if (mode & SPI_CPOL)
> +               sdev->control |= SPI_CTL_CPOL;
> +       if (mode & SPI_LSB_FIRST)
> +               sdev->control |= SPI_CTL_LSBF;
> +       sdev->control &= ~SPI_CTL_ASSEL;
> +       sdev->cs_pol = mode & SPI_CS_HIGH ? 1 : 0;
> +       spi_set_speed(&sdev->slave, max_hz);
> +
> +       return &sdev->slave;
> +}
> +
> +void spi_free_slave(struct spi_slave *slave)
> +{
> +       struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
> +       free(sdev);
> +}
> +
> +int spi_claim_bus(struct spi_slave *slave)
> +{
> +       struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
> +
> +       debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
> +
> +       if (is_gpio_cs(slave->cs)) {
> +               unsigned int cs = gpio_cs(slave->cs);
> +               gpio_request(cs, "adi-spi3");
> +               gpio_direction_output(cs, !sdev->cs_pol);
> +               sdev->pins[0] = P_DONTCARE;
> +       }
> +       peripheral_request_list(sdev->pins, "adi-spi3");
> +
> +       writel(sdev->control, &sdev->regs->control);
> +       writel(sdev->clock, &sdev->regs->clock);
> +       writel(0x0, &sdev->regs->delay);
> +       writel(SPI_RXCTL_REN, &sdev->regs->rx_control);
> +       writel(SPI_TXCTL_TEN | SPI_TXCTL_TTI, &sdev->regs->tx_control);
> +
> +       return 0;
> +}
> +
> +void spi_release_bus(struct spi_slave *slave)
> +{
> +       struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
> +
> +       debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
> +
> +       peripheral_free_list(sdev->pins);
> +       if (is_gpio_cs(slave->cs))
> +               gpio_free(gpio_cs(slave->cs));
> +
> +       writel(0x0, &sdev->regs->rx_control);
> +       writel(0x0, &sdev->regs->tx_control);
> +       writel(0x0, &sdev->regs->control);
> +}
> +
> +#ifndef CONFIG_SPI_IDLE_VAL
> +# define CONFIG_SPI_IDLE_VAL 0xff
> +#endif
> +
> +static int spi_pio_xfer(struct adi_spi_slave *sdev, const u8 *tx, u8 *rx,
> +                       uint bytes)
> +{
> +       /* discard invalid rx data and empty rfifo */
> +       while (!(readl(&sdev->regs->status) & SPI_STAT_RFE))
> +               readl(&sdev->regs->rfifo);
> +
> +       while (bytes--) {
> +               u8 value = (tx ? *tx++ : CONFIG_SPI_IDLE_VAL);
> +               debug("%s: tx:%x ", __func__, value);
> +               writel(value, &sdev->regs->tfifo);
> +               while (readl(&sdev->regs->status) & SPI_STAT_RFE)
> +                       if (ctrlc())
> +                               return -1;
> +               value = readl(&sdev->regs->rfifo);
> +               if (rx)
> +                       *rx++ = value;
> +               debug("rx:%x\n", value);
> +       }
> +
> +       return 0;
> +}
> +
> +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
> +               void *din, unsigned long flags)
> +{
> +       struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
> +       const u8 *tx = dout;
> +       u8 *rx = din;
> +       uint bytes = bitlen / 8;
> +       int ret = 0;
> +
> +       debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
> +               slave->bus, slave->cs, bitlen, bytes, flags);
> +
> +       if (bitlen == 0)
> +               goto done;
> +
> +       /* we can only do 8 bit transfers */
> +       if (bitlen % 8) {
> +               flags |= SPI_XFER_END;
> +               goto done;
> +       }
> +
> +       if (flags & SPI_XFER_BEGIN)
> +               spi_cs_activate(slave);
> +
> +       ret = spi_pio_xfer(sdev, tx, rx, bytes);
> +
> + done:
> +       if (flags & SPI_XFER_END)
> +               spi_cs_deactivate(slave);
> +
> +       return ret;
> +}
> diff --git a/arch/blackfin/include/asm/mach-common/bits/spi6xx.h b/drivers/spi/adi_spi3.h
> similarity index 96%
> rename from arch/blackfin/include/asm/mach-common/bits/spi6xx.h
> rename to drivers/spi/adi_spi3.h
> index 3368712..509d08a 100644
> --- a/arch/blackfin/include/asm/mach-common/bits/spi6xx.h
> +++ b/drivers/spi/adi_spi3.h
> @@ -1,7 +1,7 @@
>  /*
> - * Analog Devices bfin_spi3 controller driver
> + * Analog Devices SPI3 controller driver
>   *
> - * Copyright (c) 2011 Analog Devices Inc.
> + * Copyright (c) 2014 Analog Devices Inc.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -11,10 +11,6 @@
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
>   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>   * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>   */
>
>  #ifndef _SPI_CHANNEL_H_
> @@ -22,6 +18,10 @@
>
>  #include <linux/types.h>
>
> +#define MAX_CTRL_CS 7
> +#define gpio_cs(cs) ((cs) - MAX_CTRL_CS)
> +#define is_gpio_cs(cs) ((cs) > MAX_CTRL_CS)
> +
>  /* SPI_CONTROL */
>  #define SPI_CTL_EN          0x00000001 /* Enable */
>  #define SPI_CTL_MSTR        0x00000002 /* Master/Slave */
> @@ -211,7 +211,7 @@
>  /*
>   * bfin spi3 registers layout
>   */
> -struct bfin_spi_regs {
> +struct spi_regs {
>         u32 revid;
>         u32 control;
>         u32 rx_control;
> @@ -237,4 +237,15 @@ struct bfin_spi_regs {
>         u32 tfifo;
>  };
>
> +struct adi_spi_slave {
> +       struct spi_slave slave;
> +       u32 control, clock;
> +       struct spi_regs *regs;
> +       unsigned short *pins;
> +       int cs_pol;
> +};
> +
> +extern int adi_spi_cs_valid(unsigned int bus, unsigned int cs);
> +extern struct adi_spi_slave *adi_spi_setup(unsigned int bus, unsigned int cs);
> +
>  #endif /* _SPI_CHANNEL_H_ */
> diff --git a/drivers/spi/bfin_spi6xx.c b/drivers/spi/bfin_spi6xx.c
> index eba01d1..39573d1 100644
> --- a/drivers/spi/bfin_spi6xx.c
> +++ b/drivers/spi/bfin_spi6xx.c
> @@ -1,7 +1,7 @@
>  /*
> - * Analog Devices SPI3 controller driver
> + * Analog Devices bf609 spi driver
>   *
> - * Copyright (c) 2011 Analog Devices Inc.
> + * Copyright (c) 2014 Analog Devices Inc.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -11,108 +11,19 @@
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
>   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>   * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>   */
>
>  #include <common.h>
> -#include <malloc.h>
>  #include <spi.h>
> -
> -#include <asm/blackfin.h>
> -#include <asm/clock.h>
> -#include <asm/gpio.h>
>  #include <asm/portmux.h>
> -#include <asm/mach-common/bits/spi6xx.h>
> -
> -struct bfin_spi_slave {
> -       struct spi_slave slave;
> -       u32 control, clock;
> -       struct bfin_spi_regs *regs;
> -       int cs_pol;
> -};
> -
> -#define to_bfin_spi_slave(s) container_of(s, struct bfin_spi_slave, slave)
> -
> -#define gpio_cs(cs) ((cs) - MAX_CTRL_CS)
> -#ifdef CONFIG_BFIN_SPI_GPIO_CS
> -# define is_gpio_cs(cs) ((cs) > MAX_CTRL_CS)
> -#else
> -# define is_gpio_cs(cs) 0
> -#endif
> -
> -int spi_cs_is_valid(unsigned int bus, unsigned int cs)
> -{
> -       if (is_gpio_cs(cs))
> -               return gpio_is_valid(gpio_cs(cs));
> -       else
> -               return (cs >= 1 && cs <= MAX_CTRL_CS);
> -}
>
> -void spi_cs_activate(struct spi_slave *slave)
> -{
> -       struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
> -
> -       if (is_gpio_cs(slave->cs)) {
> -               unsigned int cs = gpio_cs(slave->cs);
> -               gpio_set_value(cs, bss->cs_pol);
> -       } else {
> -               u32 ssel;
> -               ssel = bfin_read32(&bss->regs->ssel);
> -               ssel |= 1 << slave->cs;
> -               if (bss->cs_pol)
> -                       ssel |= (1 << 8) << slave->cs;
> -               else
> -                       ssel &= ~((1 << 8) << slave->cs);
> -               bfin_write32(&bss->regs->ssel, ssel);
> -       }
> -
> -       SSYNC();
> -}
> -
> -void spi_cs_deactivate(struct spi_slave *slave)
> -{
> -       struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
> -
> -       if (is_gpio_cs(slave->cs)) {
> -               unsigned int cs = gpio_cs(slave->cs);
> -               gpio_set_value(cs, !bss->cs_pol);
> -       } else {
> -               u32 ssel;
> -               ssel = bfin_read32(&bss->regs->ssel);
> -               if (bss->cs_pol)
> -                       ssel &= ~((1 << 8) << slave->cs);
> -               else
> -                       ssel |= (1 << 8) << slave->cs;
> -               /* deassert cs */
> -               bfin_write32(&bss->regs->ssel, ssel);
> -               SSYNC();
> -               /* disable cs */
> -               ssel &= ~(1 << slave->cs);
> -               bfin_write32(&bss->regs->ssel, ssel);
> -       }
> -
> -       SSYNC();
> -}
> -
> -void spi_init()
> -{
> -}
> +#include "adi_spi3.h"
>
>  #define SPI_PINS(n) \
>         { 0, P_SPI##n##_SCK, P_SPI##n##_MISO, P_SPI##n##_MOSI, 0 }
>  static unsigned short pins[][5] = {
> -#ifdef SPI0_REGBASE
>         [0] = SPI_PINS(0),
> -#endif
> -#ifdef SPI1_REGBASE
>         [1] = SPI_PINS(1),
> -#endif
> -#ifdef SPI2_REGBASE
> -       [2] = SPI_PINS(2),
> -#endif
>  };
>
>  #define SPI_CS_PINS(n) \
> @@ -122,183 +33,29 @@ static unsigned short pins[][5] = {
>                 P_SPI##n##_SSEL7, \
>         }
>  static const unsigned short cs_pins[][7] = {
> -#ifdef SPI0_REGBASE
>         [0] = SPI_CS_PINS(0),
> -#endif
> -#ifdef SPI1_REGBASE
>         [1] = SPI_CS_PINS(1),
> -#endif
> -#ifdef SPI2_REGBASE
> -       [2] = SPI_CS_PINS(2),
> -#endif
>  };
>
> -void spi_set_speed(struct spi_slave *slave, uint hz)
> +int adi_spi_cs_valid(unsigned int bus, unsigned int cs)
>  {
> -       struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
> -       ulong clk;
> -       u32 clock;
> -
> -       clk = get_spi_clk();
> -       clock = clk / hz;
> -       if (clock)
> -               clock--;
> -       bss->clock = clock;
> +       if (bus > 1)
> +               return 0;
> +       return cs >= 1 && cs <= MAX_CTRL_CS;
>  }
>
> -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
> -               unsigned int max_hz, unsigned int mode)
> +struct adi_spi_slave *adi_spi_setup(unsigned int bus, unsigned int cs)
>  {
> -       struct bfin_spi_slave *bss;
> -       u32 reg_base;
> -
> -       if (!spi_cs_is_valid(bus, cs))
> -               return NULL;
> -
> -       switch (bus) {
> -#ifdef SPI0_REGBASE
> -       case 0:
> -               reg_base = SPI0_REGBASE;
> -               break;
> -#endif
> -#ifdef SPI1_REGBASE
> -       case 1:
> -               reg_base = SPI1_REGBASE;
> -               break;
> -#endif
> -#ifdef SPI2_REGBASE
> -       case 2:
> -               reg_base = SPI2_REGBASE;
> -               break;
> -#endif
> -       default:
> -               debug("%s: invalid bus %u\n", __func__, bus);
> -               return NULL;
> -       }
> -
> -       bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
> -       if (!bss)
> -               return NULL;
> -
> -       bss->regs = (struct bfin_spi_regs *)reg_base;
> -       bss->control = SPI_CTL_EN | SPI_CTL_MSTR;
> -       if (mode & SPI_CPHA)
> -               bss->control |= SPI_CTL_CPHA;
> -       if (mode & SPI_CPOL)
> -               bss->control |= SPI_CTL_CPOL;
> -       if (mode & SPI_LSB_FIRST)
> -               bss->control |= SPI_CTL_LSBF;
> -       bss->control &= ~SPI_CTL_ASSEL;
> -       bss->cs_pol = mode & SPI_CS_HIGH ? 1 : 0;
> -       spi_set_speed(&bss->slave, max_hz);
> -
> -       return &bss->slave;
> -}
> +       struct adi_spi_slave *sdev;
>
> -void spi_free_slave(struct spi_slave *slave)
> -{
> -       struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
> -       free(bss);
> -}
> -
> -int spi_claim_bus(struct spi_slave *slave)
> -{
> -       struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
> -
> -       debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
> -
> -       if (is_gpio_cs(slave->cs)) {
> -               unsigned int cs = gpio_cs(slave->cs);
> -               gpio_request(cs, "bfin-spi");
> -               gpio_direction_output(cs, !bss->cs_pol);
> -               pins[slave->bus][0] = P_DONTCARE;
> -       } else
> -               pins[slave->bus][0] = cs_pins[slave->bus][slave->cs - 1];
> -       peripheral_request_list(pins[slave->bus], "bfin-spi");
> -
> -       bfin_write32(&bss->regs->control, bss->control);
> -       bfin_write32(&bss->regs->clock, bss->clock);
> -       bfin_write32(&bss->regs->delay, 0x0);
> -       bfin_write32(&bss->regs->rx_control, SPI_RXCTL_REN);
> -       bfin_write32(&bss->regs->tx_control, SPI_TXCTL_TEN | SPI_TXCTL_TTI);
> -       SSYNC();
> -
> -       return 0;
> -}
> -
> -void spi_release_bus(struct spi_slave *slave)
> -{
> -       struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
> -
> -       debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
> -
> -       peripheral_free_list(pins[slave->bus]);
> -       if (is_gpio_cs(slave->cs))
> -               gpio_free(gpio_cs(slave->cs));
> -
> -       bfin_write32(&bss->regs->rx_control, 0x0);
> -       bfin_write32(&bss->regs->tx_control, 0x0);
> -       bfin_write32(&bss->regs->control, 0x0);
> -       SSYNC();
> -}
> -
> -#ifndef CONFIG_BFIN_SPI_IDLE_VAL
> -# define CONFIG_BFIN_SPI_IDLE_VAL 0xff
> -#endif
> -
> -static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx,
> -                       uint bytes)
> -{
> -       /* discard invalid rx data and empty rfifo */
> -       while (!(bfin_read32(&bss->regs->status) & SPI_STAT_RFE))
> -               bfin_read32(&bss->regs->rfifo);
> -
> -       while (bytes--) {
> -               u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL);
> -               debug("%s: tx:%x ", __func__, value);
> -               bfin_write32(&bss->regs->tfifo, value);
> -               SSYNC();
> -               while (bfin_read32(&bss->regs->status) & SPI_STAT_RFE)
> -                       if (ctrlc())
> -                               return -1;
> -               value = bfin_read32(&bss->regs->rfifo);
> -               if (rx)
> -                       *rx++ = value;
> -               debug("rx:%x\n", value);
> -       }
> -
> -       return 0;
> -}
> -
> -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
> -               void *din, unsigned long flags)
> -{
> -       struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
> -       const u8 *tx = dout;
> -       u8 *rx = din;
> -       uint bytes = bitlen / 8;
> -       int ret = 0;
> -
> -       debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
> -               slave->bus, slave->cs, bitlen, bytes, flags);
> -
> -       if (bitlen == 0)
> -               goto done;
> -
> -       /* we can only do 8 bit transfers */
> -       if (bitlen % 8) {
> -               flags |= SPI_XFER_END;
> -               goto done;
> +       sdev = spi_alloc_slave(struct adi_spi_slave, bus, cs);
> +       if (sdev) {
> +               if (bus)
> +                       sdev->regs = (struct spi_regs *)SPI1_REGBASE;
> +               else
> +                       sdev->regs = (struct spi_regs *)SPI0_REGBASE;
> +               pins[bus][0] = cs_pins[bus][cs - 1];
> +               sdev->pins = pins[bus];
>         }
> -
> -       if (flags & SPI_XFER_BEGIN)
> -               spi_cs_activate(slave);
> -
> -       ret = spi_pio_xfer(bss, tx, rx, bytes);
> -
> - done:
> -       if (flags & SPI_XFER_END)
> -               spi_cs_deactivate(slave);
> -
> -       return ret;
> +       return sdev;
>  }
> diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h
> index 12192ff..839ebe7 100644
> --- a/include/configs/bf609-ezkit.h
> +++ b/include/configs/bf609-ezkit.h
> @@ -101,6 +101,7 @@
>  /*
>   * SPI Settings
>   */
> +#define CONFIG_ADI_SPI3
>  #define CONFIG_BFIN_SPI6XX
>  #define CONFIG_ENV_SPI_MAX_HZ  25000000
>  #define CONFIG_SF_DEFAULT_SPEED        25000000
> --
> 1.7.9.5
>
>


thanks!
diff mbox

Patch

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 81b6af6..0ce6fc9 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -15,6 +15,7 @@  obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
 obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
 obj-$(CONFIG_BFIN_SPI) += bfin_spi.o
 obj-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o
+obj-$(CONFIG_ADI_SPI3) += adi_spi3.o
 obj-$(CONFIG_CF_SPI) += cf_spi.o
 obj-$(CONFIG_CF_QSPI) += cf_qspi.o
 obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
diff --git a/drivers/spi/adi_spi3.c b/drivers/spi/adi_spi3.c
new file mode 100644
index 0000000..41cd36c
--- /dev/null
+++ b/drivers/spi/adi_spi3.c
@@ -0,0 +1,222 @@ 
+/*
+ * Analog Devices SPI3 controller driver
+ *
+ * Copyright (c) 2014 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/clock.h>
+#include "adi_spi3.h"
+
+#define to_adi_spi_slave(s) container_of(s, struct adi_spi_slave, slave)
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	if (is_gpio_cs(cs))
+		return gpio_is_valid(gpio_cs(cs));
+	else
+		return adi_spi_cs_valid(bus, cs);
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+	struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
+
+	if (is_gpio_cs(slave->cs)) {
+		unsigned int cs = gpio_cs(slave->cs);
+		gpio_set_value(cs, sdev->cs_pol);
+	} else {
+		u32 ssel;
+		ssel = readl(&sdev->regs->ssel);
+		ssel |= 1 << slave->cs;
+		if (sdev->cs_pol)
+			ssel |= (1 << 8) << slave->cs;
+		else
+			ssel &= ~((1 << 8) << slave->cs);
+		writel(ssel, &sdev->regs->ssel);
+	}
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
+
+	if (is_gpio_cs(slave->cs)) {
+		unsigned int cs = gpio_cs(slave->cs);
+		gpio_set_value(cs, !sdev->cs_pol);
+		gpio_set_value(cs, 1);
+	} else {
+		u32 ssel;
+		ssel = readl(&sdev->regs->ssel);
+		if (sdev->cs_pol)
+			ssel &= ~((1 << 8) << slave->cs);
+		else
+			ssel |= (1 << 8) << slave->cs;
+		/* deassert cs */
+		writel(ssel, &sdev->regs->ssel);
+		/* disable cs */
+		ssel &= ~(1 << slave->cs);
+		writel(ssel, &sdev->regs->ssel);
+	}
+}
+
+void spi_init()
+{
+}
+
+void spi_set_speed(struct spi_slave *slave, uint hz)
+{
+	struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
+	u32 clock;
+
+	clock = get_spi_clk() / hz;
+	if (clock)
+		clock--;
+	sdev->clock = clock;
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+		unsigned int max_hz, unsigned int mode)
+{
+	struct adi_spi_slave *sdev;
+
+	if (!spi_cs_is_valid(bus, cs))
+		return NULL;
+
+	if (max_hz > get_spi_clk())
+		return NULL;
+
+	sdev = adi_spi_setup(bus, cs);
+	if (!sdev)
+		return NULL;
+
+	sdev->control = SPI_CTL_EN | SPI_CTL_MSTR;
+	if (mode & SPI_CPHA)
+		sdev->control |= SPI_CTL_CPHA;
+	if (mode & SPI_CPOL)
+		sdev->control |= SPI_CTL_CPOL;
+	if (mode & SPI_LSB_FIRST)
+		sdev->control |= SPI_CTL_LSBF;
+	sdev->control &= ~SPI_CTL_ASSEL;
+	sdev->cs_pol = mode & SPI_CS_HIGH ? 1 : 0;
+	spi_set_speed(&sdev->slave, max_hz);
+
+	return &sdev->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
+	free(sdev);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
+
+	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+
+	if (is_gpio_cs(slave->cs)) {
+		unsigned int cs = gpio_cs(slave->cs);
+		gpio_request(cs, "adi-spi3");
+		gpio_direction_output(cs, !sdev->cs_pol);
+		sdev->pins[0] = P_DONTCARE;
+	}
+	peripheral_request_list(sdev->pins, "adi-spi3");
+
+	writel(sdev->control, &sdev->regs->control);
+	writel(sdev->clock, &sdev->regs->clock);
+	writel(0x0, &sdev->regs->delay);
+	writel(SPI_RXCTL_REN, &sdev->regs->rx_control);
+	writel(SPI_TXCTL_TEN | SPI_TXCTL_TTI, &sdev->regs->tx_control);
+
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
+
+	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+
+	peripheral_free_list(sdev->pins);
+	if (is_gpio_cs(slave->cs))
+		gpio_free(gpio_cs(slave->cs));
+
+	writel(0x0, &sdev->regs->rx_control);
+	writel(0x0, &sdev->regs->tx_control);
+	writel(0x0, &sdev->regs->control);
+}
+
+#ifndef CONFIG_SPI_IDLE_VAL
+# define CONFIG_SPI_IDLE_VAL 0xff
+#endif
+
+static int spi_pio_xfer(struct adi_spi_slave *sdev, const u8 *tx, u8 *rx,
+			uint bytes)
+{
+	/* discard invalid rx data and empty rfifo */
+	while (!(readl(&sdev->regs->status) & SPI_STAT_RFE))
+		readl(&sdev->regs->rfifo);
+
+	while (bytes--) {
+		u8 value = (tx ? *tx++ : CONFIG_SPI_IDLE_VAL);
+		debug("%s: tx:%x ", __func__, value);
+		writel(value, &sdev->regs->tfifo);
+		while (readl(&sdev->regs->status) & SPI_STAT_RFE)
+			if (ctrlc())
+				return -1;
+		value = readl(&sdev->regs->rfifo);
+		if (rx)
+			*rx++ = value;
+		debug("rx:%x\n", value);
+	}
+
+	return 0;
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+		void *din, unsigned long flags)
+{
+	struct adi_spi_slave *sdev = to_adi_spi_slave(slave);
+	const u8 *tx = dout;
+	u8 *rx = din;
+	uint bytes = bitlen / 8;
+	int ret = 0;
+
+	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
+		slave->bus, slave->cs, bitlen, bytes, flags);
+
+	if (bitlen == 0)
+		goto done;
+
+	/* we can only do 8 bit transfers */
+	if (bitlen % 8) {
+		flags |= SPI_XFER_END;
+		goto done;
+	}
+
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(slave);
+
+	ret = spi_pio_xfer(sdev, tx, rx, bytes);
+
+ done:
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(slave);
+
+	return ret;
+}
diff --git a/arch/blackfin/include/asm/mach-common/bits/spi6xx.h b/drivers/spi/adi_spi3.h
similarity index 96%
rename from arch/blackfin/include/asm/mach-common/bits/spi6xx.h
rename to drivers/spi/adi_spi3.h
index 3368712..509d08a 100644
--- a/arch/blackfin/include/asm/mach-common/bits/spi6xx.h
+++ b/drivers/spi/adi_spi3.h
@@ -1,7 +1,7 @@ 
 /*
- * Analog Devices bfin_spi3 controller driver
+ * Analog Devices SPI3 controller driver
  *
- * Copyright (c) 2011 Analog Devices Inc.
+ * Copyright (c) 2014 Analog Devices Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,10 +11,6 @@ 
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _SPI_CHANNEL_H_
@@ -22,6 +18,10 @@ 
 
 #include <linux/types.h>
 
+#define MAX_CTRL_CS 7
+#define gpio_cs(cs) ((cs) - MAX_CTRL_CS)
+#define is_gpio_cs(cs) ((cs) > MAX_CTRL_CS)
+
 /* SPI_CONTROL */
 #define SPI_CTL_EN          0x00000001 /* Enable */
 #define SPI_CTL_MSTR        0x00000002 /* Master/Slave */
@@ -211,7 +211,7 @@ 
 /*
  * bfin spi3 registers layout
  */
-struct bfin_spi_regs {
+struct spi_regs {
 	u32 revid;
 	u32 control;
 	u32 rx_control;
@@ -237,4 +237,15 @@  struct bfin_spi_regs {
 	u32 tfifo;
 };
 
+struct adi_spi_slave {
+	struct spi_slave slave;
+	u32 control, clock;
+	struct spi_regs *regs;
+	unsigned short *pins;
+	int cs_pol;
+};
+
+extern int adi_spi_cs_valid(unsigned int bus, unsigned int cs);
+extern struct adi_spi_slave *adi_spi_setup(unsigned int bus, unsigned int cs);
+
 #endif /* _SPI_CHANNEL_H_ */
diff --git a/drivers/spi/bfin_spi6xx.c b/drivers/spi/bfin_spi6xx.c
index eba01d1..39573d1 100644
--- a/drivers/spi/bfin_spi6xx.c
+++ b/drivers/spi/bfin_spi6xx.c
@@ -1,7 +1,7 @@ 
 /*
- * Analog Devices SPI3 controller driver
+ * Analog Devices bf609 spi driver
  *
- * Copyright (c) 2011 Analog Devices Inc.
+ * Copyright (c) 2014 Analog Devices Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,108 +11,19 @@ 
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <common.h>
-#include <malloc.h>
 #include <spi.h>
-
-#include <asm/blackfin.h>
-#include <asm/clock.h>
-#include <asm/gpio.h>
 #include <asm/portmux.h>
-#include <asm/mach-common/bits/spi6xx.h>
-
-struct bfin_spi_slave {
-	struct spi_slave slave;
-	u32 control, clock;
-	struct bfin_spi_regs *regs;
-	int cs_pol;
-};
-
-#define to_bfin_spi_slave(s) container_of(s, struct bfin_spi_slave, slave)
-
-#define gpio_cs(cs) ((cs) - MAX_CTRL_CS)
-#ifdef CONFIG_BFIN_SPI_GPIO_CS
-# define is_gpio_cs(cs) ((cs) > MAX_CTRL_CS)
-#else
-# define is_gpio_cs(cs) 0
-#endif
-
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-	if (is_gpio_cs(cs))
-		return gpio_is_valid(gpio_cs(cs));
-	else
-		return (cs >= 1 && cs <= MAX_CTRL_CS);
-}
 
-void spi_cs_activate(struct spi_slave *slave)
-{
-	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
-
-	if (is_gpio_cs(slave->cs)) {
-		unsigned int cs = gpio_cs(slave->cs);
-		gpio_set_value(cs, bss->cs_pol);
-	} else {
-		u32 ssel;
-		ssel = bfin_read32(&bss->regs->ssel);
-		ssel |= 1 << slave->cs;
-		if (bss->cs_pol)
-			ssel |= (1 << 8) << slave->cs;
-		else
-			ssel &= ~((1 << 8) << slave->cs);
-		bfin_write32(&bss->regs->ssel, ssel);
-	}
-
-	SSYNC();
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
-
-	if (is_gpio_cs(slave->cs)) {
-		unsigned int cs = gpio_cs(slave->cs);
-		gpio_set_value(cs, !bss->cs_pol);
-	} else {
-		u32 ssel;
-		ssel = bfin_read32(&bss->regs->ssel);
-		if (bss->cs_pol)
-			ssel &= ~((1 << 8) << slave->cs);
-		else
-			ssel |= (1 << 8) << slave->cs;
-		/* deassert cs */
-		bfin_write32(&bss->regs->ssel, ssel);
-		SSYNC();
-		/* disable cs */
-		ssel &= ~(1 << slave->cs);
-		bfin_write32(&bss->regs->ssel, ssel);
-	}
-
-	SSYNC();
-}
-
-void spi_init()
-{
-}
+#include "adi_spi3.h"
 
 #define SPI_PINS(n) \
 	{ 0, P_SPI##n##_SCK, P_SPI##n##_MISO, P_SPI##n##_MOSI, 0 }
 static unsigned short pins[][5] = {
-#ifdef SPI0_REGBASE
 	[0] = SPI_PINS(0),
-#endif
-#ifdef SPI1_REGBASE
 	[1] = SPI_PINS(1),
-#endif
-#ifdef SPI2_REGBASE
-	[2] = SPI_PINS(2),
-#endif
 };
 
 #define SPI_CS_PINS(n) \
@@ -122,183 +33,29 @@  static unsigned short pins[][5] = {
 		P_SPI##n##_SSEL7, \
 	}
 static const unsigned short cs_pins[][7] = {
-#ifdef SPI0_REGBASE
 	[0] = SPI_CS_PINS(0),
-#endif
-#ifdef SPI1_REGBASE
 	[1] = SPI_CS_PINS(1),
-#endif
-#ifdef SPI2_REGBASE
-	[2] = SPI_CS_PINS(2),
-#endif
 };
 
-void spi_set_speed(struct spi_slave *slave, uint hz)
+int adi_spi_cs_valid(unsigned int bus, unsigned int cs)
 {
-	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
-	ulong clk;
-	u32 clock;
-
-	clk = get_spi_clk();
-	clock = clk / hz;
-	if (clock)
-		clock--;
-	bss->clock = clock;
+	if (bus > 1)
+		return 0;
+	return cs >= 1 && cs <= MAX_CTRL_CS;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-		unsigned int max_hz, unsigned int mode)
+struct adi_spi_slave *adi_spi_setup(unsigned int bus, unsigned int cs)
 {
-	struct bfin_spi_slave *bss;
-	u32 reg_base;
-
-	if (!spi_cs_is_valid(bus, cs))
-		return NULL;
-
-	switch (bus) {
-#ifdef SPI0_REGBASE
-	case 0:
-		reg_base = SPI0_REGBASE;
-		break;
-#endif
-#ifdef SPI1_REGBASE
-	case 1:
-		reg_base = SPI1_REGBASE;
-		break;
-#endif
-#ifdef SPI2_REGBASE
-	case 2:
-		reg_base = SPI2_REGBASE;
-		break;
-#endif
-	default:
-		debug("%s: invalid bus %u\n", __func__, bus);
-		return NULL;
-	}
-
-	bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
-	if (!bss)
-		return NULL;
-
-	bss->regs = (struct bfin_spi_regs *)reg_base;
-	bss->control = SPI_CTL_EN | SPI_CTL_MSTR;
-	if (mode & SPI_CPHA)
-		bss->control |= SPI_CTL_CPHA;
-	if (mode & SPI_CPOL)
-		bss->control |= SPI_CTL_CPOL;
-	if (mode & SPI_LSB_FIRST)
-		bss->control |= SPI_CTL_LSBF;
-	bss->control &= ~SPI_CTL_ASSEL;
-	bss->cs_pol = mode & SPI_CS_HIGH ? 1 : 0;
-	spi_set_speed(&bss->slave, max_hz);
-
-	return &bss->slave;
-}
+	struct adi_spi_slave *sdev;
 
-void spi_free_slave(struct spi_slave *slave)
-{
-	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
-	free(bss);
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
-
-	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
-
-	if (is_gpio_cs(slave->cs)) {
-		unsigned int cs = gpio_cs(slave->cs);
-		gpio_request(cs, "bfin-spi");
-		gpio_direction_output(cs, !bss->cs_pol);
-		pins[slave->bus][0] = P_DONTCARE;
-	} else
-		pins[slave->bus][0] = cs_pins[slave->bus][slave->cs - 1];
-	peripheral_request_list(pins[slave->bus], "bfin-spi");
-
-	bfin_write32(&bss->regs->control, bss->control);
-	bfin_write32(&bss->regs->clock, bss->clock);
-	bfin_write32(&bss->regs->delay, 0x0);
-	bfin_write32(&bss->regs->rx_control, SPI_RXCTL_REN);
-	bfin_write32(&bss->regs->tx_control, SPI_TXCTL_TEN | SPI_TXCTL_TTI);
-	SSYNC();
-
-	return 0;
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
-	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
-
-	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
-
-	peripheral_free_list(pins[slave->bus]);
-	if (is_gpio_cs(slave->cs))
-		gpio_free(gpio_cs(slave->cs));
-
-	bfin_write32(&bss->regs->rx_control, 0x0);
-	bfin_write32(&bss->regs->tx_control, 0x0);
-	bfin_write32(&bss->regs->control, 0x0);
-	SSYNC();
-}
-
-#ifndef CONFIG_BFIN_SPI_IDLE_VAL
-# define CONFIG_BFIN_SPI_IDLE_VAL 0xff
-#endif
-
-static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx,
-			uint bytes)
-{
-	/* discard invalid rx data and empty rfifo */
-	while (!(bfin_read32(&bss->regs->status) & SPI_STAT_RFE))
-		bfin_read32(&bss->regs->rfifo);
-
-	while (bytes--) {
-		u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL);
-		debug("%s: tx:%x ", __func__, value);
-		bfin_write32(&bss->regs->tfifo, value);
-		SSYNC();
-		while (bfin_read32(&bss->regs->status) & SPI_STAT_RFE)
-			if (ctrlc())
-				return -1;
-		value = bfin_read32(&bss->regs->rfifo);
-		if (rx)
-			*rx++ = value;
-		debug("rx:%x\n", value);
-	}
-
-	return 0;
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
-		void *din, unsigned long flags)
-{
-	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
-	const u8 *tx = dout;
-	u8 *rx = din;
-	uint bytes = bitlen / 8;
-	int ret = 0;
-
-	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
-		slave->bus, slave->cs, bitlen, bytes, flags);
-
-	if (bitlen == 0)
-		goto done;
-
-	/* we can only do 8 bit transfers */
-	if (bitlen % 8) {
-		flags |= SPI_XFER_END;
-		goto done;
+	sdev = spi_alloc_slave(struct adi_spi_slave, bus, cs);
+	if (sdev) {
+		if (bus)
+			sdev->regs = (struct spi_regs *)SPI1_REGBASE;
+		else
+			sdev->regs = (struct spi_regs *)SPI0_REGBASE;
+		pins[bus][0] = cs_pins[bus][cs - 1];
+		sdev->pins = pins[bus];
 	}
-
-	if (flags & SPI_XFER_BEGIN)
-		spi_cs_activate(slave);
-
-	ret = spi_pio_xfer(bss, tx, rx, bytes);
-
- done:
-	if (flags & SPI_XFER_END)
-		spi_cs_deactivate(slave);
-
-	return ret;
+	return sdev;
 }
diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h
index 12192ff..839ebe7 100644
--- a/include/configs/bf609-ezkit.h
+++ b/include/configs/bf609-ezkit.h
@@ -101,6 +101,7 @@ 
 /*
  * SPI Settings
  */
+#define CONFIG_ADI_SPI3
 #define CONFIG_BFIN_SPI6XX
 #define CONFIG_ENV_SPI_MAX_HZ	25000000
 #define CONFIG_SF_DEFAULT_SPEED	25000000