diff --git a/configs/sama5d3x-ek/src/sam_usb.c b/configs/sama5d3x-ek/src/sam_usb.c index a4c4c16cc59..d6b41c2b0c6 100644 --- a/configs/sama5d3x-ek/src/sam_usb.c +++ b/configs/sama5d3x-ek/src/sam_usb.c @@ -83,6 +83,12 @@ static struct usbhost_connection_s *g_ohciconn; static struct usbhost_connection_s *g_ehciconn; #endif +/* Overcurrent interrupt handler */ + +#if defined(HAVE_USBHOST) && defined(CONFIG_SAMA5_PIOD_IRQ) +static xcpt_t g_ochandler; +#endif + /************************************************************************************ * Private Functions ************************************************************************************/ @@ -229,7 +235,7 @@ static int ehci_waiter(int argc, char *argv[]) void weak_function sam_usbinitialize(void) { -#if 0 +#ifdef HAVE_USBDEV /* Configure Port A to support the USB device function */ sam_configpio(PIO_USBA_VBUS_SENSE); /* VBUS sense */ @@ -237,21 +243,20 @@ void weak_function sam_usbinitialize(void) /* TODO: Configure an interrupt on VBUS sense */ #endif -#ifdef CONFIG_SAMA5_OHCI - /* Configure Port C to support the USB OHCI function */ - - sam_configpio(PIO_USBC_VBUS_ENABLE); /* VBUS enable, initially OFF */ +#ifdef HAVE_USBHOST +#ifndef HAVE_USBDEV + /* Configure Port A to support the USB OHCI/EHCI function only if USB + * device is not also supported. + */ + sam_configpio(PIO_USBA_VBUS_ENABLE); /* VBUS enable, initially OFF */ #endif -#ifdef CONFIG_SAMA5_EHCI - /* Configure Port B to support the USB OHCI function */ + /* Configure Ports B and C to support the USB OHCI/EHCI function */ sam_configpio(PIO_USBB_VBUS_ENABLE); /* VBUS enable, initially OFF */ + sam_configpio(PIO_USBC_VBUS_ENABLE); /* VBUS enable, initially OFF */ -#endif - -#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) /* Configure Port B/C VBUS overrcurrent detection */ sam_configpio(PIO_USBBC_VBUS_OVERCURRENT); /* VBUS overcurrent */ @@ -271,7 +276,7 @@ void weak_function sam_usbinitialize(void) #if HAVE_USBHOST int sam_usbhost_initialize(void) { - int pid; + pid_t pid; int ret; /* First, register all of the class drivers needed to support the drivers @@ -338,9 +343,8 @@ int sam_usbhost_initialize(void) * each platform that implements the OHCI or EHCI host interface * * Input Parameters: - * iface - Selects USB host interface: - * 0 = EHCI (Port B) - * 1 = OHCI (Port C) + * rhport - Selects root hub port to be powered host interface. See SAM_RHPORT_* + * definitions above. * enable - true: enable VBUS power; false: disable VBUS power * * Returned Value: @@ -349,34 +353,37 @@ int sam_usbhost_initialize(void) ***********************************************************************************/ #if HAVE_USBHOST -void sam_usbhost_vbusdrive(int iface, bool enable) +void sam_usbhost_vbusdrive(int rhport, bool enable) { - pio_pinset_t pinset; + pio_pinset_t pinset = 0; - /* Pick the PIO associated with the OHCI or EHCI interface */ + uvdbg("RHPort%d: enable=%d\n", rhport+1, enable); -#ifdef CONFIG_SAMA5_OHCI - if (iface == SAM_OHCI_IFACE) + /* Pick the PIO configuration associated with the selected root hub port */ + + switch (rhport) { - uvdbg("OHCI: iface %d enable %d\n", iface, enable); - pinset = PIO_USBC_VBUS_ENABLE; - } - else + case SAM_RHPORT1: +#ifdef HAVE_USBDEV + udbg("ERROR: RHPort1 is not available in this configuration\n"); + return; +#else + pinset = PIO_USBA_VBUS_ENABLE; + break; #endif -#ifdef CONFIG_SAMA5_EHCI - if (iface == SAM_EHCI_IFACE) - { - uvdbg("EHCI: iface %d enable %d\n", iface, enable); + case SAM_RHPORT2: pinset = PIO_USBB_VBUS_ENABLE; - } - else -#endif + break; - { - udbg("ERROR: Unsupported iface %d\n", iface); - return; - } + case SAM_RHPORT3: + pinset = PIO_USBC_VBUS_ENABLE; + break; + + default: + udbg("ERROR: RHPort%d is not supported\n", rhport+1); + return; + } /* Then enable or disable VBUS power */ @@ -384,13 +391,13 @@ void sam_usbhost_vbusdrive(int iface, bool enable) { /* Enable the Power Switch by driving the enable pin low */ - sam_piowrite(pinset, false); + sam_piowrite(pinset, false); } else { /* Disable the Power Switch by driving the enable pin high */ - sam_piowrite(pinset, false); + sam_piowrite(pinset, true); } } #endif @@ -402,6 +409,9 @@ void sam_usbhost_vbusdrive(int iface, bool enable) * Setup to receive an interrupt-level callback if an overcurrent condition is * detected. * + * REVISIT: Since this is a common signal, we will need to come up with some way + * to inform both EHCI and OHCI drivers when this error occurs. + * * Input paramter: * handler - New overcurrent interrupt handler * @@ -413,12 +423,33 @@ void sam_usbhost_vbusdrive(int iface, bool enable) #if HAVE_USBHOST xcpt_t sam_setup_overcurrent(xcpt_t handler) { - /* Since this is a common signal, we will need to come up with some way to inform - * both EHCI and OHCI drivers when this error occurs. +#if defined(CONFIG_SAMA5_PIOD_IRQ) + xcpt_t oldhandler; + irqstate_t flags; + + /* Disable interrupts until we are done. This guarantees that the + * following operations are atomic. */ -# warning Missing logic + flags = irqsave(); + + /* Get the old button interrupt handler and save the new one */ + + oldhandler = *g_ochandler; + *g_ochandler = handler; + + /* Configure the interrupt */ + + sam_pioirq(IRQ_USBBC_VBUS_OVERCURRENT); + (void)irq_attach(IRQ_USBBC_VBUS_OVERCURRENT, handler); + sam_pioirqenable(IRQ_USBBC_VBUS_OVERCURRENT); + + /* Return the old button handler (so that it can be restored) */ + + return oldhandler; +#else return NULL; +#endif } #endif diff --git a/configs/sama5d3x-ek/src/sama5d3x-ek.h b/configs/sama5d3x-ek/src/sama5d3x-ek.h index 9f91aee92b5..dd77e0f663f 100644 --- a/configs/sama5d3x-ek/src/sama5d3x-ek.h +++ b/configs/sama5d3x-ek/src/sama5d3x-ek.h @@ -58,6 +58,7 @@ #define HAVE_HSMCI_MTD 1 #define HAVE_AT25_MTD 1 #define HAVE_USBHOST 1 +#define HAVE_USBDEV 1 /* HSMCI */ /* Can't support MMC/SD if the card interface(s) are not enable */ @@ -120,12 +121,13 @@ #endif #if !defined(CONFIG_SAMA5_UDPHS) +# undef HAVE_USBDEV #endif /* CONFIG_USBDEV and CONFIG_USBHOST must also be defined */ -#if defined(CONFIG_USBDEV) -#else +#if !defined(CONFIG_USBDEV) +# undef HAVE_USBDEV #endif #if defined(CONFIG_USBHOST) @@ -137,11 +139,6 @@ # undef CONFIG_SAMA5_EHCI #endif -#if defined(CONFIG_SAMA5_OHCI) && defined(CONFIG_SAMA5_EHCI) -# warning Both CONFIG_SAMA5_OHCI and CONFIG_SAMA5_EHCI are defined -# undef CONFIG_SAMA5_EHCI -#endif - #if !defined(CONFIG_SAMA5_OHCI) && !defined(CONFIG_SAMA5_EHCI) # undef HAVE_USBHOST #endif