mirror of
https://github.com/Stichting-MINIX-Research-Foundation/u-boot.git
synced 2025-09-10 12:39:22 -04:00
Blackfin: bfin_spi: support gpios as chip selects
Rather than only support the pins dedicated as chip selects, utilize the gpio framework to support any gpio pin. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
parent
f3732edf46
commit
37a4b75d4c
@ -13,6 +13,7 @@
|
|||||||
#include <spi.h>
|
#include <spi.h>
|
||||||
|
|
||||||
#include <asm/blackfin.h>
|
#include <asm/blackfin.h>
|
||||||
|
#include <asm/gpio.h>
|
||||||
#include <asm/portmux.h>
|
#include <asm/portmux.h>
|
||||||
#include <asm/mach-common/bits/spi.h>
|
#include <asm/mach-common/bits/spi.h>
|
||||||
|
|
||||||
@ -34,48 +35,68 @@ MAKE_SPI_FUNC(SPI_BAUD, 0x14)
|
|||||||
|
|
||||||
#define to_bfin_spi_slave(s) container_of(s, struct bfin_spi_slave, slave)
|
#define to_bfin_spi_slave(s) container_of(s, struct bfin_spi_slave, slave)
|
||||||
|
|
||||||
__attribute__((weak))
|
#define MAX_CTRL_CS 7
|
||||||
|
|
||||||
|
#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)
|
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
|
||||||
{
|
{
|
||||||
#if defined(__ADSPBF538__) || defined(__ADSPBF539__)
|
if (is_gpio_cs(cs))
|
||||||
/* The SPI1/SPI2 buses are weird ... only 1 CS */
|
return gpio_is_valid(gpio_cs(cs));
|
||||||
if (bus > 0 && cs != 1)
|
else
|
||||||
return 0;
|
return (cs >= 1 && cs <= MAX_CTRL_CS);
|
||||||
#endif
|
|
||||||
return (cs >= 1 && cs <= 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak))
|
|
||||||
void spi_cs_activate(struct spi_slave *slave)
|
void spi_cs_activate(struct spi_slave *slave)
|
||||||
{
|
{
|
||||||
struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
|
struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
|
||||||
write_SPI_FLG(bss,
|
|
||||||
(read_SPI_FLG(bss) &
|
if (is_gpio_cs(slave->cs)) {
|
||||||
~((!bss->flg << 8) << slave->cs)) |
|
unsigned int cs = gpio_cs(slave->cs);
|
||||||
(1 << slave->cs));
|
gpio_set_value(cs, bss->flg);
|
||||||
|
debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
|
||||||
|
} else {
|
||||||
|
write_SPI_FLG(bss,
|
||||||
|
(read_SPI_FLG(bss) &
|
||||||
|
~((!bss->flg << 8) << slave->cs)) |
|
||||||
|
(1 << slave->cs));
|
||||||
|
debug("%s: SPI_FLG:%x\n", __func__, read_SPI_FLG(bss));
|
||||||
|
}
|
||||||
|
|
||||||
SSYNC();
|
SSYNC();
|
||||||
debug("%s: SPI_FLG:%x\n", __func__, read_SPI_FLG(bss));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak))
|
|
||||||
void spi_cs_deactivate(struct spi_slave *slave)
|
void spi_cs_deactivate(struct spi_slave *slave)
|
||||||
{
|
{
|
||||||
struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
|
struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
|
||||||
u16 flg;
|
|
||||||
|
|
||||||
/* make sure we force the cs to deassert rather than let the
|
if (is_gpio_cs(slave->cs)) {
|
||||||
* pin float back up. otherwise, exact timings may not be
|
unsigned int cs = gpio_cs(slave->cs);
|
||||||
* met some of the time leading to random behavior (ugh).
|
gpio_set_value(cs, !bss->flg);
|
||||||
*/
|
debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
|
||||||
flg = read_SPI_FLG(bss) | ((!bss->flg << 8) << slave->cs);
|
} else {
|
||||||
write_SPI_FLG(bss, flg);
|
u16 flg;
|
||||||
SSYNC();
|
|
||||||
debug("%s: SPI_FLG:%x\n", __func__, read_SPI_FLG(bss));
|
/* make sure we force the cs to deassert rather than let the
|
||||||
|
* pin float back up. otherwise, exact timings may not be
|
||||||
|
* met some of the time leading to random behavior (ugh).
|
||||||
|
*/
|
||||||
|
flg = read_SPI_FLG(bss) | ((!bss->flg << 8) << slave->cs);
|
||||||
|
write_SPI_FLG(bss, flg);
|
||||||
|
SSYNC();
|
||||||
|
debug("%s: SPI_FLG:%x\n", __func__, read_SPI_FLG(bss));
|
||||||
|
|
||||||
|
flg &= ~(1 << slave->cs);
|
||||||
|
write_SPI_FLG(bss, flg);
|
||||||
|
debug("%s: SPI_FLG:%x\n", __func__, read_SPI_FLG(bss));
|
||||||
|
}
|
||||||
|
|
||||||
flg &= ~(1 << slave->cs);
|
|
||||||
write_SPI_FLG(bss, flg);
|
|
||||||
SSYNC();
|
SSYNC();
|
||||||
debug("%s: SPI_FLG:%x\n", __func__, read_SPI_FLG(bss));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spi_init()
|
void spi_init()
|
||||||
@ -188,7 +209,13 @@ int spi_claim_bus(struct spi_slave *slave)
|
|||||||
|
|
||||||
debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
|
debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
|
||||||
|
|
||||||
pins[slave->bus][0] = cs_pins[slave->bus][slave->cs - 1];
|
if (is_gpio_cs(slave->cs)) {
|
||||||
|
unsigned int cs = gpio_cs(slave->cs);
|
||||||
|
gpio_request(cs, "bfin-spi");
|
||||||
|
gpio_direction_output(cs, !bss->flg);
|
||||||
|
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");
|
peripheral_request_list(pins[slave->bus], "bfin-spi");
|
||||||
|
|
||||||
write_SPI_CTL(bss, bss->ctl);
|
write_SPI_CTL(bss, bss->ctl);
|
||||||
@ -205,6 +232,8 @@ void spi_release_bus(struct spi_slave *slave)
|
|||||||
debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
|
debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
|
||||||
|
|
||||||
peripheral_free_list(pins[slave->bus]);
|
peripheral_free_list(pins[slave->bus]);
|
||||||
|
if (is_gpio_cs(slave->cs))
|
||||||
|
gpio_free(gpio_cs(slave->cs));
|
||||||
|
|
||||||
write_SPI_CTL(bss, 0);
|
write_SPI_CTL(bss, 0);
|
||||||
SSYNC();
|
SSYNC();
|
||||||
|
@ -254,6 +254,7 @@
|
|||||||
/*
|
/*
|
||||||
* Misc Settings
|
* Misc Settings
|
||||||
*/
|
*/
|
||||||
|
#define CONFIG_BFIN_SPI_GPIO_CS /* Only matters if BFIN_SPI is enabled */
|
||||||
#define CONFIG_LZMA
|
#define CONFIG_LZMA
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user