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
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to