Author: manu
Date: Mon Oct 24 20:33:42 2016
New Revision: 307878
URL: https://svnweb.freebsd.org/changeset/base/307878

Log:
  allwinner: Add support for P2WI in RSB driver
  
  Push-Pull Two Wire interface is a almost compatible iic like bus used
  in sun6i SoC. It's only use is to communicate with the power management IC.
  
  Reviewed by:  jmcneill
  MFC after:    1 week
  Relnotes:     yes

Modified:
  head/sys/arm/allwinner/aw_rsb.c
  head/sys/arm/allwinner/files.allwinner
  head/sys/arm/conf/GENERIC

Modified: head/sys/arm/allwinner/aw_rsb.c
==============================================================================
--- head/sys/arm/allwinner/aw_rsb.c     Mon Oct 24 19:24:07 2016        
(r307877)
+++ head/sys/arm/allwinner/aw_rsb.c     Mon Oct 24 20:33:42 2016        
(r307878)
@@ -27,7 +27,7 @@
  */
 
 /*
- * Allwinner RSB (Reduced Serial Bus)
+ * Allwinner RSB (Reduced Serial Bus) and P2WI (Push-Pull Two Wire Interface)
  */
 
 #include <sys/cdefs.h>
@@ -92,8 +92,12 @@ __FBSDID("$FreeBSD$");
 #define        RSB_ADDR_PMIC_SECONDARY 0x745
 #define        RSB_ADDR_PERIPH_IC      0xe89
 
+#define        A31_P2WI        1
+#define        A23_RSB         2
+
 static struct ofw_compat_data compat_data[] = {
-       { "allwinner,sun8i-a23-rsb",            1 },
+       { "allwinner,sun6i-a31-p2wi",           A31_P2WI },
+       { "allwinner,sun8i-a23-rsb",            A23_RSB },
        { NULL,                                 0 }
 };
 
@@ -131,6 +135,7 @@ struct rsb_softc {
        int             busy;
        uint32_t        status;
        uint16_t        cur_addr;
+       int             type;
 
        struct iic_msg  *msg;
 };
@@ -270,8 +275,8 @@ rsb_transfer(device_t dev, struct iic_ms
        sc = device_get_softc(dev);
 
        /*
-        * RSB is not really an I2C or SMBus controller, so there are some
-        * restrictions imposed by the driver.
+        * P2WI and RSB are not really I2C or SMBus controllers, so there are
+        * some restrictions imposed by the driver.
         *
         * Transfers must contain exactly two messages. The first is always
         * a write, containing a single data byte offset. Data will either
@@ -284,34 +289,36 @@ rsb_transfer(device_t dev, struct iic_ms
            msgs[0].len != 1 || msgs[1].len > RSB_MAXLEN)
                return (EINVAL);
 
-       /* The controller can read or write 1, 2, or 4 bytes at a time. */
-       if ((msgs[1].flags & IIC_M_RD) != 0) {
-               switch (msgs[1].len) {
-               case 1:
-                       cmd = CMD_RD8;
-                       break;
-               case 2:
-                       cmd = CMD_RD16;
-                       break;
-               case 4:
-                       cmd = CMD_RD32;
-                       break;
-               default:
-                       return (EINVAL);
-               }
-       } else {
-               switch (msgs[1].len) {
-               case 1:
-                       cmd = CMD_WR8;
-                       break;
-               case 2:
-                       cmd = CMD_WR16;
-                       break;
-               case 4: 
-                       cmd = CMD_WR32;
-                       break;
-               default:
-                       return (EINVAL);
+       /* The RSB controller can read or write 1, 2, or 4 bytes at a time. */
+       if (sc->type == A23_RSB) {
+               if ((msgs[1].flags & IIC_M_RD) != 0) {
+                       switch (msgs[1].len) {
+                       case 1:
+                               cmd = CMD_RD8;
+                               break;
+                       case 2:
+                               cmd = CMD_RD16;
+                               break;
+                       case 4:
+                               cmd = CMD_RD32;
+                               break;
+                       default:
+                               return (EINVAL);
+                       }
+               } else {
+                       switch (msgs[1].len) {
+                       case 1:
+                               cmd = CMD_WR8;
+                               break;
+                       case 2:
+                               cmd = CMD_WR16;
+                               break;
+                       case 4:
+                               cmd = CMD_WR32;
+                               break;
+                       default:
+                               return (EINVAL);
+                       }
                }
        }
 
@@ -322,13 +329,15 @@ rsb_transfer(device_t dev, struct iic_ms
        sc->status = 0;
 
        /* Select current run-time address if necessary */
-       device_addr = msgs[0].slave >> 1;
-       if (sc->cur_addr != device_addr) {
-               error = rsb_set_rta(dev, device_addr);
-               if (error != 0)
-                       goto done;
-               sc->cur_addr = device_addr;
-               sc->status = 0;
+       if (sc->type == A23_RSB) {
+               device_addr = msgs[0].slave >> 1;
+               if (sc->cur_addr != device_addr) {
+                       error = rsb_set_rta(dev, device_addr);
+                       if (error != 0)
+                               goto done;
+                       sc->cur_addr = device_addr;
+                       sc->status = 0;
+               }
        }
 
        /* Clear interrupt status */
@@ -344,8 +353,9 @@ rsb_transfer(device_t dev, struct iic_ms
                RSB_WRITE(sc, RSB_DATA0, data[0]);
        }
 
-       /* Set command type */
-       RSB_WRITE(sc, RSB_CMD, cmd);
+       /* Set command type for RSB */
+       if (sc->type == A23_RSB)
+               RSB_WRITE(sc, RSB_CMD, cmd);
 
        /* Program data length register and transfer direction */
        dlen = msgs[0].len - 1;
@@ -379,10 +389,17 @@ rsb_probe(device_t dev)
        if (!ofw_bus_status_okay(dev))
                return (ENXIO);
 
-       if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+       switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
+       case A23_RSB:
+               device_set_desc(dev, "Allwinner RSB");
+               break;
+       case A31_P2WI:
+               device_set_desc(dev, "Allwinner P2WI");
+               break;
+       default:
                return (ENXIO);
+       }
 
-       device_set_desc(dev, "Allwinner RSB");
        return (BUS_PROBE_DEFAULT);
 }
 
@@ -395,6 +412,8 @@ rsb_attach(device_t dev)
        sc = device_get_softc(dev);
        mtx_init(&sc->mtx, device_get_nameunit(dev), "rsb", MTX_DEF);
 
+       sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+
        if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) {
                error = clk_enable(sc->clk);
                if (error != 0) {

Modified: head/sys/arm/allwinner/files.allwinner
==============================================================================
--- head/sys/arm/allwinner/files.allwinner      Mon Oct 24 19:24:07 2016        
(r307877)
+++ head/sys/arm/allwinner/files.allwinner      Mon Oct 24 20:33:42 2016        
(r307878)
@@ -12,7 +12,7 @@ arm/allwinner/a10_mmc.c                       optional        
mmc
 arm/allwinner/a10_sramc.c              standard
 arm/allwinner/aw_nmi.c                 optional        intrng
 arm/allwinner/aw_if_dwc.c              optional        dwc
-arm/allwinner/aw_rsb.c                 optional        rsb
+arm/allwinner/aw_rsb.c                 optional        rsb | p2wi
 arm/allwinner/aw_rtc.c                 standard
 arm/allwinner/aw_ts.c                  standard
 arm/allwinner/aw_wdog.c                        standard

Modified: head/sys/arm/conf/GENERIC
==============================================================================
--- head/sys/arm/conf/GENERIC   Mon Oct 24 19:24:07 2016        (r307877)
+++ head/sys/arm/conf/GENERIC   Mon Oct 24 20:33:42 2016        (r307878)
@@ -106,7 +106,8 @@ device              psci
 device         iicbus
 device         iic
 device         twsi
-device         rsb
+device         rsb                     # Allwinner Reduced Serial Bus
+device         p2wi                    # Allwinner Push-Pull Two Wire
 device         axp209                  # AXP209 Power Management Unit
 device         axp81x                  # AXP813/818 Power Management Unit
 device         bcm2835_bsc
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to