svn commit: r202723 - head/sys/mips/atheros

Oleksandr Tymoshenko gonzo at FreeBSD.org
Thu Jan 21 00:15:59 UTC 2010


Author: gonzo
Date: Thu Jan 21 00:15:59 2010
New Revision: 202723
URL: http://svn.freebsd.org/changeset/base/202723

Log:
  - Remove unnecessary register writes in activate_device
      and deactivate_device
  - Save state before attaching driver and restore it when
      detaching
  - Clear CLK bit after last bit of byte has been sent over
      the bus providing falling edge for last byte in transfer
  - Fix several places where CS0 was always assumed
  - Add $FreeBSD$ to ar71xxreg.h

Modified:
  head/sys/mips/atheros/ar71xx_spi.c
  head/sys/mips/atheros/ar71xxreg.h

Modified: head/sys/mips/atheros/ar71xx_spi.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_spi.c	Wed Jan 20 22:45:59 2010	(r202722)
+++ head/sys/mips/atheros/ar71xx_spi.c	Thu Jan 21 00:15:59 2010	(r202723)
@@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$");
 struct ar71xx_spi_softc {
 	device_t		sc_dev;
 	struct resource		*sc_mem_res;
-	uint32_t		sc_reg_ioctrl;
+	uint32_t		sc_reg_ctrl;
 };
 
 static int
@@ -102,12 +102,11 @@ ar71xx_spi_attach(device_t dev)
 		return (ENXIO);
 	}
 
-	sc->sc_reg_ioctrl  = SPI_READ(sc, AR71XX_SPI_IO_CTRL);
 
-	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS0 | SPI_IO_CTRL_CS1 |
-	    SPI_IO_CTRL_CS2);
-	SPI_WRITE(sc, AR71XX_SPI_CTRL, sc->sc_reg_ioctrl);
-	SPI_WRITE(sc, AR71XX_SPI_FS, 0);
+	SPI_WRITE(sc, AR71XX_SPI_FS, 1);
+	sc->sc_reg_ctrl  = SPI_READ(sc, AR71XX_SPI_CTRL);
+	SPI_WRITE(sc, AR71XX_SPI_CTRL, 0x43);
+	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CSMASK);
 
 	device_add_child(dev, "spibus", 0);
 	return (bus_generic_attach(dev));
@@ -116,14 +115,12 @@ ar71xx_spi_attach(device_t dev)
 static void
 ar71xx_spi_chip_activate(struct ar71xx_spi_softc *sc, int cs)
 {
-	uint32_t ioctrl = SPI_IO_CTRL_CS0 |SPI_IO_CTRL_CS1 | SPI_IO_CTRL_CS2;
+	uint32_t ioctrl = SPI_IO_CTRL_CSMASK;
 	/*
 	 * Put respective CSx to low
 	 */
 	ioctrl &= ~(SPI_IO_CTRL_CS0 << cs);
 
-	SPI_WRITE(sc, AR71XX_SPI_FS, 1);
-	SPI_WRITE(sc, AR71XX_SPI_CTRL, 0x43);
 	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, ioctrl);
 }
 
@@ -133,18 +130,19 @@ ar71xx_spi_chip_deactivate(struct ar71xx
 	/*
 	 * Put all CSx to high
 	 */
-	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS0 | SPI_IO_CTRL_CS1 |
-	    SPI_IO_CTRL_CS2);
-	SPI_WRITE(sc, AR71XX_SPI_CTRL, sc->sc_reg_ioctrl);
-	SPI_WRITE(sc, AR71XX_SPI_FS, 0);
+	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CSMASK);
 }
 
 static uint8_t
-ar71xx_spi_txrx(struct ar71xx_spi_softc *sc, uint8_t data)
+ar71xx_spi_txrx(struct ar71xx_spi_softc *sc, int cs, uint8_t data)
 {
 	int bit;
 	/* CS0 */
-	uint32_t ioctrl = SPI_IO_CTRL_CS1 | SPI_IO_CTRL_CS2;
+	uint32_t ioctrl = SPI_IO_CTRL_CSMASK;
+	/*
+	 * low-level for selected CS
+	 */
+	ioctrl &= ~(SPI_IO_CTRL_CS0 << cs);
 
 	uint32_t iod, rds;
 	for (bit = 7; bit >=0; bit--) {
@@ -156,6 +154,10 @@ ar71xx_spi_txrx(struct ar71xx_spi_softc 
 		SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, iod | SPI_IO_CTRL_CLK);
 	}
 
+	/*
+	 * Provide falling edge for connected device by clear clock bit.
+	 */
+	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, iod);
 	rds = SPI_READ(sc, AR71XX_SPI_RDS);
 
 	return (rds & 0xff);
@@ -184,7 +186,7 @@ ar71xx_spi_transfer(device_t dev, device
 	buf_out = (uint8_t *)cmd->tx_cmd;
 	buf_in = (uint8_t *)cmd->rx_cmd;
 	for (i = 0; i < cmd->tx_cmd_sz; i++)
-		buf_in[i] = ar71xx_spi_txrx(sc, buf_out[i]);
+		buf_in[i] = ar71xx_spi_txrx(sc, devi->cs, buf_out[i]);
 
 	/*
 	 * Receive/transmit data (depends on  command)
@@ -192,7 +194,7 @@ ar71xx_spi_transfer(device_t dev, device
 	buf_out = (uint8_t *)cmd->tx_data;
 	buf_in = (uint8_t *)cmd->rx_data;
 	for (i = 0; i < cmd->tx_data_sz; i++)
-		buf_in[i] = ar71xx_spi_txrx(sc, buf_out[i]);
+		buf_in[i] = ar71xx_spi_txrx(sc, devi->cs, buf_out[i]);
 
 	ar71xx_spi_chip_deactivate(sc, devi->cs);
 
@@ -202,8 +204,15 @@ ar71xx_spi_transfer(device_t dev, device
 static int
 ar71xx_spi_detach(device_t dev)
 {
+	struct ar71xx_spi_softc *sc = device_get_softc(dev);
 
-	return (EBUSY);	/* XXX */
+	SPI_WRITE(sc, AR71XX_SPI_CTRL, sc->sc_reg_ctrl);
+	SPI_WRITE(sc, AR71XX_SPI_FS, 0);
+
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+
+	return (0);
 }
 
 static device_method_t ar71xx_spi_methods[] = {

Modified: head/sys/mips/atheros/ar71xxreg.h
==============================================================================
--- head/sys/mips/atheros/ar71xxreg.h	Wed Jan 20 22:45:59 2010	(r202722)
+++ head/sys/mips/atheros/ar71xxreg.h	Thu Jan 21 00:15:59 2010	(r202723)
@@ -23,6 +23,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
+/* $FreeBSD$ */
+
 #ifndef _AR71XX_REG_H_
 #define _AR71XX_REG_H_
 
@@ -422,6 +425,7 @@
 #define			SPI_IO_CTRL_CS2			(1 << 18)
 #define			SPI_IO_CTRL_CS1			(1 << 17)
 #define			SPI_IO_CTRL_CS0			(1 << 16)
+#define			SPI_IO_CTRL_CSMASK		(7 << 16)
 #define			SPI_IO_CTRL_CLK			(1 << 8)
 #define			SPI_IO_CTRL_DO			1
 #define		AR71XX_SPI_RDS		0x0C


More information about the svn-src-all mailing list