From 991963bce9e3a8f51499785c736ec54e527f3a2b Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 22 Mar 2015 18:07:08 +0100 Subject: sunxi: gpio: Indentation fix Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/gpio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index f2c247d79f..a66e45caff 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -84,7 +84,7 @@ struct sunxi_gpio_reg { #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) @@ -194,7 +194,7 @@ enum sunxi_gpio_number { #define SUN8I_GPL3_R_UART_RX 2 #define SUN9I_GPN0_R_RSB_SCK 3 -#define SUN9I_GPN1_R_RSB_SDA 3 +#define SUN9I_GPN1_R_RSB_SDA 3 /* GPIO pin pull-up/down config */ #define SUNXI_GPIO_PULL_DISABLE 0 -- cgit v1.2.3 From f7c7ab636ab2c81d9fb1def7256c94b998c7298f Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 22 Mar 2015 18:07:09 +0100 Subject: power: axp221: Virtual VBUS detect and enable GPIOs to replace separate logic This converts the VBUS detection and enable logic to GPIO instead of separate axp functions and checks that have to be used aside usual GPIO functions. Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/gpio.h | 4 ++ drivers/gpio/sunxi_gpio.c | 9 ++++ drivers/power/axp221.c | 75 ++++++++++++++++++++-------------- include/axp221.h | 14 +++---- 4 files changed, 63 insertions(+), 39 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index a66e45caff..3a4b8c3165 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -201,6 +201,10 @@ enum sunxi_gpio_number { #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); diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 62960929ad..670af0c383 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -21,6 +21,9 @@ #ifdef CONFIG_AXP209_POWER #include #endif +#ifdef CONFIG_AXP221_POWER +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -125,6 +128,12 @@ int sunxi_name_to_gpio(const char *name) #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/power/axp221.c b/drivers/power/axp221.c index c2c3988804..f758a75e9a 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -14,6 +14,7 @@ #include #include #include +#include #include /* @@ -385,54 +386,66 @@ int axp221_get_sid(unsigned int *sid) 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_USABLE); + 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/include/axp221.h b/include/axp221.h index be6058e439..0aac04dfeb 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_aldo3(unsigned int mvolt); 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); -- cgit v1.2.3 From ebd468b2d26660ff7811e37cc64fa2369d4b5fff Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 22 Mar 2015 18:07:12 +0100 Subject: sunxi: common VBUS detection logic in usbc VBUS detection could be needed not only by the musb code (to prevent host mode), but also by e.g. gadget drivers to start only when a cable is connected. In addition, this allows more flexibility in vbus detection, as it could easily be extended to other USBC indexes. Eventually, this would help making musb support independent from a hardcoded USB controller index (0). Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/usbc.c | 43 ++++++++++++++++++++++++++++++---- arch/arm/include/asm/arch-sunxi/usbc.h | 1 + board/sunxi/Kconfig | 1 - drivers/usb/musb-new/sunxi.c | 35 +++++---------------------- 4 files changed, 46 insertions(+), 34 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c index f4f7217a6d..1c777aac49 100644 --- a/arch/arm/cpu/armv7/sunxi/usbc.c +++ b/arch/arm/cpu/armv7/sunxi/usbc.c @@ -41,6 +41,7 @@ static struct sunxi_usbc_hcd { int usb_rst_mask; int ahb_clk_mask; int gpio_vbus; + int gpio_vbus_det; int irq; int id; } sunxi_usbc_hcd[] = { @@ -104,6 +105,14 @@ static int get_vbus_gpio(int index) 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) { @@ -183,22 +192,31 @@ void sunxi_usbc_enable_squelch_detect(int index, int enable) 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"); + ret |= gpio_request(sunxi_usbc->gpio_vbus, "usbc_vbus"); - return 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"); + + 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); + + if (sunxi_usbc->gpio_vbus_det != -1) + ret |= gpio_free(sunxi_usbc->gpio_vbus_det); - return 0; + return ret; } void sunxi_usbc_enable(int index) @@ -260,3 +278,20 @@ void sunxi_usbc_vbus_disable(int index) if (sunxi_usbc->gpio_vbus != -1) gpio_direction_output(sunxi_usbc->gpio_vbus, 0); } + +int sunxi_usbc_vbus_detect(int index) +{ + struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index]; + int err; + + if (sunxi_usbc->gpio_vbus_det == -1) { + eprintf("Error: invalid vbus detection pin\n"); + return -1; + } + + err = gpio_direction_input(sunxi_usbc->gpio_vbus_det); + if (err) + return err; + + return gpio_get_value(sunxi_usbc->gpio_vbus_det); +} diff --git a/arch/arm/include/asm/arch-sunxi/usbc.h b/arch/arm/include/asm/arch-sunxi/usbc.h index 133073321b..ab0f272e41 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_enable(int index); 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/board/sunxi/Kconfig b/board/sunxi/Kconfig index 2fcab602db..98228e87ff 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -229,7 +229,6 @@ config USB0_VBUS_PIN 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 diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 80499442f1..c9a6a16b89 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -235,42 +235,19 @@ static int sunxi_musb_init(struct musb *musb) pr_debug("%s():\n", __func__); - if (is_host_enabled(musb)) { - int vbus_det = sunxi_name_to_gpio(CONFIG_USB0_VBUS_DET); - - 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); + 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); -- cgit v1.2.3 From 487b3277d4f70bcb2e4a1930beb6438565f25910 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 22 Mar 2015 18:12:22 +0100 Subject: sunxi: GPIO pin mux hardware-feature-specific function index defines Each hardware feature exposed through the GPIO pin mux is usually using the same function index (for a given port), so there is no need to define one value per pin: one value per hardware feature per port is sufficient, avoids duplication and makes everything easier to understand. Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/board.c | 29 +++++++++------- arch/arm/cpu/armv7/sunxi/rsb.c | 8 ++--- arch/arm/include/asm/arch-sunxi/gpio.h | 60 +++++++++++----------------------- board/sunxi/board.c | 12 +++---- board/sunxi/gmac.c | 22 ++++++------- drivers/net/sunxi_emac.c | 2 +- drivers/video/sunxi_display.c | 8 ++--- 7 files changed, 62 insertions(+), 79 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index c02c015096..c1b4cf5c2f 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -46,28 +46,33 @@ static int gpio_init(void) 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 b00befb301..f115a9cac4 100644 --- a/arch/arm/cpu/armv7/sunxi/rsb.c +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -21,15 +21,15 @@ static int rsb_set_device_mode(void); 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/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 3a4b8c3165..a6b15d6102 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -142,59 +142,37 @@ enum sunxi_gpio_number { #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 SUNXI_GPB0_TWI0 2 +#define SUNXI_GPB_TWI0 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 SUN5I_GPB19_UART0_TX 2 -#define SUN5I_GPB20_UART0_RX 2 +#define SUNXI_GPD_LCD0 2 +#define SUNXI_GPD_LVDS0 3 -#define SUNXI_GPC6_SDC2 3 +#define SUNXI_GPF_SDC0 2 +#define SUNXI_GPF_UART0 4 +#define SUN8I_GPF_UART0 3 -#define SUNXI_GPD0_LCD0 2 -#define SUNXI_GPD0_LVDS0 3 +#define SUN5I_GPG_SDC1 2 +#define SUN5I_GPG_UART1 4 -#define SUNXI_GPF0_SDC0 2 +#define SUN6I_GPH_UART0 2 -#define SUNXI_GPF2_SDC0 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 SUN4I_GPI_SDC3 2 #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 diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 3b419b398b..af8cf1104d 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -76,7 +76,7 @@ static void mmc_pinmux_setup(int sdc) case 0: /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-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); } @@ -85,7 +85,7 @@ static void mmc_pinmux_setup(int sdc) case 1: /* CMD-PG3, CLK-PG4, D0~D3-PG5-8 */ 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); } @@ -94,7 +94,7 @@ static void mmc_pinmux_setup(int sdc) case 2: /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-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); } @@ -103,7 +103,7 @@ static void mmc_pinmux_setup(int sdc) case 3: /* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */ for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3); + sunxi_gpio_set_cfgpin(pin, SUN4I_GPI_SDC3); sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } @@ -155,8 +155,8 @@ int board_mmc_init(bd_t *bis) 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); + sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB_TWI0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB_TWI0); clock_twi_onoff(0, 1); #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); diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c index 8849132627..63a7360b6d 100644 --- a/board/sunxi/gmac.c +++ b/board/sunxi/gmac.c @@ -39,45 +39,45 @@ int sunxi_gmac_initialize(bd_t *bis) 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/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c index 5a06d68af7..2a9fd56c95 100644 --- a/drivers/net/sunxi_emac.c +++ b/drivers/net/sunxi_emac.c @@ -497,7 +497,7 @@ int sunxi_emac_initialize(void) /* 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/video/sunxi_display.c b/drivers/video/sunxi_display.c index 4e12150027..d2341b0e36 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -665,10 +665,10 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, 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 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, &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) -- cgit v1.2.3 From 8deacca975585c11663db984002dca0c48bcc2d5 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 22 Mar 2015 18:12:23 +0100 Subject: sunxi: Complete mmc pin mux for each supported platform, configured with Kconfig Sunxi platforms have different possible mmc pin mux setups (except for mmc0), which are different across platforms. This lets users configure which is used through the CONFIG_MMC*_PINS Kconfig options. This is especially relevant when a second (in addition to mmc0) port is used and CONFIG_MMC_SUNXI_SLOT_EXTRA is enabled. Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/gpio.h | 13 +++- board/sunxi/Kconfig | 19 +++++ board/sunxi/board.c | 131 +++++++++++++++++++++++++++++++-- drivers/gpio/sunxi_gpio.c | 14 ++++ 4 files changed, 171 insertions(+), 6 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index a6b15d6102..f2270449c1 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -145,26 +145,36 @@ enum sunxi_gpio_number { #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_GPB_TWI0 2 #define SUN4I_GPB_UART0 2 #define SUN5I_GPB_UART0 2 #define SUNXI_GPC_SDC2 3 +#define SUN6I_GPC_SDC3 4 +#define SUN8I_GPD_SDC1 3 #define SUNXI_GPD_LCD0 2 #define SUNXI_GPD_LVDS0 3 +#define SUN5I_GPE_SDC2 3 + #define SUNXI_GPF_SDC0 2 #define SUNXI_GPF_UART0 4 #define SUN8I_GPF_UART0 3 +#define SUN4I_GPG_SDC1 4 #define SUN5I_GPG_SDC1 2 +#define SUN6I_GPG_SDC1 2 +#define SUN8I_GPG_SDC1 2 #define SUN5I_GPG_UART1 4 +#define SUN4I_GPH_SDC1 5 #define SUN6I_GPH_UART0 2 -#define SUN4I_GPI_SDC3 2 +#define SUNXI_GPI_SDC3 2 #define SUN6I_GPL0_R_P2WI_SCK 3 #define SUN6I_GPL1_R_P2WI_SDA 3 @@ -189,6 +199,7 @@ 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/board/sunxi/Kconfig b/board/sunxi/Kconfig index 98228e87ff..ccc2080d8c 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -212,6 +212,25 @@ config MMC3_CD_PIN ---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 diff --git a/board/sunxi/board.c b/board/sunxi/board.c index af8cf1104d..0c9d3b8029 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -71,10 +71,11 @@ int dram_init(void) 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_GPF_SDC0); sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); @@ -83,30 +84,150 @@ static void mmc_pinmux_setup(int sdc) 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_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_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_GPI_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: diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 670af0c383..510123fdf8 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -118,6 +118,20 @@ int gpio_set_value(unsigned gpio, int value) 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; -- cgit v1.2.3 From dd82242b4dd7d251ef9ba43563cf9a0017d6f98e Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Fri, 10 Apr 2015 23:09:51 +0200 Subject: i2c: mvtwsi: Support for up to 4 different controllers Orion5x, Kirkwood and Armada XP platforms come with a single TWSI (I2C) MVTWSI controller. However, other platforms using MVTWSI may come with more: this is the case on Allwinner (sunxi) platforms, where up to 4 controllers can be found on the same chip. Signed-off-by: Paul Kocialkowski Acked-by: Heiko Schocher Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/i2c.h | 2 +- arch/arm/mach-kirkwood/include/mach/config.h | 2 +- drivers/i2c/mvtwsi.c | 128 +++++++++++++++++++++------ include/configs/db-mv784mp-gp.h | 2 +- include/configs/edminiv2.h | 2 +- include/configs/maxbcm.h | 2 +- 6 files changed, 104 insertions(+), 34 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h index dc5406b213..502e3c68ea 100644 --- a/arch/arm/include/asm/arch-sunxi/i2c.h +++ b/arch/arm/include/asm/arch-sunxi/i2c.h @@ -8,7 +8,7 @@ #include -#define CONFIG_I2C_MVTWSI_BASE SUNXI_TWI0_BASE +#define CONFIG_I2C_MVTWSI_BASE0 SUNXI_TWI0_BASE /* 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/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h index e77ac400d8..d049395036 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/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 6f6edd5e51..f20d1b2291 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -14,7 +14,7 @@ #include /* - * 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 @@ struct mvtwsi_registers { #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 @@ static struct mvtwsi_registers *twsi = * 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 @@ static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN; * 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 @@ static int twsi_recv(u8 *byte) /* 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 @@ static int twsi_recv(u8 *byte) * 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 unsigned int twsi_calc_freq(const int n, const int m) */ 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 void twsi_reset(struct i2c_adapter *adap) 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 unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap, 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 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) 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 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) * 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 @@ static int i2c_begin(int expected_start_status, u8 addr) 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 @@ static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip) 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 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, 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 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, 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 @@ static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, 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/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h index 1683a1582f..4dd7b11fb4 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 5ce01fb2ae..bd0874065c 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 5999d60146..e9096234af 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 -- cgit v1.2.3 From 6c739c5d8a3466f8ef2f8543636484957bcca6ee Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Fri, 10 Apr 2015 23:09:52 +0200 Subject: sunxi: Complete i2c support for each supported platform Sunxi platforms come with at least 3 TWI (I2C) controllers and some platforms even have up to 5. This adds support for every controller on each supported platform, which is especially useful when using expansion ports on single-board- computers. Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 7 +++ arch/arm/include/asm/arch-sunxi/gpio.h | 15 +++++- arch/arm/include/asm/arch-sunxi/i2c.h | 15 ++++++ board/sunxi/Kconfig | 38 ++++++++++++++ board/sunxi/board.c | 77 ++++++++++++++++++++++++++++- include/configs/sunxi-common.h | 4 ++ 6 files changed, 153 insertions(+), 3 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index dae60696f9..f403742d3a 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 f2270449c1..ae7cbb7e78 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -148,7 +148,11 @@ enum sunxi_gpio_number { #define SUN6I_GPA_SDC2 5 #define SUN6I_GPA_SDC3 4 -#define SUNXI_GPB_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 @@ -160,6 +164,7 @@ enum sunxi_gpio_number { #define SUNXI_GPD_LVDS0 3 #define SUN5I_GPE_SDC2 3 +#define SUN8I_GPE_TWI2 3 #define SUNXI_GPF_SDC0 2 #define SUNXI_GPF_UART0 4 @@ -169,12 +174,20 @@ enum sunxi_gpio_number { #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 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 #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 diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h index 502e3c68ea..561cd2be16 100644 --- a/arch/arm/include/asm/arch-sunxi/i2c.h +++ b/arch/arm/include/asm/arch-sunxi/i2c.h @@ -8,7 +8,22 @@ #include +#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/board/sunxi/Kconfig b/board/sunxi/Kconfig index ccc2080d8c..88e335836d 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -269,6 +269,44 @@ config USB2_VBUS_PIN ---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/board.c b/board/sunxi/board.c index 7633d65e6c..dda50b55a5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -276,9 +276,82 @@ int board_mmc_init(bd_t *bis) void i2c_init_board(void) { - sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB_TWI0); - sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB_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); diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 1f7a1cb1f4..438272cbda 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 -- cgit v1.2.3