Hi,

diff does add the quirk needed on sun6i-a31, and above including sun8i-h3,
for which it does also add related gates+resets.

-Artturi


diff --git a/sys/dev/fdt/sxiccmu_clocks.h b/sys/dev/fdt/sxiccmu_clocks.h
index 8b25ac42bd4..f82613e0125 100644
--- a/sys/dev/fdt/sxiccmu_clocks.h
+++ b/sys/dev/fdt/sxiccmu_clocks.h
@@ -95,6 +95,10 @@ struct sxiccmu_ccu_bit sun50i_a64_gates[] = {
 
 #define H3_CLK_BUS_PIO         54
 
+#define H3_CLK_BUS_I2C0                59
+#define H3_CLK_BUS_I2C1                60
+#define H3_CLK_BUS_I2C2                61
+
 #define H3_CLK_BUS_UART0       62
 #define H3_CLK_BUS_UART1       63
 #define H3_CLK_BUS_UART2       64
@@ -128,6 +132,9 @@ struct sxiccmu_ccu_bit sun8i_h3_gates[] = {
        [H3_CLK_BUS_OHCI2] = { 0x0060, 30 },
        [H3_CLK_BUS_OHCI3] = { 0x0060, 31 },
        [H3_CLK_BUS_PIO]   = { 0x0068, 5 },
+       [H3_CLK_BUS_I2C0] = { 0x006c, 0, H3_CLK_APB2 },
+       [H3_CLK_BUS_I2C1] = { 0x006c, 1, H3_CLK_APB2 },
+       [H3_CLK_BUS_I2C2] = { 0x006c, 2, H3_CLK_APB2 },
        [H3_CLK_BUS_UART0] = { 0x006c, 16, H3_CLK_APB2 },
        [H3_CLK_BUS_UART1] = { 0x006c, 17, H3_CLK_APB2 },
        [H3_CLK_BUS_UART2] = { 0x006c, 18, H3_CLK_APB2 },
@@ -195,6 +202,10 @@ struct sxiccmu_ccu_bit sun50i_a64_resets[] = {
 
 #define H3_RST_BUS_EPHY                39
 
+#define H3_RST_BUS_I2C0                46
+#define H3_RST_BUS_I2C1                47
+#define H3_RST_BUS_I2C2                48
+
 struct sxiccmu_ccu_bit sun8i_h3_resets[] = {
        [H3_RST_USB_PHY0] =  { 0x00cc, 0 },
        [H3_RST_USB_PHY1] =  { 0x00cc, 1 },
@@ -213,4 +224,7 @@ struct sxiccmu_ccu_bit sun8i_h3_resets[] = {
        [H3_RST_BUS_OHCI2] = { 0x02c0, 30 },
        [H3_RST_BUS_OHCI3] = { 0x02c0, 31 },
        [H3_RST_BUS_EPHY]  = { 0x02c8, 2 },
+       [H3_RST_BUS_I2C0] =  { 0x02d8, 0 },
+       [H3_RST_BUS_I2C1] =  { 0x02d8, 1 },
+       [H3_RST_BUS_I2C2] =  { 0x02d8, 2 },
 };
diff --git a/sys/dev/fdt/sxitwi.c b/sys/dev/fdt/sxitwi.c
index f53f2bfd594..e98b36f9588 100644
--- a/sys/dev/fdt/sxitwi.c
+++ b/sys/dev/fdt/sxitwi.c
@@ -144,6 +144,7 @@ struct sxitwi_softc {
        bus_space_handle_t       sc_ioh;
        int                      sc_node;
        u_int                    sc_started;
+       u_int                    sc_twsien_iflg;
        struct i2c_controller    sc_ic;
        struct rwlock            sc_buslock;
        void                    *sc_ih;
@@ -179,7 +180,8 @@ sxitwi_match(struct device *parent, void *match, void *aux)
        struct fdt_attach_args *faa = aux;
 
        return (OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-i2c") ||
-           OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-i2c"));
+           OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-i2c") ||
+           OF_is_compatible(faa->fa_node, "allwinner,sun6i-a31-i2c"));
 }
 
 void
@@ -206,6 +208,8 @@ sxitwi_attach(struct device *parent, struct device *self, 
void *aux)
        rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname);
 
        sc->sc_started = 0;
+       sc->sc_twsien_iflg = CONTROL_TWSIEN | (OF_is_compatible(sc->sc_node,
+           "allwinner,sun6i-a31-i2c") ? CONTROL_IFLG : 0);
        sc->sc_ic.ic_cookie = sc;
        sc->sc_ic.ic_acquire_bus = sxitwi_acquire_bus;
        sc->sc_ic.ic_release_bus = sxitwi_release_bus;
@@ -220,6 +224,7 @@ sxitwi_attach(struct device *parent, struct device *self, 
void *aux)
 
        /* Enable clock */
        clock_enable(faa->fa_node, NULL);
+       reset_deassert_all(faa->fa_node);
 
        /*
         * Set clock rate to 100kHz. From the datasheet:
@@ -358,13 +363,11 @@ sxitwi_send_stop(void *v, int flags)
 {
        struct sxitwi_softc *sc = v;
        int retry = TWSI_RETRY_COUNT;
-       u_int control;
 
        sc->sc_started = 0;
 
        /* Interrupt is not generated for STAT_NRS. */
-       control = CONTROL_STOP | CONTROL_TWSIEN;
-       sxitwi_write_4(sc, TWSI_CONTROL, control);
+       sxitwi_write_4(sc, TWSI_CONTROL, CONTROL_STOP | sc->sc_twsien_iflg);
        while (--retry > 0) {
                if (sxitwi_read_4(sc, TWSI_STATUS) == STAT_NRS)
                        return 0;
@@ -458,7 +461,7 @@ sxitwi_wait(struct sxitwi_softc *sc, u_int control, u_int 
expect, int flags)
        delay(5);
        if (!(flags & I2C_F_POLL))
                control |= CONTROL_INTEN;
-       sxitwi_write_4(sc, TWSI_CONTROL, control | CONTROL_TWSIEN);
+       sxitwi_write_4(sc, TWSI_CONTROL, control | sc->sc_twsien_iflg);
 
        timo = 0;
        do {

Reply via email to