summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2015-03-22 18:07:12 +0100
committerHans de Goede <hdegoede@redhat.com>2015-04-15 16:17:17 +0200
commitebd468b2d26660ff7811e37cc64fa2369d4b5fff (patch)
treecc53c766c49aa654db0197fd8698f4672bd5b6cb /arch/arm/cpu/armv7
parent1a59ecff804ffd96ab11001f722b8311296e6e5b (diff)
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 <contact@paulk.fr> Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/sunxi/usbc.c43
1 files changed, 39 insertions, 4 deletions
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);
+}