summaryrefslogtreecommitdiffstats
path: root/bitbang_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'bitbang_spi.c')
-rw-r--r--bitbang_spi.c124
1 files changed, 56 insertions, 68 deletions
diff --git a/bitbang_spi.c b/bitbang_spi.c
index 5ee52f5..51fc9c6 100644
--- a/bitbang_spi.c
+++ b/bitbang_spi.c
@@ -25,42 +25,37 @@
#include "programmer.h"
#include "spi.h"
-/* Length of half a clock period in usecs. */
-static int bitbang_spi_half_period;
-
-static const struct bitbang_spi_master *bitbang_spi_master = NULL;
-
/* Note that CS# is active low, so val=0 means the chip is active. */
-static void bitbang_spi_set_cs(int val)
+static void bitbang_spi_set_cs(const const struct bitbang_spi_master *master, int val)
{
- bitbang_spi_master->set_cs(val);
+ master->set_cs(val);
}
-static void bitbang_spi_set_sck(int val)
+static void bitbang_spi_set_sck(const const struct bitbang_spi_master *master, int val)
{
- bitbang_spi_master->set_sck(val);
+ master->set_sck(val);
}
-static void bitbang_spi_set_mosi(int val)
+static void bitbang_spi_set_mosi(const const struct bitbang_spi_master *master, int val)
{
- bitbang_spi_master->set_mosi(val);
+ master->set_mosi(val);
}
-static int bitbang_spi_get_miso(void)
+static int bitbang_spi_get_miso(const const struct bitbang_spi_master *master)
{
- return bitbang_spi_master->get_miso();
+ return master->get_miso();
}
-static void bitbang_spi_request_bus(void)
+static void bitbang_spi_request_bus(const const struct bitbang_spi_master *master)
{
- if (bitbang_spi_master->request_bus)
- bitbang_spi_master->request_bus();
+ if (master->request_bus)
+ master->request_bus();
}
-static void bitbang_spi_release_bus(void)
+static void bitbang_spi_release_bus(const const struct bitbang_spi_master *master)
{
- if (bitbang_spi_master->release_bus)
- bitbang_spi_master->release_bus();
+ if (master->release_bus)
+ master->release_bus();
}
static int bitbang_spi_send_command(struct flashctx *flash,
@@ -78,67 +73,59 @@ static const struct spi_programmer spi_programmer_bitbang = {
.write_256 = default_spi_write_256,
};
-int bitbang_spi_init(const struct bitbang_spi_master *master, int halfperiod)
+#if 0 // until it is needed
+static int bitbang_spi_shutdown(const struct bitbang_spi_master *master)
{
+ /* FIXME: Run bitbang_spi_release_bus here or per command? */
+ return 0;
+}
+#endif
+
+int bitbang_spi_init(const struct bitbang_spi_master *master)
+{
+ struct spi_programmer pgm = spi_programmer_bitbang;
/* BITBANG_SPI_INVALID is 0, so if someone forgot to initialize ->type,
* we catch it here. Same goes for missing initialization of bitbanging
* functions.
*/
if (!master || master->type == BITBANG_SPI_INVALID || !master->set_cs ||
- !master->set_sck || !master->set_mosi || !master->get_miso) {
+ !master->set_sck || !master->set_mosi || !master->get_miso ||
+ (master->request_bus && !master->release_bus) ||
+ (!master->request_bus && master->release_bus)) {
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;
+ return ERROR_FLASHROM_BUG;
}
- bitbang_spi_master = master;
- bitbang_spi_half_period = halfperiod;
+ pgm.data = master;
+ register_spi_programmer(&pgm);
- register_spi_programmer(&spi_programmer_bitbang);
-
- /* 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;
+ /* Only mess with the bus if we're sure nobody else uses it. */
+ bitbang_spi_request_bus(master);
+ bitbang_spi_set_cs(master, 1);
+ bitbang_spi_set_sck(master, 0);
+ bitbang_spi_set_mosi(master, 0);
+ /* FIXME: Release SPI bus here and request it again for each command or
+ * don't release it now and only release it on programmer shutdown?
+ */
+ bitbang_spi_release_bus(master);
return 0;
}
-static uint8_t bitbang_spi_readwrite_byte(uint8_t val)
+static uint8_t bitbang_spi_rw_byte(const struct bitbang_spi_master *master,
+ uint8_t val)
{
uint8_t ret = 0;
int i;
for (i = 7; i >= 0; i--) {
- bitbang_spi_set_mosi((val >> i) & 1);
- programmer_delay(bitbang_spi_half_period);
- bitbang_spi_set_sck(1);
+ bitbang_spi_set_mosi(master, (val >> i) & 1);
+ programmer_delay(master->half_period);
+ bitbang_spi_set_sck(master, 1);
ret <<= 1;
- ret |= bitbang_spi_get_miso();
- programmer_delay(bitbang_spi_half_period);
- bitbang_spi_set_sck(0);
+ ret |= bitbang_spi_get_miso(master);
+ programmer_delay(master->half_period);
+ bitbang_spi_set_sck(master, 0);
}
return ret;
}
@@ -149,23 +136,24 @@ static int bitbang_spi_send_command(struct flashctx *flash,
unsigned char *readarr)
{
int i;
+ const struct bitbang_spi_master *master = flash->pgm->spi.data;
/* 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);
+ bitbang_spi_request_bus(master);
+ bitbang_spi_set_cs(master, 0);
for (i = 0; i < writecnt; i++)
- bitbang_spi_readwrite_byte(writearr[i]);
+ bitbang_spi_rw_byte(master, writearr[i]);
for (i = 0; i < readcnt; i++)
- readarr[i] = bitbang_spi_readwrite_byte(0);
+ readarr[i] = bitbang_spi_rw_byte(master, 0);
- programmer_delay(bitbang_spi_half_period);
- bitbang_spi_set_cs(1);
- programmer_delay(bitbang_spi_half_period);
+ programmer_delay(master->half_period);
+ bitbang_spi_set_cs(master, 1);
+ programmer_delay(master->half_period);
/* FIXME: Run bitbang_spi_release_bus here or in programmer init? */
- bitbang_spi_release_bus();
+ bitbang_spi_release_bus(master);
return 0;
}
OpenPOWER on IntegriCloud