[U-Boot] [PATCHv2 5/5] e1000: Add a small SPI driver wrapper around the EEPROM code
Kyle Moffett
Kyle.D.Moffett at boeing.com
Wed Feb 23 16:57:46 CET 2011
To make it possible to use the "sspi" command with the e1000 firmware
EEPROM we add a small "generic SPI" driver wrapper around the existing
e1000 SPI backend.
Signed-off-by: Kyle Moffett <Kyle.D.Moffett at boeing.com>
Cc: Ben Warren <biggerbadderben at gmail.com>
---
No changes since v1
drivers/net/e1000.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++-
drivers/net/e1000.h | 7 ++++
2 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 48129cc..82ca055 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -5264,7 +5264,7 @@ e1000_initialize(bd_t * bis)
return i;
}
-#ifdef CONFIG_CMD_E1000
+#if defined(CONFIG_E1000_SPI) || defined(CONFIG_CMD_E1000)
static struct e1000_hw *e1000_find_card(unsigned int cardnum)
{
struct e1000_hw *hw;
@@ -5343,6 +5343,96 @@ static int e1000_spi_xfer(struct e1000_hw *hw, unsigned int bitlen,
return 0;
}
+#endif /* defined(CONFIG_E1000_SPI) || defined(CONFIG_CMD_E1000) */
+
+#ifdef CONFIG_E1000_SPI
+static inline struct e1000_hw *e1000_hw_from_spi(struct spi_slave *spi)
+{
+ return container_of(spi, struct e1000_hw, spi);
+}
+
+/* Not sure why all of these are necessary */
+void spi_init_r(void) { /* Nothing to do */ }
+void spi_init_f(void) { /* Nothing to do */ }
+void spi_init(void) { /* Nothing to do */ }
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ /* Find the right PCI device */
+ struct e1000_hw *hw = e1000_find_card(bus);
+ if (!hw) {
+ printf("ERROR: No such e1000 device: e1000#%u\n", bus);
+ return NULL;
+ }
+
+ /* Make sure it has an SPI chip */
+ if (hw->eeprom.type != e1000_eeprom_spi) {
+ printf("%s: No attached SPI EEPROM found!\n", hw->nic->name);
+ return NULL;
+ }
+
+ /* Argument sanity checks */
+ if (cs != 0) {
+ printf("%s: No such SPI chip: %u\n", hw->nic->name, cs);
+ return NULL;
+ }
+ if (mode != SPI_MODE_0) {
+ printf("%s: Cannot support SPI modes other than MODE-0\n",
+ hw->nic->name);
+ return NULL;
+ }
+
+ /* TODO: Use max_hz somehow */
+ printf("%s: EEPROM SPI access requested\n", hw->nic->name);
+ return &hw->spi;
+}
+
+void spi_free_slave(struct spi_slave *spi)
+{
+ struct e1000_hw *hw = e1000_hw_from_spi(spi);
+ printf("%s: EEPROM SPI access released\n", hw->nic->name);
+}
+
+int spi_claim_bus(struct spi_slave *spi)
+{
+ struct e1000_hw *hw = e1000_hw_from_spi(spi);
+
+ if (e1000_acquire_eeprom(hw)) {
+ printf("%s: EEPROM SPI cannot be acquired!", hw->nic->name);
+ return -1;
+ }
+
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *spi)
+{
+ struct e1000_hw *hw = e1000_hw_from_spi(spi);
+ e1000_release_eeprom(hw);
+}
+
+/* Skinny wrapper around e1000_spi_xfer */
+int spi_xfer(struct spi_slave *spi, unsigned int bitlen,
+ const void *dout_mem, void *din_mem, unsigned long flags)
+{
+ struct e1000_hw *hw = e1000_hw_from_spi(spi);
+ int ret;
+
+ if (flags & SPI_XFER_BEGIN)
+ e1000_standby_eeprom(hw);
+
+ ret = e1000_spi_xfer(hw, bitlen, dout_mem, din_mem, TRUE);
+
+ if (flags & SPI_XFER_END)
+ e1000_standby_eeprom(hw);
+
+ return ret;
+}
+
+#endif /* CONFIG_E1000_SPI */
+
+#ifdef CONFIG_CMD_E1000
/* The EEPROM opcodes */
#define SPI_EEPROM_ENABLE_WR 0x06
diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h
index 68a3409..f504c90 100644
--- a/drivers/net/e1000.h
+++ b/drivers/net/e1000.h
@@ -41,6 +41,10 @@
#include <asm/io.h>
#include <pci.h>
+#ifdef CONFIG_E1000_SPI
+#include <spi.h>
+#endif
+
#define E1000_ERR(args...) printf("e1000: " args)
#ifdef E1000_DEBUG
@@ -1046,6 +1050,9 @@ typedef enum {
struct e1000_hw {
struct list_head list_node;
struct eth_device *nic;
+#ifdef CONFIG_E1000_SPI
+ struct spi_slave spi;
+#endif
unsigned int cardnum;
pci_dev_t pdev;
--
1.7.2.3
More information about the U-Boot
mailing list