Merge branch 'master' of http://git.denx.de/u-boot-sunxi
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index c02c015..c1b4cf5 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -46,28 +46,33 @@
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
 #endif
-	sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX);
-	sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX);
+#if defined(CONFIG_MACH_SUN8I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0_TX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0_RX);
+#else
+	sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF_UART0_TX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0_RX);
+#endif
 	sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
 #elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I))
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB_UART0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB_UART0);
 	sunxi_gpio_set_pull(SUNXI_GPB(23), SUNXI_GPIO_PULL_UP);
 #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN5I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB_UART0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB_UART0);
 	sunxi_gpio_set_pull(SUNXI_GPB(20), SUNXI_GPIO_PULL_UP);
 #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN6I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH20_UART0_TX);
-	sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH21_UART0_RX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH_UART0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH_UART0);
 	sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP);
 #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX);
-	sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG_UART1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG_UART1);
 	sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP);
 #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL2_R_UART_TX);
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL3_R_UART_RX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
 	sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
 #else
 #error Unsupported console port number. Please fix pin mux settings in board.c
diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c
index b00befb..f115a9c 100644
--- a/arch/arm/cpu/armv7/sunxi/rsb.c
+++ b/arch/arm/cpu/armv7/sunxi/rsb.c
@@ -21,15 +21,15 @@
 static void rsb_cfg_io(void)
 {
 #ifdef CONFIG_MACH_SUN8I
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL0_R_RSB_SCK);
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL1_R_RSB_SDA);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB);
 	sunxi_gpio_set_pull(SUNXI_GPL(0), 1);
 	sunxi_gpio_set_pull(SUNXI_GPL(1), 1);
 	sunxi_gpio_set_drv(SUNXI_GPL(0), 2);
 	sunxi_gpio_set_drv(SUNXI_GPL(1), 2);
 #elif defined CONFIG_MACH_SUN9I
-	sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN0_R_RSB_SCK);
-	sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN1_R_RSB_SDA);
+	sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB);
+	sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB);
 	sunxi_gpio_set_pull(SUNXI_GPN(0), 1);
 	sunxi_gpio_set_pull(SUNXI_GPN(1), 1);
 	sunxi_gpio_set_drv(SUNXI_GPN(0), 2);
diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c
index 524f25c..a0e9604 100644
--- a/arch/arm/cpu/armv7/sunxi/usbc.c
+++ b/arch/arm/cpu/armv7/sunxi/usbc.c
@@ -41,6 +41,7 @@
 	int usb_rst_mask;
 	int ahb_clk_mask;
 	int gpio_vbus;
+	int gpio_vbus_det;
 	int irq;
 	int id;
 } sunxi_usbc_hcd[] = {
@@ -80,12 +81,6 @@
 
 static int enabled_hcd_count;
 
-static bool use_axp_drivebus(int index)
-{
-	return index == 0 &&
-	       strcmp(CONFIG_USB0_VBUS_PIN, "axp_drivebus") == 0;
-}
-
 void *sunxi_usbc_get_io_base(int index)
 {
 	switch (index) {
@@ -102,9 +97,6 @@
 
 static int get_vbus_gpio(int index)
 {
-	if (use_axp_drivebus(index))
-		return -1;
-
 	switch (index) {
 	case 0: return sunxi_name_to_gpio(CONFIG_USB0_VBUS_PIN);
 	case 1: return sunxi_name_to_gpio(CONFIG_USB1_VBUS_PIN);
@@ -113,6 +105,14 @@
 	return -1;
 }
 
+static int get_vbus_detect_gpio(int index)
+{
+	switch (index) {
+	case 0: return sunxi_name_to_gpio(CONFIG_USB0_VBUS_DET);
+	}
+	return -1;
+}
+
 static void usb_phy_write(struct sunxi_usbc_hcd *sunxi_usbc, int addr,
 			  int data, int len)
 {
@@ -192,22 +192,35 @@
 int sunxi_usbc_request_resources(int index)
 {
 	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
+	int ret = 0;
 
 	sunxi_usbc->gpio_vbus = get_vbus_gpio(index);
-	if (sunxi_usbc->gpio_vbus != -1)
-		return gpio_request(sunxi_usbc->gpio_vbus, "usbc_vbus");
+	if (sunxi_usbc->gpio_vbus != -1) {
+		ret |= gpio_request(sunxi_usbc->gpio_vbus, "usbc_vbus");
+		ret |= gpio_direction_output(sunxi_usbc->gpio_vbus, 0);
+	}
+
+	sunxi_usbc->gpio_vbus_det = get_vbus_detect_gpio(index);
+	if (sunxi_usbc->gpio_vbus_det != -1) {
+		ret |= gpio_request(sunxi_usbc->gpio_vbus_det, "usbc_vbus_det");
+		ret |= gpio_direction_input(sunxi_usbc->gpio_vbus_det);
+	}
 
-	return 0;
+	return ret;
 }
 
 int sunxi_usbc_free_resources(int index)
 {
 	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
+	int ret = 0;
 
 	if (sunxi_usbc->gpio_vbus != -1)
-		return gpio_free(sunxi_usbc->gpio_vbus);
+		ret |= gpio_free(sunxi_usbc->gpio_vbus);
 
-	return 0;
+	if (sunxi_usbc->gpio_vbus_det != -1)
+		ret |= gpio_free(sunxi_usbc->gpio_vbus_det);
+
+	return ret;
 }
 
 void sunxi_usbc_enable(int index)
@@ -258,22 +271,38 @@
 {
 	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
-#ifdef AXP_DRIVEBUS
-	if (use_axp_drivebus(index))
-		axp_drivebus_enable();
-#endif
 	if (sunxi_usbc->gpio_vbus != -1)
-		gpio_direction_output(sunxi_usbc->gpio_vbus, 1);
+		gpio_set_value(sunxi_usbc->gpio_vbus, 1);
 }
 
 void sunxi_usbc_vbus_disable(int index)
 {
 	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
-#ifdef AXP_DRIVEBUS
-	if (use_axp_drivebus(index))
-		axp_drivebus_disable();
-#endif
 	if (sunxi_usbc->gpio_vbus != -1)
-		gpio_direction_output(sunxi_usbc->gpio_vbus, 0);
+		gpio_set_value(sunxi_usbc->gpio_vbus, 0);
+}
+
+int sunxi_usbc_vbus_detect(int index)
+{
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
+	int err, retries = 3;
+
+	if (sunxi_usbc->gpio_vbus_det == -1) {
+		eprintf("Error: invalid vbus detection pin\n");
+		return -1;
+	}
+
+	err = gpio_get_value(sunxi_usbc->gpio_vbus_det);
+	/*
+	 * Vbus may have been provided by the board and just been turned of
+	 * some milliseconds ago on reset, what we're measuring then is a
+	 * residual charge on Vbus, sleep a bit and try again.
+	 */
+	while (err > 0 && retries--) {
+		mdelay(100);
+		err = gpio_get_value(sunxi_usbc->gpio_vbus_det);
+	}
+
+	return err;
 }
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index dae6069..f403742 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -94,6 +94,13 @@
 #define SUNXI_TWI0_BASE			0x01c2ac00
 #define SUNXI_TWI1_BASE			0x01c2b000
 #define SUNXI_TWI2_BASE			0x01c2b400
+#ifdef CONFIG_MACH_SUN6I
+#define SUNXI_TWI3_BASE			0x01c0b800
+#endif
+#ifdef CONFIG_MACH_SUN7I
+#define SUNXI_TWI3_BASE			0x01c2b800
+#define SUNXI_TWI4_BASE			0x01c2c000
+#endif
 
 #define SUNXI_CAN_BASE			0x01c2bc00
 
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index f2c247d..ae7cbb7 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -84,7 +84,7 @@
 #define GPIO_CFG_INDEX(pin)	(((pin) & 0x1f) >> 3)
 #define GPIO_CFG_OFFSET(pin)	((((pin) & 0x1f) & 0x7) << 2)
 
-#define GPIO_DRV_INDEX(pin)   (((pin) & 0x1f) >> 4)
+#define GPIO_DRV_INDEX(pin)	(((pin) & 0x1f) >> 4)
 #define GPIO_DRV_OFFSET(pin)	((((pin) & 0x1f) & 0xf) << 1)
 
 #define GPIO_PULL_INDEX(pin)	(((pin) & 0x1f) >> 4)
@@ -142,71 +142,77 @@
 #define SUNXI_GPIO_INPUT	0
 #define SUNXI_GPIO_OUTPUT	1
 
-#define SUNXI_GPA0_EMAC		2
-#define SUN6I_GPA0_GMAC		2
-#define SUN7I_GPA0_GMAC		5
+#define SUNXI_GPA_EMAC		2
+#define SUN6I_GPA_GMAC		2
+#define SUN7I_GPA_GMAC		5
+#define SUN6I_GPA_SDC2		5
+#define SUN6I_GPA_SDC3		4
 
-#define SUNXI_GPB0_TWI0		2
+#define SUN4I_GPB_TWI0		2
+#define SUN4I_GPB_TWI1		2
+#define SUN5I_GPB_TWI1		2
+#define SUN4I_GPB_TWI2		2
+#define SUN5I_GPB_TWI2		2
+#define SUN4I_GPB_UART0		2
+#define SUN5I_GPB_UART0		2
 
-#define SUN4I_GPB22_UART0_TX	2
-#define SUN4I_GPB23_UART0_RX	2
+#define SUNXI_GPC_SDC2		3
+#define SUN6I_GPC_SDC3		4
 
-#define SUN5I_GPB19_UART0_TX	2
-#define SUN5I_GPB20_UART0_RX	2
+#define SUN8I_GPD_SDC1		3
+#define SUNXI_GPD_LCD0		2
+#define SUNXI_GPD_LVDS0		3
 
-#define SUNXI_GPC6_SDC2		3
+#define SUN5I_GPE_SDC2		3
+#define SUN8I_GPE_TWI2		3
 
-#define SUNXI_GPD0_LCD0		2
-#define SUNXI_GPD0_LVDS0	3
+#define SUNXI_GPF_SDC0		2
+#define SUNXI_GPF_UART0		4
+#define SUN8I_GPF_UART0		3
 
-#define SUNXI_GPF0_SDC0		2
+#define SUN4I_GPG_SDC1		4
+#define SUN5I_GPG_SDC1		2
+#define SUN6I_GPG_SDC1		2
+#define SUN8I_GPG_SDC1		2
+#define SUN6I_GPG_TWI3		2
+#define SUN5I_GPG_UART1		4
 
-#define SUNXI_GPF2_SDC0		2
+#define SUN4I_GPH_SDC1		5
+#define SUN6I_GPH_TWI0		2
+#define SUN8I_GPH_TWI0		2
+#define SUN6I_GPH_TWI1		2
+#define SUN8I_GPH_TWI1		2
+#define SUN6I_GPH_TWI2		2
+#define SUN6I_GPH_UART0		2
 
-#ifdef CONFIG_MACH_SUN8I
-#define SUNXI_GPF2_UART0_TX	3
-#define SUNXI_GPF4_UART0_RX	3
-#else
-#define SUNXI_GPF2_UART0_TX	4
-#define SUNXI_GPF4_UART0_RX	4
-#endif
-
-#define SUN4I_GPG0_SDC1		4
-
-#define SUN5I_GPG3_SDC1		2
-
-#define SUN5I_GPG3_UART1_TX	4
-#define SUN5I_GPG4_UART1_RX	4
-
-#define SUN4I_GPH22_SDC1	5
-
-#define SUN6I_GPH20_UART0_TX	2
-#define SUN6I_GPH21_UART0_RX	2
-
-#define SUN4I_GPI4_SDC3		2
+#define SUNXI_GPI_SDC3		2
+#define SUN7I_GPI_TWI3		3
+#define SUN7I_GPI_TWI4		3
 
 #define SUN6I_GPL0_R_P2WI_SCK	3
 #define SUN6I_GPL1_R_P2WI_SDA	3
 
-#define SUN8I_GPL0_R_RSB_SCK	2
-#define SUN8I_GPL1_R_RSB_SDA	2
-#define SUN8I_GPL2_R_UART_TX	2
-#define SUN8I_GPL3_R_UART_RX	2
+#define SUN8I_GPL_R_RSB		2
+#define SUN8I_GPL_R_UART	2
 
-#define SUN9I_GPN0_R_RSB_SCK	3
-#define SUN9I_GPN1_R_RSB_SDA    3
+#define SUN9I_GPN_R_RSB		3
 
 /* GPIO pin pull-up/down config */
 #define SUNXI_GPIO_PULL_DISABLE	0
 #define SUNXI_GPIO_PULL_UP	1
 #define SUNXI_GPIO_PULL_DOWN	2
 
+/* Virtual AXP0 GPIOs */
+#define SUNXI_GPIO_AXP0_VBUS_DETECT	8
+#define SUNXI_GPIO_AXP0_VBUS_ENABLE	9
+
 void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
 void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
 int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset);
 int sunxi_gpio_get_cfgpin(u32 pin);
 int sunxi_gpio_set_drv(u32 pin, u32 val);
 int sunxi_gpio_set_pull(u32 pin, u32 val);
+int sunxi_name_to_gpio_bank(const char *name);
 int sunxi_name_to_gpio(const char *name);
 #define name_to_gpio(name) sunxi_name_to_gpio(name)
 
diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h
index dc5406b..561cd2b 100644
--- a/arch/arm/include/asm/arch-sunxi/i2c.h
+++ b/arch/arm/include/asm/arch-sunxi/i2c.h
@@ -8,7 +8,22 @@
 
 #include <asm/arch/cpu.h>
 
-#define CONFIG_I2C_MVTWSI_BASE	SUNXI_TWI0_BASE
+#ifdef CONFIG_I2C0_ENABLE
+#define CONFIG_I2C_MVTWSI_BASE0	SUNXI_TWI0_BASE
+#endif
+#ifdef CONFIG_I2C1_ENABLE
+#define CONFIG_I2C_MVTWSI_BASE1	SUNXI_TWI1_BASE
+#endif
+#ifdef CONFIG_I2C2_ENABLE
+#define CONFIG_I2C_MVTWSI_BASE2	SUNXI_TWI2_BASE
+#endif
+#ifdef CONFIG_I2C3_ENABLE
+#define CONFIG_I2C_MVTWSI_BASE3	SUNXI_TWI3_BASE
+#endif
+#ifdef CONFIG_I2C4_ENABLE
+#define CONFIG_I2C_MVTWSI_BASE4	SUNXI_TWI4_BASE
+#endif
+
 /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */
 #define CONFIG_SYS_TCLK		24000000
 
diff --git a/arch/arm/include/asm/arch-sunxi/usbc.h b/arch/arm/include/asm/arch-sunxi/usbc.h
index 1330733..ab0f272 100644
--- a/arch/arm/include/asm/arch-sunxi/usbc.h
+++ b/arch/arm/include/asm/arch-sunxi/usbc.h
@@ -20,4 +20,5 @@
 void sunxi_usbc_disable(int index);
 void sunxi_usbc_vbus_enable(int index);
 void sunxi_usbc_vbus_disable(int index);
+int sunxi_usbc_vbus_detect(int index);
 void sunxi_usbc_enable_squelch_detect(int index, int enable);
diff --git a/arch/arm/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h
index e77ac40..d049395 100644
--- a/arch/arm/mach-kirkwood/include/mach/config.h
+++ b/arch/arm/mach-kirkwood/include/mach/config.h
@@ -44,7 +44,7 @@
 #define CONFIG_SYS_INIT_SP_ADDR		0xC8012000
 #define CONFIG_NR_DRAM_BANKS_MAX	2
 
-#define CONFIG_I2C_MVTWSI_BASE	KW_TWSI_BASE
+#define CONFIG_I2C_MVTWSI_BASE0	KW_TWSI_BASE
 #define MV_UART_CONSOLE_BASE	KW_UART0_BASE
 #define MV_SATA_BASE		KW_SATA_BASE
 #define MV_SATA_PORT0_OFFSET	KW_SATA_PORT0_OFFSET
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 2fcab60..88e3358 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -212,6 +212,25 @@
 	---help---
 	See MMC0_CD_PIN help text.
 
+config MMC1_PINS
+	string "Pins for mmc1"
+	default ""
+	---help---
+	Set the pins used for mmc1, when applicable. This takes a string in the
+	format understood by sunxi_name_to_gpio_bank, e.g. PH for port H.
+
+config MMC2_PINS
+	string "Pins for mmc2"
+	default ""
+	---help---
+	See MMC1_PINS help text.
+
+config MMC3_PINS
+	string "Pins for mmc3"
+	default ""
+	---help---
+	See MMC1_PINS help text.
+
 config MMC_SUNXI_SLOT_EXTRA
 	int "mmc extra slot number"
 	default -1
@@ -229,7 +248,6 @@
 
 config USB0_VBUS_DET
 	string "Vbus detect pin for usb0 (otg)"
-	depends on USB_MUSB_SUNXI
 	default ""
 	---help---
 	Set the Vbus detect pin for usb0 (otg). This takes a string in the
@@ -251,6 +269,44 @@
 	---help---
 	See USB1_VBUS_PIN help text.
 
+config I2C0_ENABLE
+	bool "Enable I2C/TWI controller 0"
+	default y if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
+	default n if MACH_SUN6I || MACH_SUN8I
+	---help---
+	This allows enabling I2C/TWI controller 0 by muxing its pins, enabling
+	its clock and setting up the bus. This is especially useful on devices
+	with slaves connected to the bus or with pins exposed through e.g. an
+	expansion port/header.
+
+config I2C1_ENABLE
+	bool "Enable I2C/TWI controller 1"
+	default n
+	---help---
+	See I2C0_ENABLE help text.
+
+config I2C2_ENABLE
+	bool "Enable I2C/TWI controller 2"
+	default n
+	---help---
+	See I2C0_ENABLE help text.
+
+if MACH_SUN6I || MACH_SUN7I
+config I2C3_ENABLE
+	bool "Enable I2C/TWI controller 3"
+	default n
+	---help---
+	See I2C0_ENABLE help text.
+endif
+
+if MACH_SUN7I
+config I2C4_ENABLE
+	bool "Enable I2C/TWI controller 4"
+	default n
+	---help---
+	See I2C0_ENABLE help text.
+endif
+
 config VIDEO
 	boolean "Enable graphical uboot console on HDMI, LCD or VGA"
 	default y
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index be48213..75e8b5a 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -42,15 +42,18 @@
 A20-OLINUXINO-LIME BOARD
 M:	FUKAUMI Naoki <naobsd@gmail.com>
 S:	Maintained
-F:	board/sunxi/dram_a20_olinuxino_l.c
 F:	configs/A20-OLinuXino-Lime_defconfig
 
 A20-OLINUXINO-LIME2 BOARD
 M:	Iain Paton <ipaton0@gmail.com>
 S:	Maintained
-F:	board/sunxi/dram_a20_olinuxino_l2.c
 F:	configs/A20-OLinuXino-Lime2_defconfig
 
+AINOL AW1 BOARD
+M:	Paul Kocialkowski <contact@paulk.fr>
+S:	Maintained
+F:	configs/Ainol_AW1_defconfig
+
 AMPE A76 BOARD
 M:	Paul Kocialkowski <contact@paulk.fr>
 S:	Maintained
@@ -84,11 +87,20 @@
 S:	Maintained
 F:	configs/Hummingbird_A31_defconfig
 
-INET-86VS BOARD
+INET 3F BOARD
+M:	Paul Kocialkowski <contact@paulk.fr>
+S:	Maintained
+F:	configs/iNet_3F_defconfig
+
+INET 3W BOARD
+M:	Paul Kocialkowski <contact@paulk.fr>
+S:	Maintained
+F:	configs/iNet_3W_defconfig
+
+INET 86VS BOARD
 M:	Michal Suchanek <hramrach@gmail.com>
 S:	Maintained
-F:	board/sunxi/dram_inet_86vs.c
-F:	configs/Inet_86VS_defconfig
+F:	configs/iNet_86VS_defconfig
 
 IPPO-Q8H-V5 BOARD
 M:	Chen-Yu Tsai <wens@csie.org>
@@ -120,6 +132,11 @@
 S:	Maintained
 F:	configs/Mele_M5_defconfig
 
+MIXTILE-LOFTQ BOARD
+M:  Phil Han <pengphei@sina.com>
+S:  Maintained
+F:  configs/mixtile_loftq_defconfig
+
 MK808C BOARD
 M:	Marcus Cooper <codekipper@gmail.com>
 S:	Maintained
@@ -144,3 +161,8 @@
 M:	Aleksei Mamlin <mamlinav@gmail.com>
 S:	Maintained
 F:	configs/Wexler_TAB7200_defconfig
+
+YONES TOPTECH BD1078 BOARD
+M:	Paul Kocialkowski <contact@paulk.fr>
+S:	Maintained
+F:	configs/Yones_Toptech_BD1078_defconfig
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 808bf82..dda50b5 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -71,42 +71,163 @@
 static void mmc_pinmux_setup(int sdc)
 {
 	unsigned int pin;
+	__maybe_unused int pins;
 
 	switch (sdc) {
 	case 0:
-		/* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */
+		/* SDC0: PF0-PF5 */
 		for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) {
-			sunxi_gpio_set_cfgpin(pin, SUNXI_GPF0_SDC0);
+			sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0);
 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
 			sunxi_gpio_set_drv(pin, 2);
 		}
 		break;
 
 	case 1:
-		/* CMD-PG3, CLK-PG4, D0~D3-PG5-8 */
+		pins = sunxi_name_to_gpio_bank(CONFIG_MMC1_PINS);
+
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
+		if (pins == SUNXI_GPIO_H) {
+			/* SDC1: PH22-PH-27 */
+			for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		} else {
+			/* SDC1: PG0-PG5 */
+			for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		}
+#elif defined(CONFIG_MACH_SUN5I)
+		/* SDC1: PG3-PG8 */
 		for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) {
-			sunxi_gpio_set_cfgpin(pin, SUN5I_GPG3_SDC1);
+			sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1);
+			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+			sunxi_gpio_set_drv(pin, 2);
+		}
+#elif defined(CONFIG_MACH_SUN6I)
+		/* SDC1: PG0-PG5 */
+		for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
+			sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1);
 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
 			sunxi_gpio_set_drv(pin, 2);
 		}
+#elif defined(CONFIG_MACH_SUN8I)
+		if (pins == SUNXI_GPIO_D) {
+			/* SDC1: PD2-PD7 */
+			for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN8I_GPD_SDC1);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		} else {
+			/* SDC1: PG0-PG5 */
+			for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		}
+#endif
 		break;
 
 	case 2:
-		/* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */
+		pins = sunxi_name_to_gpio_bank(CONFIG_MMC2_PINS);
+
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
+		/* SDC2: PC6-PC11 */
 		for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) {
-			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC6_SDC2);
+			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
+			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+			sunxi_gpio_set_drv(pin, 2);
+		}
+#elif defined(CONFIG_MACH_SUN5I)
+		if (pins == SUNXI_GPIO_E) {
+			/* SDC2: PE4-PE9 */
+			for (pin = SUNXI_GPE(4); pin <= SUNXI_GPD(9); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN5I_GPE_SDC2);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		} else {
+			/* SDC2: PC6-PC15 */
+			for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		}
+#elif defined(CONFIG_MACH_SUN6I)
+		if (pins == SUNXI_GPIO_A) {
+			/* SDC2: PA9-PA14 */
+			for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC2);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		} else {
+			/* SDC2: PC6-PC15, PC24 */
+			for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+
+			sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
+			sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
+			sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
+		}
+#elif defined(CONFIG_MACH_SUN8I)
+		/* SDC2: PC5-PC6, PC8-PC16 */
+		for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
+			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
+			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+			sunxi_gpio_set_drv(pin, 2);
+		}
+
+		for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) {
+			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
 			sunxi_gpio_set_drv(pin, 2);
 		}
+#endif
 		break;
 
 	case 3:
-		/* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */
+		pins = sunxi_name_to_gpio_bank(CONFIG_MMC3_PINS);
+
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
+		/* SDC3: PI4-PI9 */
 		for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) {
-			sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3);
+			sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3);
 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
 			sunxi_gpio_set_drv(pin, 2);
 		}
+#elif defined(CONFIG_MACH_SUN6I)
+		if (pins == SUNXI_GPIO_A) {
+			/* SDC3: PA9-PA14 */
+			for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC3);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+		} else {
+			/* SDC3: PC6-PC15, PC24 */
+			for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
+				sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3);
+				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+				sunxi_gpio_set_drv(pin, 2);
+			}
+
+			sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3);
+			sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
+			sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
+		}
+#endif
 		break;
 
 	default:
@@ -155,9 +276,82 @@
 
 void i2c_init_board(void)
 {
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0);
-	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0);
+#ifdef CONFIG_I2C0_ENABLE
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0);
 	clock_twi_onoff(0, 1);
+#elif defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
+	clock_twi_onoff(0, 1);
+#elif defined(CONFIG_MACH_SUN8I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
+	clock_twi_onoff(0, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C1_ENABLE
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1);
+	clock_twi_onoff(1, 1);
+#elif defined(CONFIG_MACH_SUN5I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1);
+	clock_twi_onoff(1, 1);
+#elif defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1);
+	clock_twi_onoff(1, 1);
+#elif defined(CONFIG_MACH_SUN8I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
+	clock_twi_onoff(1, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C2_ENABLE
+#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2);
+	clock_twi_onoff(2, 1);
+#elif defined(CONFIG_MACH_SUN5I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2);
+	clock_twi_onoff(2, 1);
+#elif defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2);
+	clock_twi_onoff(2, 1);
+#elif defined(CONFIG_MACH_SUN8I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
+	clock_twi_onoff(2, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C3_ENABLE
+#if defined(CONFIG_MACH_SUN6I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3);
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3);
+	clock_twi_onoff(3, 1);
+#elif defined(CONFIG_MACH_SUN7I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3);
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3);
+	clock_twi_onoff(3, 1);
+#endif
+#endif
+
+#ifdef CONFIG_I2C4_ENABLE
+#if defined(CONFIG_MACH_SUN7I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4);
+	sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4);
+	clock_twi_onoff(4, 1);
+#endif
+#endif
+
 #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
 	soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA);
 	soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL);
@@ -241,23 +435,41 @@
 };
 #endif
 
+#ifdef CONFIG_USB_GADGET
+int g_dnl_board_usb_cable_connected(void)
+{
+	return sunxi_usbc_vbus_detect(0);
+}
+#endif
+
 #ifdef CONFIG_MISC_INIT_R
 int misc_init_r(void)
 {
+	char serial_string[17] = { 0 };
 	unsigned int sid[4];
+	uint8_t mac_addr[6];
+	int ret;
 
-	if (!getenv("ethaddr") && sunxi_get_sid(sid) == 0 &&
-			sid[0] != 0 && sid[3] != 0) {
-		uint8_t mac_addr[6];
+	ret = sunxi_get_sid(sid);
+	if (ret == 0 && sid[0] != 0 && sid[3] != 0) {
+		if (!getenv("ethaddr")) {
+			/* Non OUI / registered MAC address */
+			mac_addr[0] = 0x02;
+			mac_addr[1] = (sid[0] >>  0) & 0xff;
+			mac_addr[2] = (sid[3] >> 24) & 0xff;
+			mac_addr[3] = (sid[3] >> 16) & 0xff;
+			mac_addr[4] = (sid[3] >>  8) & 0xff;
+			mac_addr[5] = (sid[3] >>  0) & 0xff;
 
-		mac_addr[0] = 0x02; /* Non OUI / registered MAC address */
-		mac_addr[1] = (sid[0] >>  0) & 0xff;
-		mac_addr[2] = (sid[3] >> 24) & 0xff;
-		mac_addr[3] = (sid[3] >> 16) & 0xff;
-		mac_addr[4] = (sid[3] >>  8) & 0xff;
-		mac_addr[5] = (sid[3] >>  0) & 0xff;
+			eth_setenv_enetaddr("ethaddr", mac_addr);
+		}
 
-		eth_setenv_enetaddr("ethaddr", mac_addr);
+		if (!getenv("serial#")) {
+			snprintf(serial_string, sizeof(serial_string),
+				"%08x%08x", sid[0], sid[3]);
+
+			setenv("serial#", serial_string);
+		}
 	}
 
 #if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c
index 8849132..63a7360 100644
--- a/board/sunxi/gmac.c
+++ b/board/sunxi/gmac.c
@@ -39,45 +39,45 @@
 		if (pin == SUNXI_GPA(9) || pin == SUNXI_GPA(14))
 			continue;
 #endif
-		sunxi_gpio_set_cfgpin(pin, SUN7I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN7I_GPA_GMAC);
 		sunxi_gpio_set_drv(pin, 3);
 	}
 #elif defined CONFIG_RGMII
 	/* Configure sun6i RGMII mode pin mux settings */
 	for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(3); pin++) {
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 		sunxi_gpio_set_drv(pin, 3);
 	}
 	for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 		sunxi_gpio_set_drv(pin, 3);
 	}
 	for (pin = SUNXI_GPA(19); pin <= SUNXI_GPA(20); pin++) {
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 		sunxi_gpio_set_drv(pin, 3);
 	}
 	for (pin = SUNXI_GPA(25); pin <= SUNXI_GPA(27); pin++) {
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 		sunxi_gpio_set_drv(pin, 3);
 	}
 #elif defined CONFIG_GMII
 	/* Configure sun6i GMII mode pin mux settings */
 	for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(27); pin++) {
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 		sunxi_gpio_set_drv(pin, 2);
 	}
 #else
 	/* Configure sun6i MII mode pin mux settings */
 	for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(3); pin++)
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 	for (pin = SUNXI_GPA(8); pin <= SUNXI_GPA(9); pin++)
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 	for (pin = SUNXI_GPA(11); pin <= SUNXI_GPA(14); pin++)
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 	for (pin = SUNXI_GPA(19); pin <= SUNXI_GPA(24); pin++)
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 	for (pin = SUNXI_GPA(26); pin <= SUNXI_GPA(27); pin++)
-		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC);
+		sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
 #endif
 
 #ifdef CONFIG_RGMII
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index 8c76360..4fcff92 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -1,6 +1,9 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-olinuxino-lime2.dtb"
+CONFIG_MMC0_CD_PIN="PH1"
+CONFIG_USB0_VBUS_PIN="PC17"
+CONFIG_USB0_VBUS_DET="PH5"
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN7I=y
diff --git a/configs/Ainol_AW1_defconfig b/configs/Ainol_AW1_defconfig
new file mode 100644
index 0000000..e5c2e21
--- /dev/null
+++ b/configs/Ainol_AW1_defconfig
@@ -0,0 +1,22 @@
+# The Ainol AW1 is an A20 based tablet with a 800x480 lcd screen, sdio wifi,
+# volume up/down and home buttons, micro-sd slot, micro usb (otg), headphones    
+# connector and a SPCI modem connector.
+#
+# Also see: http://linux-sunxi.org/Ainol_AW1
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
+CONFIG_FDTFILE="sun7i-a20-ainol-aw1.dtb"
+CONFIG_MMC0_CD_PIN="PH1"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:40000,le:87,ri:112,up:38,lo:141,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_POWER="PH8"
+CONFIG_VIDEO_LCD_BL_EN="PH7"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN7I=y
+CONFIG_DRAM_CLK=432
+CONFIG_DRAM_ZQ=123
+CONFIG_DRAM_EMR1=4
diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig
index af8aefa..af7638d 100644
--- a/configs/Ampe_A76_defconfig
+++ b/configs/Ampe_A76_defconfig
@@ -1,9 +1,10 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER"
 CONFIG_FDTFILE="sun5i-a13-ampe-a76.dtb"
+CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="PG12"
-CONFIG_USB0_VBUS_DET="PG01"
+CONFIG_USB0_VBUS_DET="PG1"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_EN="AXP0-1"
diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig
index 05b11a0..d866ad1 100644
--- a/configs/Cubieboard2_defconfig
+++ b/configs/Cubieboard2_defconfig
@@ -1,6 +1,7 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-cubieboard2.dtb"
+CONFIG_MMC0_CD_PIN="PH1"
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN7I=y
diff --git a/configs/Ippo_q8h_v1_2_defconfig b/configs/Ippo_q8h_v1_2_defconfig
index 0c88edd..e003b4c 100644
--- a/configs/Ippo_q8h_v1_2_defconfig
+++ b/configs/Ippo_q8h_v1_2_defconfig
@@ -2,8 +2,8 @@
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
 CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v1.2.dtb"
 CONFIG_USB_MUSB_SUNXI=y
-CONFIG_USB0_VBUS_PIN="axp_drivebus"
-CONFIG_USB0_VBUS_DET="axp_vbus_detect"
+CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig
index 16ba03b..87d898e 100644
--- a/configs/Ippo_q8h_v5_defconfig
+++ b/configs/Ippo_q8h_v5_defconfig
@@ -2,8 +2,8 @@
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
 CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v5.dtb"
 CONFIG_USB_MUSB_SUNXI=y
-CONFIG_USB0_VBUS_PIN="axp_drivebus"
-CONFIG_USB0_VBUS_DET="axp_vbus_detect"
+CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
diff --git a/configs/TZX-Q8-713B7_defconfig b/configs/TZX-Q8-713B7_defconfig
index 4ff4542..0953554 100644
--- a/configs/TZX-Q8-713B7_defconfig
+++ b/configs/TZX-Q8-713B7_defconfig
@@ -1,6 +1,7 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER"
 CONFIG_FDTFILE="sun5i-a13-tzx-q8-713b7.dtb"
+CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="PG12"
 CONFIG_USB0_VBUS_DET="PG1"
diff --git a/configs/Yones_Toptech_BD1078_defconfig b/configs/Yones_Toptech_BD1078_defconfig
new file mode 100644
index 0000000..00ede67
--- /dev/null
+++ b/configs/Yones_Toptech_BD1078_defconfig
@@ -0,0 +1,29 @@
+# The Yones Toptech BD1078 is an A20 based 10" tablet with a 1024x600 lcd
+# screen, volume up/down and back buttons, headphones jack, mini hdmi, micro
+# usb (otg), micro usb (host), external micro-sd slot and a separate internal
+# micro-sd slot.
+#
+# Also see: http://linux-sunxi.org/Yones_Toptech_BD1078
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
+CONFIG_FDTFILE="sun7i-a20-yones-toptech-bd1078.dtb"
+CONFIG_MMC_SUNXI_SLOT_EXTRA=1
+CONFIG_MMC0_CD_PIN="PH1"
+CONFIG_MMC1_CD_PIN="PH2"
+CONFIG_MMC1_PINS="PH"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:24,pclk_khz:63000,le:32,ri:287,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_DCLK_PHASE=0
+CONFIG_VIDEO_LCD_PANEL_LVDS=y
+CONFIG_VIDEO_LCD_POWER="PH8"
+CONFIG_VIDEO_LCD_BL_EN="PH7"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW=n
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN7I=y
+CONFIG_DRAM_CLK=408
+CONFIG_DRAM_ZQ=127
+CONFIG_DRAM_EMR1=4
diff --git a/configs/iNet_3F_defconfig b/configs/iNet_3F_defconfig
new file mode 100644
index 0000000..4225b85
--- /dev/null
+++ b/configs/iNet_3F_defconfig
@@ -0,0 +1,20 @@
+# The iNet 3F is an A10 tablet with 1GiB RAM and a 1024x768 screen.
+# Also see: http://linux-sunxi.org/INet_3F
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
+CONFIG_FDTFILE="sun4i-a10-inet-3f.dtb"
+CONFIG_MMC0_CD_PIN="PH1"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_USB0_VBUS_DET="PH5"
+CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:18,pclk_khz:100000,le:799,ri:260,up:15,lo:16,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_PANEL_LVDS=y
+CONFIG_VIDEO_LCD_POWER="PH8"
+CONFIG_VIDEO_LCD_BL_EN="PH7"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN4I=y
+CONFIG_DRAM_CLK=432
+CONFIG_DRAM_ZQ=123
+CONFIG_DRAM_EMR1=4
diff --git a/configs/iNet_3W_defconfig b/configs/iNet_3W_defconfig
new file mode 100644
index 0000000..0a8e0f5
--- /dev/null
+++ b/configs/iNet_3W_defconfig
@@ -0,0 +1,19 @@
+# The iNet 3W is an A10 tablet with 1GiB RAM and a 1024x768 screen.
+# Also see: http://linux-sunxi.org/INet_3W
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
+CONFIG_FDTFILE="sun4i-a10-inet-3w.dtb"
+CONFIG_MMC0_CD_PIN="PH20"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB9"
+CONFIG_USB0_VBUS_DET="PH5"
+CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:24,pclk_khz:65000,le:159,ri:160,up:22,lo:15,hs:1,vs:1,sync:3,vmode:0"
+CONFIG_VIDEO_LCD_POWER="PH8"
+CONFIG_VIDEO_LCD_BL_EN="PH7"
+CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN4I=y
+CONFIG_DRAM_CLK=408
+CONFIG_DRAM_ZQ=127
+CONFIG_DRAM_EMR1=4
diff --git a/configs/Inet_86VS_defconfig b/configs/iNet_86VS_defconfig
similarity index 100%
rename from configs/Inet_86VS_defconfig
rename to configs/iNet_86VS_defconfig
diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig
new file mode 100644
index 0000000..47453cd
--- /dev/null
+++ b/configs/mixtile_loftq_defconfig
@@ -0,0 +1,21 @@
+# The Mixtile LOFT-Q is an A31 based board with 2G RAM, 8G EMMC, sdio wifi,
+# 1Gbit ethernet, HDMI display, toslink audio plug, 4 USB2.0 port, external
+# USB2SATA connector, sd card plug, 3x60 external fpic expansion connector,
+# NXP JN5168 zigbee gw, remote support.
+#
+# Also see http://focalcrest.com/en/pc.html#pro02
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPA(21)"
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN6I=y
+CONFIG_DRAM_CLK=312
+CONFIG_DRAM_ZQ=251
+CONFIG_MMC_SUNXI_SLOT=0
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+# Wifi power
+CONFIG_AXP221_ALDO1_VOLT=3300
+# Vbus gpio for usb1
+CONFIG_USB1_VBUS_PIN="PH24"
+# No Vbus gpio for usb2
+CONFIG_USB2_VBUS_PIN=""
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 6296092..510123f 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -21,6 +21,9 @@
 #ifdef CONFIG_AXP209_POWER
 #include <axp209.h>
 #endif
+#ifdef CONFIG_AXP221_POWER
+#include <axp221.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -115,6 +118,20 @@
 	return sunxi_gpio_output(gpio, value);
 }
 
+int sunxi_name_to_gpio_bank(const char *name)
+{
+	int group = 0;
+
+	if (*name == 'P' || *name == 'p')
+		name++;
+	if (*name >= 'A') {
+		group = *name - (*name > 'a' ? 'a' : 'A');
+		return group;
+	}
+
+	return -1;
+}
+
 int sunxi_name_to_gpio(const char *name)
 {
 	int group = 0;
@@ -125,6 +142,12 @@
 #ifdef AXP_GPIO
 	if (strncasecmp(name, "AXP0-", 5) == 0) {
 		name += 5;
+		if (strcmp(name, "VBUS-DETECT") == 0)
+			return SUNXI_GPIO_AXP0_START +
+				SUNXI_GPIO_AXP0_VBUS_DETECT;
+		if (strcmp(name, "VBUS-ENABLE") == 0)
+			return SUNXI_GPIO_AXP0_START +
+				SUNXI_GPIO_AXP0_VBUS_ENABLE;
 		pin = simple_strtol(name, &eptr, 10);
 		if (!*name || *eptr)
 			return -1;
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 6f6edd5..f20d1b2 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -14,7 +14,7 @@
 #include <asm/io.h>
 
 /*
- * include a file that will provide CONFIG_I2C_MVTWSI_BASE
+ * include a file that will provide CONFIG_I2C_MVTWSI_BASE*
  * and possibly other settings
  */
 
@@ -91,11 +91,39 @@
 #define	MVTWSI_STATUS_IDLE		0xF8
 
 /*
- * The single instance of the controller we'll be dealing with
+ * MVTWSI controller base
  */
 
-static struct  mvtwsi_registers *twsi =
-	(struct  mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE;
+static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap)
+{
+	switch (adap->hwadapnr) {
+#ifdef CONFIG_I2C_MVTWSI_BASE0
+	case 0:
+		return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE0;
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE1
+	case 1:
+		return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE1;
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE2
+	case 2:
+		return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE2;
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE3
+	case 3:
+		return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE3;
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE4
+	case 4:
+		return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4;
+#endif
+	default:
+		printf("Missing mvtwsi controller %d base\n", adap->hwadapnr);
+		break;
+	}
+
+	return NULL;
+}
 
 /*
  * Returned statuses are 0 for success and nonzero otherwise.
@@ -117,8 +145,9 @@
  * Wait for IFLG to raise, or return 'timeout'; then if status is as expected,
  * return 0 (ok) or return 'wrong status'.
  */
-static int twsi_wait(int expected_status)
+static int twsi_wait(struct i2c_adapter *adap, int expected_status)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
 	int control, status;
 	int timeout = 1000;
 
@@ -153,35 +182,40 @@
  * Assert the START condition, either in a single I2C transaction
  * or inside back-to-back ones (repeated starts).
  */
-static int twsi_start(int expected_status)
+static int twsi_start(struct i2c_adapter *adap, int expected_status)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
+
 	/* globally set TWSIEN in case it was not */
 	twsi_control_flags |= MVTWSI_CONTROL_TWSIEN;
 	/* assert START */
 	writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control);
 	/* wait for controller to process START */
-	return twsi_wait(expected_status);
+	return twsi_wait(adap, expected_status);
 }
 
 /*
  * Send a byte (i2c address or data).
  */
-static int twsi_send(u8 byte, int expected_status)
+static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
+
 	/* put byte in data register for sending */
 	writel(byte, &twsi->data);
 	/* clear any pending interrupt -- that'll cause sending */
 	writel(twsi_control_flags, &twsi->control);
 	/* wait for controller to receive byte and check ACK */
-	return twsi_wait(expected_status);
+	return twsi_wait(adap, expected_status);
 }
 
 /*
  * Receive a byte.
  * Global mvtwsi_control_flags variable says if we should ack or nak.
  */
-static int twsi_recv(u8 *byte)
+static int twsi_recv(struct i2c_adapter *adap, u8 *byte)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
 	int expected_status, status;
 
 	/* compute expected status based on ACK bit in global control flags */
@@ -192,7 +226,7 @@
 	/* acknowledge *previous state* and launch receive */
 	writel(twsi_control_flags, &twsi->control);
 	/* wait for controller to receive byte and assert ACK or NAK */
-	status = twsi_wait(expected_status);
+	status = twsi_wait(adap, expected_status);
 	/* if we did receive expected byte then store it */
 	if (status == 0)
 		*byte = readl(&twsi->data);
@@ -204,8 +238,9 @@
  * Assert the STOP condition.
  * This is also used to force the bus back in idle (SDA=SCL=1).
  */
-static int twsi_stop(int status)
+static int twsi_stop(struct i2c_adapter *adap, int status)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
 	int control, stop_status;
 	int timeout = 1000;
 
@@ -244,6 +279,7 @@
  */
 static void twsi_reset(struct i2c_adapter *adap)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
 	/* ensure controller will be enabled by any twsi*() function */
 	twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
 	/* reset controller */
@@ -259,6 +295,7 @@
 static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
 					   unsigned int requested_speed)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
 	unsigned int tmp_speed, highest_speed, n, m;
 	unsigned int baud = 0x44; /* baudrate at controller reset */
 
@@ -281,6 +318,8 @@
 
 static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 {
+	struct mvtwsi_registers *twsi = twsi_get_base(adap);
+
 	/* reset controller */
 	twsi_reset(adap);
 	/* set speed */
@@ -289,7 +328,7 @@
 	writel(slaveadd, &twsi->slave_address);
 	writel(0, &twsi->xtnd_slave_addr);
 	/* assert STOP but don't care for the result */
-	(void) twsi_stop(0);
+	(void) twsi_stop(adap, 0);
 }
 
 /*
@@ -297,7 +336,8 @@
  * Common to i2c_probe, i2c_read and i2c_write.
  * Expected address status will derive from direction bit (bit 0) in addr.
  */
-static int i2c_begin(int expected_start_status, u8 addr)
+static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
+		     u8 addr)
 {
 	int status, expected_addr_status;
 
@@ -307,10 +347,10 @@
 	else /* writing */
 		expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
 	/* assert START */
-	status = twsi_start(expected_start_status);
+	status = twsi_start(adap, expected_start_status);
 	/* send out the address if the start went well */
 	if (status == 0)
-		status = twsi_send(addr, expected_addr_status);
+		status = twsi_send(adap, addr, expected_addr_status);
 	/* return ok or status of first failure to caller */
 	return status;
 }
@@ -325,12 +365,12 @@
 	int status;
 
 	/* begin i2c read */
-	status = i2c_begin(MVTWSI_STATUS_START, (chip << 1) | 1);
+	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1);
 	/* dummy read was accepted: receive byte but NAK it. */
 	if (status == 0)
-		status = twsi_recv(&dummy_byte);
+		status = twsi_recv(adap, &dummy_byte);
 	/* Stop transaction */
-	twsi_stop(0);
+	twsi_stop(adap, 0);
 	/* return 0 or status of first failure */
 	return status;
 }
@@ -351,15 +391,15 @@
 	int status;
 
 	/* begin i2c write to send the address bytes */
-	status = i2c_begin(MVTWSI_STATUS_START, (chip << 1));
+	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
 	/* send addr bytes */
 	while ((status == 0) && alen--)
-		status = twsi_send(addr >> (8*alen),
+		status = twsi_send(adap, addr >> (8*alen),
 			MVTWSI_STATUS_DATA_W_ACK);
 	/* begin i2c read to receive eeprom data bytes */
 	if (status == 0)
-		status = i2c_begin(
-			MVTWSI_STATUS_REPEATED_START, (chip << 1) | 1);
+		status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
+				   (chip << 1) | 1);
 	/* prepare ACK if at least one byte must be received */
 	if (length > 0)
 		twsi_control_flags |= MVTWSI_CONTROL_ACK;
@@ -369,10 +409,10 @@
 		if (length == 0)
 			twsi_control_flags &= ~MVTWSI_CONTROL_ACK;
 		/* read current byte */
-		status = twsi_recv(data++);
+		status = twsi_recv(adap, data++);
 	}
 	/* Stop transaction */
-	status = twsi_stop(status);
+	status = twsi_stop(adap, status);
 	/* return 0 or status of first failure */
 	return status;
 }
@@ -387,21 +427,51 @@
 	int status;
 
 	/* begin i2c write to send the eeprom adress bytes then data bytes */
-	status = i2c_begin(MVTWSI_STATUS_START, (chip << 1));
+	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
 	/* send addr bytes */
 	while ((status == 0) && alen--)
-		status = twsi_send(addr >> (8*alen),
+		status = twsi_send(adap, addr >> (8*alen),
 			MVTWSI_STATUS_DATA_W_ACK);
 	/* send data bytes */
 	while ((status == 0) && (length-- > 0))
-		status = twsi_send(*(data++), MVTWSI_STATUS_DATA_W_ACK);
+		status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK);
 	/* Stop transaction */
-	status = twsi_stop(status);
+	status = twsi_stop(adap, status);
 	/* return 0 or status of first failure */
 	return status;
 }
 
+#ifdef CONFIG_I2C_MVTWSI_BASE0
 U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe,
 			 twsi_i2c_read, twsi_i2c_write,
 			 twsi_i2c_set_bus_speed,
 			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0)
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE1
+U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe,
+			 twsi_i2c_read, twsi_i2c_write,
+			 twsi_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1)
+
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE2
+U_BOOT_I2C_ADAP_COMPLETE(twsi2, twsi_i2c_init, twsi_i2c_probe,
+			 twsi_i2c_read, twsi_i2c_write,
+			 twsi_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 2)
+
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE3
+U_BOOT_I2C_ADAP_COMPLETE(twsi3, twsi_i2c_init, twsi_i2c_probe,
+			 twsi_i2c_read, twsi_i2c_write,
+			 twsi_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 3)
+
+#endif
+#ifdef CONFIG_I2C_MVTWSI_BASE4
+U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe,
+			 twsi_i2c_read, twsi_i2c_write,
+			 twsi_i2c_set_bus_speed,
+			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4)
+
+#endif
diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
index 5a06d68..2a9fd56 100644
--- a/drivers/net/sunxi_emac.c
+++ b/drivers/net/sunxi_emac.c
@@ -497,7 +497,7 @@
 
 	/* Configure pin mux settings for MII Ethernet */
 	for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++)
-		sunxi_gpio_set_cfgpin(pin, SUNXI_GPA0_EMAC);
+		sunxi_gpio_set_cfgpin(pin, SUNXI_GPA_EMAC);
 
 	/* Set up clock gating */
 	setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC);
diff --git a/drivers/power/axp152.c b/drivers/power/axp152.c
index 27c2c4c..740a3b4 100644
--- a/drivers/power/axp152.c
+++ b/drivers/power/axp152.c
@@ -8,17 +8,6 @@
 #include <i2c.h>
 #include <axp152.h>
 
-enum axp152_reg {
-	AXP152_CHIP_VERSION = 0x3,
-	AXP152_DCDC2_VOLTAGE = 0x23,
-	AXP152_DCDC3_VOLTAGE = 0x27,
-	AXP152_DCDC4_VOLTAGE = 0x2B,
-	AXP152_LDO2_VOLTAGE = 0x2A,
-	AXP152_SHUTDOWN = 0x32,
-};
-
-#define AXP152_POWEROFF			(1 << 7)
-
 static int axp152_write(enum axp152_reg reg, u8 val)
 {
 	return i2c_write(0x30, reg, 1, &val, 1);
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index f8c9b77..1d7be49 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -7,45 +7,9 @@
 
 #include <common.h>
 #include <i2c.h>
+#include <asm/arch/gpio.h>
 #include <axp209.h>
 
-enum axp209_reg {
-	AXP209_POWER_STATUS = 0x00,
-	AXP209_CHIP_VERSION = 0x03,
-	AXP209_DCDC2_VOLTAGE = 0x23,
-	AXP209_DCDC3_VOLTAGE = 0x27,
-	AXP209_LDO24_VOLTAGE = 0x28,
-	AXP209_LDO3_VOLTAGE = 0x29,
-	AXP209_IRQ_ENABLE1 = 0x40,
-	AXP209_IRQ_ENABLE2 = 0x41,
-	AXP209_IRQ_ENABLE3 = 0x42,
-	AXP209_IRQ_ENABLE4 = 0x43,
-	AXP209_IRQ_ENABLE5 = 0x44,
-	AXP209_IRQ_STATUS5 = 0x4c,
-	AXP209_SHUTDOWN = 0x32,
-	AXP209_GPIO0_CTRL = 0x90,
-	AXP209_GPIO1_CTRL = 0x92,
-	AXP209_GPIO2_CTRL = 0x93,
-	AXP209_GPIO_STATE = 0x94,
-	AXP209_GPIO3_CTRL = 0x95,
-};
-
-#define AXP209_POWER_STATUS_ON_BY_DC	(1 << 0)
-
-#define AXP209_IRQ5_PEK_UP		(1 << 6)
-#define AXP209_IRQ5_PEK_DOWN		(1 << 5)
-
-#define AXP209_POWEROFF			(1 << 7)
-
-#define AXP209_GPIO_OUTPUT_LOW		0x00 /* Drive pin low */
-#define AXP209_GPIO_OUTPUT_HIGH		0x01 /* Drive pin high */
-#define AXP209_GPIO_INPUT		0x02 /* Float pin */
-
-/* GPIO3 is different from the others */
-#define AXP209_GPIO3_OUTPUT_LOW		0x00 /* Drive pin low, Output mode */
-#define AXP209_GPIO3_OUTPUT_HIGH	0x02 /* Float pin, Output mode */
-#define AXP209_GPIO3_INPUT		0x06 /* Float pin, Input mode */
-
 static int axp209_write(enum axp209_reg reg, u8 val)
 {
 	return i2c_write(0x34, reg, 1, &val, 1);
@@ -205,6 +169,9 @@
 
 int axp_gpio_direction_input(unsigned int pin)
 {
+	if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT)
+		return 0;
+
 	u8 reg = axp209_get_gpio_ctrl_reg(pin);
 	/* GPIO3 is "special" */
 	u8 val = (pin == 3) ? AXP209_GPIO3_INPUT : AXP209_GPIO_INPUT;
@@ -232,7 +199,10 @@
 	u8 val, mask;
 	int rc;
 
-	if (pin == 3) {
+	if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) {
+		rc = axp209_read(AXP209_POWER_STATUS, &val);
+		mask = AXP209_POWER_STATUS_VBUS_USABLE;
+	} else if (pin == 3) {
 		rc = axp209_read(AXP209_GPIO3_CTRL, &val);
 		mask = 1;
 	} else {
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index c2c3988..dc3a7f1 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -14,6 +14,7 @@
 #include <errno.h>
 #include <asm/arch/p2wi.h>
 #include <asm/arch/rsb.h>
+#include <asm/arch/gpio.h>
 #include <axp221.h>
 
 /*
@@ -385,54 +386,66 @@
 	return 0;
 }
 
-int axp_get_vbus(void)
+int axp_gpio_direction_input(unsigned int pin)
 {
-	int ret;
-	u8 val;
-
-	ret = axp221_init();
-	if (ret)
-		return ret;
-
-	ret = pmic_bus_read(AXP221_POWER_STATUS, &val);
-	if (ret)
-		return ret;
-
-	return (val & AXP221_POWER_STATUS_VBUS_USABLE) ? 1 : 0;
+	switch (pin) {
+	case SUNXI_GPIO_AXP0_VBUS_DETECT:
+		return 0;
+	default:
+		return -EINVAL;
+	}
 }
 
-static int axp_drivebus_setup(void)
+int axp_gpio_direction_output(unsigned int pin, unsigned int val)
 {
 	int ret;
 
-	ret = axp221_init();
-	if (ret)
-		return ret;
+	switch (pin) {
+	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+		ret = axp221_clrbits(AXP221_MISC_CTRL,
+				     AXP221_MISC_CTRL_N_VBUSEN_FUNC);
+		if (ret)
+			return ret;
 
-	/* Set N_VBUSEN pin to output / DRIVEBUS function */
-	return axp221_clrbits(AXP221_MISC_CTRL, AXP221_MISC_CTRL_N_VBUSEN_FUNC);
+		return axp_gpio_set_value(pin, val);
+	default:
+		return -EINVAL;
+	}
 }
 
-int axp_drivebus_enable(void)
+int axp_gpio_get_value(unsigned int pin)
 {
 	int ret;
+	u8 val;
 
-	ret = axp_drivebus_setup();
-	if (ret)
-		return ret;
+	switch (pin) {
+	case SUNXI_GPIO_AXP0_VBUS_DETECT:
+		ret = pmic_bus_read(AXP221_POWER_STATUS, &val);
+		if (ret)
+			return ret;
 
-	/* Set DRIVEBUS high */
-	return axp221_setbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS);
+		return !!(val & AXP221_POWER_STATUS_VBUS_AVAIL);
+	default:
+		return -EINVAL;
+	}
 }
 
-int axp_drivebus_disable(void)
+int axp_gpio_set_value(unsigned int pin, unsigned int val)
 {
 	int ret;
 
-	ret = axp_drivebus_setup();
-	if (ret)
-		return ret;
+	switch (pin) {
+	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+		if (val)
+			ret = axp221_setbits(AXP221_VBUS_IPSOUT,
+					     AXP221_VBUS_IPSOUT_DRIVEBUS);
+		else
+			ret = axp221_clrbits(AXP221_VBUS_IPSOUT,
+					     AXP221_VBUS_IPSOUT_DRIVEBUS);
 
-	/* Set DRIVEBUS low */
-	return axp221_clrbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index 90aaec6..c9a6a16 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -235,52 +235,19 @@
 
 	pr_debug("%s():\n", __func__);
 
-	if (is_host_enabled(musb)) {
-		int vbus_det = sunxi_name_to_gpio(CONFIG_USB0_VBUS_DET);
-
-#ifdef AXP_VBUS_DETECT
-		if (!strcmp(CONFIG_USB0_VBUS_DET, "axp_vbus_detect")) {
-			err = axp_get_vbus();
-			if (err < 0)
-				return err;
-		} else {
-#endif
-			if (vbus_det == -1) {
-				eprintf("Error invalid Vusb-det pin\n");
-				return -EINVAL;
-			}
-
-			err = gpio_request(vbus_det, "vbus0_det");
-			if (err)
-				return err;
-
-			err = gpio_direction_input(vbus_det);
-			if (err) {
-				gpio_free(vbus_det);
-				return err;
-			}
-
-			err = gpio_get_value(vbus_det);
-			if (err < 0) {
-				gpio_free(vbus_det);
-				return -EIO;
-			}
-
-			gpio_free(vbus_det);
-#ifdef AXP_VBUS_DETECT
-		}
-#endif
+	err = sunxi_usbc_request_resources(0);
+	if (err)
+		return err;
 
+	if (is_host_enabled(musb)) {
+		err = sunxi_usbc_vbus_detect(0);
 		if (err) {
 			eprintf("Error: A charger is plugged into the OTG\n");
+			sunxi_usbc_free_resources(0);
 			return -EIO;
 		}
 	}
 
-	err = sunxi_usbc_request_resources(0);
-	if (err)
-		return err;
-
 	musb->isr = sunxi_musb_interrupt;
 	sunxi_usbc_enable(0);
 
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 4e12150..d2341b0 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -665,10 +665,10 @@
 
 	for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++)
 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
-		sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LCD0);
+		sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
 #endif
 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
-		sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LVDS0);
+		sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
 #endif
 
 	sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
@@ -779,8 +779,8 @@
 	       &lcdc->tcon1_timing_sync);
 
 	if (use_portd_hvsync) {
-		sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD0_LCD0);
-		sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD0_LCD0);
+		sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
+		sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0);
 
 		val = 0;
 		if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
diff --git a/include/axp152.h b/include/axp152.h
index 3e5ccbd..9d205f8 100644
--- a/include/axp152.h
+++ b/include/axp152.h
@@ -3,6 +3,18 @@
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
+
+enum axp152_reg {
+	AXP152_CHIP_VERSION = 0x3,
+	AXP152_DCDC2_VOLTAGE = 0x23,
+	AXP152_DCDC3_VOLTAGE = 0x27,
+	AXP152_DCDC4_VOLTAGE = 0x2B,
+	AXP152_LDO2_VOLTAGE = 0x2A,
+	AXP152_SHUTDOWN = 0x32,
+};
+
+#define AXP152_POWEROFF			(1 << 7)
+
 int axp152_set_dcdc2(int mvolt);
 int axp152_set_dcdc3(int mvolt);
 int axp152_set_dcdc4(int mvolt);
diff --git a/include/axp209.h b/include/axp209.h
index 0436249..d36da41 100644
--- a/include/axp209.h
+++ b/include/axp209.h
@@ -4,6 +4,44 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+enum axp209_reg {
+	AXP209_POWER_STATUS = 0x00,
+	AXP209_CHIP_VERSION = 0x03,
+	AXP209_DCDC2_VOLTAGE = 0x23,
+	AXP209_DCDC3_VOLTAGE = 0x27,
+	AXP209_LDO24_VOLTAGE = 0x28,
+	AXP209_LDO3_VOLTAGE = 0x29,
+	AXP209_IRQ_ENABLE1 = 0x40,
+	AXP209_IRQ_ENABLE2 = 0x41,
+	AXP209_IRQ_ENABLE3 = 0x42,
+	AXP209_IRQ_ENABLE4 = 0x43,
+	AXP209_IRQ_ENABLE5 = 0x44,
+	AXP209_IRQ_STATUS5 = 0x4c,
+	AXP209_SHUTDOWN = 0x32,
+	AXP209_GPIO0_CTRL = 0x90,
+	AXP209_GPIO1_CTRL = 0x92,
+	AXP209_GPIO2_CTRL = 0x93,
+	AXP209_GPIO_STATE = 0x94,
+	AXP209_GPIO3_CTRL = 0x95,
+};
+
+#define AXP209_POWER_STATUS_ON_BY_DC	(1 << 0)
+#define AXP209_POWER_STATUS_VBUS_USABLE	(1 << 4)
+
+#define AXP209_IRQ5_PEK_UP		(1 << 6)
+#define AXP209_IRQ5_PEK_DOWN		(1 << 5)
+
+#define AXP209_POWEROFF			(1 << 7)
+
+#define AXP209_GPIO_OUTPUT_LOW		0x00 /* Drive pin low */
+#define AXP209_GPIO_OUTPUT_HIGH		0x01 /* Drive pin high */
+#define AXP209_GPIO_INPUT		0x02 /* Float pin */
+
+/* GPIO3 is different from the others */
+#define AXP209_GPIO3_OUTPUT_LOW		0x00 /* Drive pin low, Output mode */
+#define AXP209_GPIO3_OUTPUT_HIGH	0x02 /* Float pin, Output mode */
+#define AXP209_GPIO3_INPUT		0x06 /* Float pin, Input mode */
+
 #define AXP_GPIO
 
 extern int axp209_set_dcdc2(int mvolt);
diff --git a/include/axp221.h b/include/axp221.h
index be6058e..0aac04d 100644
--- a/include/axp221.h
+++ b/include/axp221.h
@@ -62,11 +62,7 @@
 /* Page 1 addresses */
 #define AXP221_SID		0x20
 
-/* We support vbus detection */
-#define AXP_VBUS_DETECT
-
-/* We support drivebus control */
-#define AXP_DRIVEBUS
+#define AXP_GPIO
 
 int axp221_set_dcdc1(unsigned int mvolt);
 int axp221_set_dcdc2(unsigned int mvolt);
@@ -83,6 +79,8 @@
 int axp221_set_eldo(int eldo_num, unsigned int mvolt);
 int axp221_init(void);
 int axp221_get_sid(unsigned int *sid);
-int axp_get_vbus(void);
-int axp_drivebus_enable(void);
-int axp_drivebus_disable(void);
+
+int axp_gpio_direction_input(unsigned int pin);
+int axp_gpio_direction_output(unsigned int pin, unsigned int val);
+int axp_gpio_get_value(unsigned int pin);
+int axp_gpio_set_value(unsigned int pin, unsigned int val);
diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h
index 1683a15..4dd7b11 100644
--- a/include/configs/db-mv784mp-gp.h
+++ b/include/configs/db-mv784mp-gp.h
@@ -37,7 +37,7 @@
 /* I2C */
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MVTWSI
-#define CONFIG_I2C_MVTWSI_BASE		MVEBU_TWSI_BASE
+#define CONFIG_I2C_MVTWSI_BASE0		MVEBU_TWSI_BASE
 #define CONFIG_SYS_I2C_SLAVE		0x0
 #define CONFIG_SYS_I2C_SPEED		100000
 
diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h
index 5ce01fb..bd08740 100644
--- a/include/configs/edminiv2.h
+++ b/include/configs/edminiv2.h
@@ -208,7 +208,7 @@
 #ifdef CONFIG_CMD_I2C
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MVTWSI
-#define CONFIG_I2C_MVTWSI_BASE		ORION5X_TWSI_BASE
+#define CONFIG_I2C_MVTWSI_BASE0		ORION5X_TWSI_BASE
 #define CONFIG_SYS_I2C_SLAVE		0x0
 #define CONFIG_SYS_I2C_SPEED		100000
 #endif
diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h
index 5999d60..e909623 100644
--- a/include/configs/maxbcm.h
+++ b/include/configs/maxbcm.h
@@ -35,7 +35,7 @@
 /* I2C */
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MVTWSI
-#define CONFIG_I2C_MVTWSI_BASE		MVEBU_TWSI_BASE
+#define CONFIG_I2C_MVTWSI_BASE0		MVEBU_TWSI_BASE
 #define CONFIG_SYS_I2C_SLAVE		0x0
 #define CONFIG_SYS_I2C_SPEED		100000
 
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 1f7a1cb..438272c 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -196,7 +196,11 @@
 #endif
 
 #define CONFIG_SYS_I2C
+#if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \
+    defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \
+    defined CONFIG_I2C4_ENABLE
 #define CONFIG_SYS_I2C_MVTWSI
+#endif
 #define CONFIG_SYS_I2C_SPEED		400000
 #define CONFIG_SYS_I2C_SLAVE		0x7f