[U-Boot] [PATCH 5/5] e1000: Add a small SPI driver wrapper around the EEPROM code

Kyle Moffett Kyle.D.Moffett at boeing.com
Mon Sep 13 17:52:26 CEST 2010


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>
---
 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 4ff845a..70457f1 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -5259,7 +5259,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;
@@ -5338,6 +5338,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.1



More information about the U-Boot mailing list