summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitbang_spi.c48
-rw-r--r--mcp6x_spi.c11
-rw-r--r--nicintel_spi.c12
-rw-r--r--programmer.h3
4 files changed, 53 insertions, 21 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;
}
diff --git a/mcp6x_spi.c b/mcp6x_spi.c
index 6635ddd..97c0a1c 100644
--- a/mcp6x_spi.c
+++ b/mcp6x_spi.c
@@ -66,18 +66,9 @@ static void mcp6x_release_spibus(void)
static void mcp6x_bitbang_set_cs(int val)
{
- /* Requesting and releasing the SPI bus is handled in here to allow the
- * chipset to use its own SPI engine for native reads.
- */
- if (val == 0)
- mcp6x_request_spibus();
-
mcp_gpiostate &= ~(1 << MCP6X_SPI_CS);
mcp_gpiostate |= (val << MCP6X_SPI_CS);
mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
-
- if (val == 1)
- mcp6x_release_spibus();
}
static void mcp6x_bitbang_set_sck(int val)
@@ -106,6 +97,8 @@ static const struct bitbang_spi_master bitbang_spi_master_mcp6x = {
.set_sck = mcp6x_bitbang_set_sck,
.set_mosi = mcp6x_bitbang_set_mosi,
.get_miso = mcp6x_bitbang_get_miso,
+ .request_bus = mcp6x_request_spibus,
+ .release_bus = mcp6x_release_spibus,
};
int mcp6x_spi_init(int want_spi)
diff --git a/nicintel_spi.c b/nicintel_spi.c
index d09facc..75dc423 100644
--- a/nicintel_spi.c
+++ b/nicintel_spi.c
@@ -91,20 +91,10 @@ static void nicintel_bitbang_set_cs(int val)
{
uint32_t tmp;
- /*
- * Requesting and releasing the SPI bus is handled in here to allow
- * the chipset to use its own SPI engine for native reads.
- */
- if (val == 0)
- nicintel_request_spibus();
-
tmp = pci_mmio_readl(nicintel_spibar + FLA);
tmp &= ~(1 << FL_CS);
tmp |= (val << FL_CS);
pci_mmio_writel(tmp, nicintel_spibar + FLA);
-
- if (val == 1)
- nicintel_release_spibus();
}
static void nicintel_bitbang_set_sck(int val)
@@ -142,6 +132,8 @@ static const struct bitbang_spi_master bitbang_spi_master_nicintel = {
.set_sck = nicintel_bitbang_set_sck,
.set_mosi = nicintel_bitbang_set_mosi,
.get_miso = nicintel_bitbang_get_miso,
+ .request_bus = nicintel_request_spibus,
+ .release_bus = nicintel_release_spibus,
};
int nicintel_spi_init(void)
diff --git a/programmer.h b/programmer.h
index 0d8e161..6407695 100644
--- a/programmer.h
+++ b/programmer.h
@@ -131,6 +131,8 @@ struct bitbang_spi_master {
void (*set_sck) (int val);
void (*set_mosi) (int val);
int (*get_miso) (void);
+ void (*request_bus) (void);
+ void (*release_bus) (void);
};
#if CONFIG_INTERNAL == 1
@@ -443,6 +445,7 @@ int mcp6x_spi_init(int want_spi);
/* bitbang_spi.c */
int bitbang_spi_init(const struct bitbang_spi_master *master, int halfperiod);
+int bitbang_spi_shutdown(const struct bitbang_spi_master *master);
int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
OpenPOWER on IntegriCloud