From c8310e06a8cc1f634e17e060f375444d0fd71b46 Mon Sep 17 00:00:00 2001 From: hailfinger Date: Wed, 15 Sep 2010 00:17:37 +0000 Subject: SPI bitbanging: request/release bus. SPI bitbanging on devices which speak SPI natively has a dual-use problem: We need to shut down normal SPI operations to do the bitbanging ourselves. Once we're done, it makes a lot of sense to reenable "normal" SPI operations again. Add request_bus/release_bus functions to struct bitbang_spi_master. Add a bitbang shutdown function (not used yet). Change MCP SPI and Intel NIC SPI to use the new request/release bus infrastructure. Cosmetic changes to a few error messages (80 column limit). There are multiple possible strategies for bus request/release: - Request at the start of a SPI command, release immediately afterwards. - Request at the start of a SPI multicommand, release once all commands of the multicommand are done. - Request on programmer init, release on shutdown. Each strategy has its own advantages. For now, we will stay with the first strategy which worked fine so far. Signed-off-by: Carl-Daniel Hailfinger Acked-by: Uwe Hermann git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1171 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- bitbang_spi.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'bitbang_spi.c') diff --git a/bitbang_spi.c b/bitbang_spi.c index f697f5a..fe85b60 100644 --- a/bitbang_spi.c +++ b/bitbang_spi.c @@ -53,6 +53,18 @@ static int bitbang_spi_get_miso(void) return bitbang_spi_master->get_miso(); } +static void bitbang_spi_request_bus(void) +{ + if (bitbang_spi_master->request_bus) + bitbang_spi_master->request_bus(); +} + +static void bitbang_spi_release_bus(void) +{ + if (bitbang_spi_master->release_bus) + bitbang_spi_master->release_bus(); +} + int bitbang_spi_init(const struct bitbang_spi_master *master, int halfperiod) { /* BITBANG_SPI_INVALID is 0, so if someone forgot to initialize ->type, @@ -61,19 +73,44 @@ int bitbang_spi_init(const struct bitbang_spi_master *master, int halfperiod) */ if (!master || master->type == BITBANG_SPI_INVALID || !master->set_cs || !master->set_sck || !master->set_mosi || !master->get_miso) { - msg_perr("Incomplete bitbanging SPI master setting! Please " - "report a bug at flashrom@flashrom.org\n"); + msg_perr("Incomplete SPI bitbang master setting!\n" + "Please report a bug at flashrom@flashrom.org\n"); + return 1; + } + if (bitbang_spi_master) { + msg_perr("SPI bitbang master already initialized!\n" + "Please report a bug at flashrom@flashrom.org\n"); return 1; } + bitbang_spi_master = master; bitbang_spi_half_period = halfperiod; + /* FIXME: Run bitbang_spi_request_bus here or in programmer init? */ bitbang_spi_set_cs(1); bitbang_spi_set_sck(0); bitbang_spi_set_mosi(0); return 0; } +int bitbang_spi_shutdown(const struct bitbang_spi_master *master) +{ + if (!bitbang_spi_master) { + msg_perr("Shutting down an uninitialized SPI bitbang master!\n" + "Please report a bug at flashrom@flashrom.org\n"); + return 1; + } + if (master != bitbang_spi_master) { + msg_perr("Shutting down a mismatched SPI bitbang master!\n" + "Please report a bug at flashrom@flashrom.org\n"); + return 1; + } + + /* FIXME: Run bitbang_spi_release_bus here or per command? */ + bitbang_spi_master = NULL; + return 0; +} + static uint8_t bitbang_spi_readwrite_byte(uint8_t val) { uint8_t ret = 0; @@ -96,6 +133,11 @@ int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, { int i; + /* FIXME: Run bitbang_spi_request_bus here or in programmer init? + * Requesting and releasing the SPI bus is handled in here to allow the + * programmer to use its own SPI engine for native accesses. + */ + bitbang_spi_request_bus(); bitbang_spi_set_cs(0); for (i = 0; i < writecnt; i++) bitbang_spi_readwrite_byte(writearr[i]); @@ -105,6 +147,8 @@ int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, programmer_delay(bitbang_spi_half_period); bitbang_spi_set_cs(1); programmer_delay(bitbang_spi_half_period); + /* FIXME: Run bitbang_spi_release_bus here or in programmer init? */ + bitbang_spi_release_bus(); return 0; } -- cgit v1.2.1