* [U-Boot] [PATCH 1/3] blackfin: spi: move spi max chip select to spi.h
@ 2014-06-06 6:44 Scott Jiang
2014-06-06 6:44 ` [U-Boot] [PATCH 2/3] blackfin: spi clock is in sysclk1 domain instead of sysclk0 Scott Jiang
2014-06-06 6:44 ` [U-Boot] [PATCH 3/3] spi: add common spi3 controller driver Scott Jiang
0 siblings, 2 replies; 4+ messages in thread
From: Scott Jiang @ 2014-06-06 6:44 UTC (permalink / raw)
To: u-boot
Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com>
---
arch/blackfin/include/asm/config-pre.h | 3 ---
arch/blackfin/include/asm/mach-common/bits/spi.h | 1 +
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/blackfin/include/asm/config-pre.h b/arch/blackfin/include/asm/config-pre.h
index d0fd537..0ffa44c 100644
--- a/arch/blackfin/include/asm/config-pre.h
+++ b/arch/blackfin/include/asm/config-pre.h
@@ -73,9 +73,6 @@ static inline const char *get_bfin_boot_mode(int bfin_boot)
# define BFIN_BOOT_SPI_SSEL 1
#endif
-/* Define to get a GPIO CS with the Blackfin SPI controller */
-#define MAX_CTRL_CS 8
-
/* There is no Blackfin/NetBSD port */
#undef CONFIG_BOOTM_NETBSD
diff --git a/arch/blackfin/include/asm/mach-common/bits/spi.h b/arch/blackfin/include/asm/mach-common/bits/spi.h
index 869dcb0..180cfaa 100644
--- a/arch/blackfin/include/asm/mach-common/bits/spi.h
+++ b/arch/blackfin/include/asm/mach-common/bits/spi.h
@@ -64,4 +64,5 @@
#define RXS 0x0020 /* SPI_RDBR Data Buffer Status (Full/Empty*) */
#define TXCOL 0x0040 /* Transmit Collision Error (Corrupt Data May Have Been Sent) */
+#define MAX_CTRL_CS 7
#endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH 2/3] blackfin: spi clock is in sysclk1 domain instead of sysclk0
2014-06-06 6:44 [U-Boot] [PATCH 1/3] blackfin: spi: move spi max chip select to spi.h Scott Jiang
@ 2014-06-06 6:44 ` Scott Jiang
2014-06-06 6:44 ` [U-Boot] [PATCH 3/3] spi: add common spi3 controller driver Scott Jiang
1 sibling, 0 replies; 4+ messages in thread
From: Scott Jiang @ 2014-06-06 6:44 UTC (permalink / raw)
To: u-boot
Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com>
---
arch/blackfin/include/asm/clock.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/blackfin/include/asm/clock.h b/arch/blackfin/include/asm/clock.h
index 59d3faa..05ae03c 100644
--- a/arch/blackfin/include/asm/clock.h
+++ b/arch/blackfin/include/asm/clock.h
@@ -78,7 +78,7 @@ extern u_long get_sclk1(void);
extern u_long get_dclk(void);
# define get_uart_clk get_sclk0
# define get_i2c_clk get_sclk0
-# define get_spi_clk get_sclk0
+# define get_spi_clk get_sclk1
#else
# define get_uart_clk get_sclk
# define get_i2c_clk get_sclk
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH 3/3] spi: add common spi3 controller driver
2014-06-06 6:44 [U-Boot] [PATCH 1/3] blackfin: spi: move spi max chip select to spi.h Scott Jiang
2014-06-06 6:44 ` [U-Boot] [PATCH 2/3] blackfin: spi clock is in sysclk1 domain instead of sysclk0 Scott Jiang
@ 2014-06-06 6:44 ` Scott Jiang
2014-06-09 8:36 ` Jagan Teki
1 sibling, 1 reply; 4+ messages in thread
From: Scott Jiang @ 2014-06-06 6:44 UTC (permalink / raw)
To: u-boot
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;
+ 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
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH 3/3] spi: add common spi3 controller driver
2014-06-06 6:44 ` [U-Boot] [PATCH 3/3] spi: add common spi3 controller driver Scott Jiang
@ 2014-06-09 8:36 ` Jagan Teki
0 siblings, 0 replies; 4+ messages in thread
From: Jagan Teki @ 2014-06-09 8:36 UTC (permalink / raw)
To: u-boot
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!
--
Jagan.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-06-09 8:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-06 6:44 [U-Boot] [PATCH 1/3] blackfin: spi: move spi max chip select to spi.h Scott Jiang
2014-06-06 6:44 ` [U-Boot] [PATCH 2/3] blackfin: spi clock is in sysclk1 domain instead of sysclk0 Scott Jiang
2014-06-06 6:44 ` [U-Boot] [PATCH 3/3] spi: add common spi3 controller driver Scott Jiang
2014-06-09 8:36 ` Jagan Teki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox