summaryrefslogtreecommitdiff
path: root/bitbang_spi.c
diff options
context:
space:
mode:
authorhailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2010-09-15 00:17:37 +0000
committerhailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2010-09-15 00:17:37 +0000
commitc8310e06a8cc1f634e17e060f375444d0fd71b46 (patch)
treea6e81bc8cf557252479496bc3a655c1981b6303e /bitbang_spi.c
parent2eb79e9e5022506b6b7478520a6fcc60d9d84454 (diff)
downloadflashrom-c8310e06a8cc1f634e17e060f375444d0fd71b46.tar.gz
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 <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1171 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'bitbang_spi.c')
-rw-r--r--bitbang_spi.c48
1 files changed, 46 insertions, 2 deletions
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;
}