]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
sunxi: common VBUS detection logic in usbc
authorPaul Kocialkowski <contact@paulk.fr>
Sun, 22 Mar 2015 17:07:12 +0000 (18:07 +0100)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 8 Sep 2015 19:47:13 +0000 (21:47 +0200)
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 <contact@paulk.fr>
Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
arch/arm/cpu/armv7/sunxi/usbc.c
arch/arm/include/asm/arch-sunxi/usbc.h
board/sunxi/Kconfig
drivers/usb/musb-new/sunxi.c

index f4f7217a6d448e7e32a8dac25d441ca134e634ce..1c777aac49aba863296323fd91bb6c8b1794ec20 100644 (file)
@@ -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);
+}
index 133073321bd3f76a729c40726b6811f256c76486..ab0f272e4151aa8f033cc88ef45327c2fca592b8 100644 (file)
@@ -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);
index 2fcab602db07c2037d5865260393e84eb509ffe1..98228e87ff739e433cf1f3714307d77b44117629 100644 (file)
@@ -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
index 80499442f10b2f33622cd2dddbdf6997fb980b06..c9a6a16b89dd1c15ce23c05eb83560ddbcbb9aa8 100644 (file)
@@ -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);