mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 19:36:35 +08:00
SAMA5: Add support for sharing ports when both OHCI and EHCI are enabled
This commit is contained in:
@@ -370,7 +370,7 @@ config SAMA5_OHCI_REGDEBUG
|
|||||||
default n
|
default n
|
||||||
depends on DEBUG
|
depends on DEBUG
|
||||||
|
|
||||||
endif # OHCI
|
endif # SAMA5_OHCI
|
||||||
|
|
||||||
config SAMA5_EHCI
|
config SAMA5_EHCI
|
||||||
bool "High speed EHCI support"
|
bool "High speed EHCI support"
|
||||||
@@ -408,7 +408,75 @@ config SAMA5_EHCI_REGDEBUG
|
|||||||
default n
|
default n
|
||||||
depends on DEBUG
|
depends on DEBUG
|
||||||
|
|
||||||
endif # EHCI
|
endif # SAMA5_EHCI
|
||||||
|
|
||||||
|
if SAMA5_OHCI && SAMA5_EHCI
|
||||||
|
|
||||||
|
config SAMA5_OHCI_RHPORT1
|
||||||
|
bool "Use Port A for OHCI"
|
||||||
|
default n
|
||||||
|
depends on !SAMA5_UDPHS
|
||||||
|
|
||||||
|
config SAMA5_OHCI_RHPORT2
|
||||||
|
bool "Use Port B for OHCI"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config SAMA5_OHCI_RHPORT3
|
||||||
|
bool "Use Port C for OHCI"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SAMA5_EHCI_RHPORT1
|
||||||
|
bool
|
||||||
|
default y if !SAMA5_OHCI_RHPORT1
|
||||||
|
default n if SAMA5_OHCI_RHPORT1
|
||||||
|
depends on !SAMA5_UDPHS
|
||||||
|
|
||||||
|
config SAMA5_EHCI_RHPORT2
|
||||||
|
bool
|
||||||
|
default y if !SAMA5_OHCI_RHPORT2
|
||||||
|
default n if SAMA5_OHCI_RHPORT2
|
||||||
|
|
||||||
|
config SAMA5_EHCI_RHPORT3
|
||||||
|
bool
|
||||||
|
default y if !SAMA5_OHCI_RHPORT3
|
||||||
|
default n if SAMA5_OHCI_RHPORT3
|
||||||
|
|
||||||
|
endif # SAMA5_OHCI && SAMA5_EHCI
|
||||||
|
|
||||||
|
if SAMA5_OHCI && !SAMA5_EHCI
|
||||||
|
|
||||||
|
config SAMA5_OHCI_RHPORT1
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
depends on !SAMA5_UDPHS
|
||||||
|
|
||||||
|
config SAMA5_OHCI_RHPORT2
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SAMA5_OHCI_RHPORT3
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
endif # SAMA5_OHCI && !SAMA5_EHCI
|
||||||
|
|
||||||
|
if !SAMA5_OHCI && SAMA5_EHCI
|
||||||
|
|
||||||
|
config SAMA5_EHCI_RHPORT1
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
depends on !SAMA5_UDPHS
|
||||||
|
|
||||||
|
config SAMA5_EHCI_RHPORT2
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SAMA5_EHCI_RHPORT3
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
endif # !SAMA5_OHCI && SAMA5_EHCI
|
||||||
|
|
||||||
endmenu # USB High Speed Host driver option
|
endmenu # USB High Speed Host driver option
|
||||||
endif # SAMA5_UHPHS
|
endif # SAMA5_UHPHS
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
#include "sam_periphclks.h"
|
#include "sam_periphclks.h"
|
||||||
#include "sam_memories.h"
|
#include "sam_memories.h"
|
||||||
#include "sam_usbhost.h"
|
#include "sam_usbhost.h"
|
||||||
|
#include "chip/sam_sfr.h"
|
||||||
#include "chip/sam_ehci.h"
|
#include "chip/sam_ehci.h"
|
||||||
|
|
||||||
#ifdef CONFIG_SAMA5_EHCI
|
#ifdef CONFIG_SAMA5_EHCI
|
||||||
@@ -110,6 +111,18 @@
|
|||||||
#undef CONFIG_USBHOST_ISOC_DISABLE
|
#undef CONFIG_USBHOST_ISOC_DISABLE
|
||||||
#define CONFIG_USBHOST_ISOC_DISABLE 1
|
#define CONFIG_USBHOST_ISOC_DISABLE 1
|
||||||
|
|
||||||
|
/* If UDPHS is enabled, then don't use port A */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAMA5_UDPHS
|
||||||
|
# undef CONFIG_SAMA5_EHCI_RHPORT1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For now, suppress use of PORTA in any event. I use that for SAM-BA and
|
||||||
|
* would prefer that the board not try to drive VBUS on that port!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef CONFIG_SAMA5_EHCI_RHPORT1
|
||||||
|
|
||||||
/* Driver-private Definitions **************************************************/
|
/* Driver-private Definitions **************************************************/
|
||||||
|
|
||||||
/* This is the set of interrupts handled by this driver */
|
/* This is the set of interrupts handled by this driver */
|
||||||
@@ -874,7 +887,7 @@ static int sam_qh_foreach(struct sam_qh_s *qh, uint32_t **bp, foreach_qh_t handl
|
|||||||
* the end of the asynchronous queue?
|
* the end of the asynchronous queue?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if (sam_virtramaddr(physaddr & QH_HLP_MASK) == &g_asynchead)
|
else if (sam_virtramaddr(physaddr & QH_HLP_MASK) == (uintptr_t)&g_asynchead)
|
||||||
{
|
{
|
||||||
/* That will also terminate the loop */
|
/* That will also terminate the loop */
|
||||||
|
|
||||||
@@ -1973,16 +1986,16 @@ static int sam_qtd_ioccheck(struct sam_qtd_s *qtd, uint32_t **bp, void *arg)
|
|||||||
(uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s));
|
(uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s));
|
||||||
sam_qtd_print(qtd);
|
sam_qtd_print(qtd);
|
||||||
|
|
||||||
/* Remove the qTD from the list */
|
/* Remove the qTD from the list
|
||||||
|
*
|
||||||
|
* NOTE that we don't check if the qTD is active nor do we check if there
|
||||||
|
* are any errors reported in the qTD. If the transfer halted due to
|
||||||
|
* an error, then qTDs in the list after the error qTD will still appear
|
||||||
|
* to be active.
|
||||||
|
*/
|
||||||
|
|
||||||
**bp = qtd->hw.nqp;
|
**bp = qtd->hw.nqp;
|
||||||
|
|
||||||
/* NOTE that we don't check if the qTD is active nor do we check if there
|
|
||||||
* are any errors reported in the qTD. If the transfer halted due to
|
|
||||||
* an error, then I am not sure if we can believe this information anyway.
|
|
||||||
* The only sure place to check for errors in in the QH overlay.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Release this QH by returning it to the free list */
|
/* Release this QH by returning it to the free list */
|
||||||
|
|
||||||
sam_qtd_free(qtd);
|
sam_qtd_free(qtd);
|
||||||
@@ -2064,6 +2077,7 @@ static int sam_qh_ioccheck(struct sam_qh_s *qh, uint32_t **bp, void *arg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
**bp = qh->hw.hlp;
|
**bp = qh->hw.hlp;
|
||||||
|
cp15_coherent_dcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t));
|
||||||
|
|
||||||
/* Check for errors, update the data toggle */
|
/* Check for errors, update the data toggle */
|
||||||
|
|
||||||
@@ -3377,9 +3391,30 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
|
|||||||
regval = sam_getreg((volatile uint32_t *)SAM_PMC_SCER);
|
regval = sam_getreg((volatile uint32_t *)SAM_PMC_SCER);
|
||||||
regval |= PMC_UHP;
|
regval |= PMC_UHP;
|
||||||
sam_putreg(regval, (volatile uint32_t *)SAM_PMC_SCER);
|
sam_putreg(regval, (volatile uint32_t *)SAM_PMC_SCER);
|
||||||
|
|
||||||
|
/* "One transceiver is shared with the USB High Speed Device (port A). The
|
||||||
|
* selection between Host Port A and USB Device is controlled by the UDPHS
|
||||||
|
* enable bit (EN_UDPHS) located in the UDPHS_CTRL control register."
|
||||||
|
*
|
||||||
|
* Make all three ports usable for EHCI unless the high speed device is
|
||||||
|
* enabled; then let the device manage port zero. Zero is the reset
|
||||||
|
* value for all ports; one makes the corresponding port available to OHCI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
regval = getreg32(SAM_SFR_OHCIICR);
|
||||||
|
#ifdef CONFIG_SAMA5_EHCI_RHPORT1
|
||||||
|
regval &= ~SFR_OHCIICR_RES1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SAMA5_EHCI_RHPORT2
|
||||||
|
regval &= ~SFR_OHCIICR_RES1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SAMA5_EHCI_RHPORT3
|
||||||
|
regval &= ~SFR_OHCIICR_RES2;
|
||||||
|
#endif
|
||||||
|
putreg32(regval, SAM_SFR_OHCIICR);
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
|
|
||||||
/* Note that no pin pinconfiguration is required. All USB HS pins have
|
/* Note that no pin configuration is required. All USB HS pins have
|
||||||
* dedicated function
|
* dedicated function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -3631,7 +3666,15 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
|
|||||||
* mode.
|
* mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sam_usbhost_vbusdrive(SAM_EHCI_IFACE, true);
|
#ifndef CONFIG_SAMA5_EHCI_RHPORT1
|
||||||
|
sam_usbhost_vbusdrive(SAM_RHPORT1, true);
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_SAMA5_EHCI_RHPORT2
|
||||||
|
sam_usbhost_vbusdrive(SAM_RHPORT2, true);
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_SAMA5_EHCI_RHPORT3
|
||||||
|
sam_usbhost_vbusdrive(SAM_RHPORT3, true);
|
||||||
|
#endif
|
||||||
up_mdelay(50);
|
up_mdelay(50);
|
||||||
|
|
||||||
/* If there is a USB device in the slot at power up, then we will not
|
/* If there is a USB device in the slot at power up, then we will not
|
||||||
|
|||||||
@@ -117,6 +117,18 @@
|
|||||||
|
|
||||||
#define SAM_BUFALLOC (CONFIG_SAMA5_OHCI_TDBUFFERS * CONFIG_SAMA5_OHCI_TDBUFSIZE)
|
#define SAM_BUFALLOC (CONFIG_SAMA5_OHCI_TDBUFFERS * CONFIG_SAMA5_OHCI_TDBUFSIZE)
|
||||||
|
|
||||||
|
/* If UDPHS is enabled, then don't use port A */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAMA5_UDPHS
|
||||||
|
# undef CONFIG_SAMA5_OHCI_RHPORT1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For now, suppress use of PORTA in any event. I use that for SAM-BA and
|
||||||
|
* would prefer that the board not try to drive VBUS on that port!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef CONFIG_SAMA5_OHCI_RHPORT1
|
||||||
|
|
||||||
/* Debug */
|
/* Debug */
|
||||||
|
|
||||||
#ifndef CONFIG_DEBUG
|
#ifndef CONFIG_DEBUG
|
||||||
@@ -3013,20 +3025,30 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller)
|
|||||||
regval = getreg32(SAM_PMC_SCER);
|
regval = getreg32(SAM_PMC_SCER);
|
||||||
regval |= PMC_UHP;
|
regval |= PMC_UHP;
|
||||||
putreg32(regval, SAM_PMC_SCER);
|
putreg32(regval, SAM_PMC_SCER);
|
||||||
irqrestore(flags);
|
|
||||||
|
|
||||||
/* Make all three ports usable. Zero is the reset value and holds the
|
/* "One transceiver is shared with the USB High Speed Device (port A). The
|
||||||
* ports in reset.
|
* selection between Host Port A and USB Device is controlled by the UDPHS
|
||||||
* REVISIT: This will have to change in future. Should be a configuration
|
* enable bit (EN_UDPHS) located in the UDPHS_CTRL control register."
|
||||||
* setting
|
*
|
||||||
|
* Make all three ports usable for OHCI unless the high speed device is
|
||||||
|
* enabled; then let the device manage port zero. Zero is the reset
|
||||||
|
* value for all ports; one makes the corresponding port available to OHCI.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regval = getreg32(SAM_SFR_OHCIICR);
|
regval = getreg32(SAM_SFR_OHCIICR);
|
||||||
regval |= (SFR_OHCIICR_RES0 | SFR_OHCIICR_RES1 | SFR_OHCIICR_RES2);
|
#ifdef CONFIG_SAMA5_OHCI_RHPORT1
|
||||||
|
regval |= SFR_OHCIICR_RES1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SAMA5_OHCI_RHPORT2
|
||||||
|
regval |= SFR_OHCIICR_RES1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SAMA5_OHCI_RHPORT3
|
||||||
|
regval |= SFR_OHCIICR_RES2;
|
||||||
|
#endif
|
||||||
putreg32(regval, SAM_SFR_OHCIICR);
|
putreg32(regval, SAM_SFR_OHCIICR);
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
|
|
||||||
/* Note that no pin pinconfiguration is required. All USB HS pins have
|
/* Note that no pin configuration is required. All USB HS pins have
|
||||||
* dedicated function
|
* dedicated function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -3140,7 +3162,15 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller)
|
|||||||
* mode.
|
* mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sam_usbhost_vbusdrive(SAM_OHCI_IFACE, true);
|
#ifndef CONFIG_SAMA5_OHCI_RHPORT1
|
||||||
|
sam_usbhost_vbusdrive(SAM_RHPORT1, true);
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_SAMA5_OHCI_RHPORT2
|
||||||
|
sam_usbhost_vbusdrive(SAM_RHPORT2, true);
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_SAMA5_OHCI_RHPORT3
|
||||||
|
sam_usbhost_vbusdrive(SAM_RHPORT3, true);
|
||||||
|
#endif
|
||||||
up_mdelay(50);
|
up_mdelay(50);
|
||||||
|
|
||||||
/* If there is a USB device in the slot at power up, then we will not
|
/* If there is a USB device in the slot at power up, then we will not
|
||||||
|
|||||||
@@ -54,6 +54,14 @@
|
|||||||
#define SAM_EHCI_IFACE 0
|
#define SAM_EHCI_IFACE 0
|
||||||
#define SAM_OHCI_IFACE 1
|
#define SAM_OHCI_IFACE 1
|
||||||
|
|
||||||
|
/* This is the interface argument for call outs to board-specific functions which
|
||||||
|
* need to know which root hub port is being used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SAM_RHPORT1 0
|
||||||
|
#define SAM_RHPORT2 1
|
||||||
|
#define SAM_RHPORT3 2
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
@@ -149,9 +157,8 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller);
|
|||||||
* each platform that implements the OHCI or EHCI host interface
|
* each platform that implements the OHCI or EHCI host interface
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* iface - Selects USB host interface:
|
* rhport - Selects root hub port to be powered host interface. See SAM_RHPORT_*
|
||||||
* 0 = EHCI
|
* definitions above.
|
||||||
* 1 = OHCI
|
|
||||||
* enable - true: enable VBUS power; false: disable VBUS power
|
* enable - true: enable VBUS power; false: disable VBUS power
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -159,7 +166,7 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller);
|
|||||||
*
|
*
|
||||||
***********************************************************************************/
|
***********************************************************************************/
|
||||||
|
|
||||||
void sam_usbhost_vbusdrive(int iface, bool enable);
|
void sam_usbhost_vbusdrive(int rhport, bool enable);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
|||||||
@@ -83,6 +83,12 @@ static struct usbhost_connection_s *g_ohciconn;
|
|||||||
static struct usbhost_connection_s *g_ehciconn;
|
static struct usbhost_connection_s *g_ehciconn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Overcurrent interrupt handler */
|
||||||
|
|
||||||
|
#if defined(HAVE_USBHOST) && defined(CONFIG_SAMA5_PIOD_IRQ)
|
||||||
|
static xcpt_t g_ochandler;
|
||||||
|
#endif
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
@@ -229,7 +235,7 @@ static int ehci_waiter(int argc, char *argv[])
|
|||||||
|
|
||||||
void weak_function sam_usbinitialize(void)
|
void weak_function sam_usbinitialize(void)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef HAVE_USBDEV
|
||||||
/* Configure Port A to support the USB device function */
|
/* Configure Port A to support the USB device function */
|
||||||
|
|
||||||
sam_configpio(PIO_USBA_VBUS_SENSE); /* VBUS sense */
|
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 */
|
/* TODO: Configure an interrupt on VBUS sense */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SAMA5_OHCI
|
#ifdef HAVE_USBHOST
|
||||||
/* Configure Port C to support the USB OHCI function */
|
#ifndef HAVE_USBDEV
|
||||||
|
/* Configure Port A to support the USB OHCI/EHCI function only if USB
|
||||||
sam_configpio(PIO_USBC_VBUS_ENABLE); /* VBUS enable, initially OFF */
|
* device is not also supported.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sam_configpio(PIO_USBA_VBUS_ENABLE); /* VBUS enable, initially OFF */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SAMA5_EHCI
|
/* Configure Ports B and C to support the USB OHCI/EHCI function */
|
||||||
/* Configure Port B to support the USB OHCI function */
|
|
||||||
|
|
||||||
sam_configpio(PIO_USBB_VBUS_ENABLE); /* VBUS enable, initially OFF */
|
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 */
|
/* Configure Port B/C VBUS overrcurrent detection */
|
||||||
|
|
||||||
sam_configpio(PIO_USBBC_VBUS_OVERCURRENT); /* VBUS overcurrent */
|
sam_configpio(PIO_USBBC_VBUS_OVERCURRENT); /* VBUS overcurrent */
|
||||||
@@ -271,7 +276,7 @@ void weak_function sam_usbinitialize(void)
|
|||||||
#if HAVE_USBHOST
|
#if HAVE_USBHOST
|
||||||
int sam_usbhost_initialize(void)
|
int sam_usbhost_initialize(void)
|
||||||
{
|
{
|
||||||
int pid;
|
pid_t pid;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* First, register all of the class drivers needed to support the drivers
|
/* 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
|
* each platform that implements the OHCI or EHCI host interface
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* iface - Selects USB host interface:
|
* rhport - Selects root hub port to be powered host interface. See SAM_RHPORT_*
|
||||||
* 0 = EHCI (Port B)
|
* definitions above.
|
||||||
* 1 = OHCI (Port C)
|
|
||||||
* enable - true: enable VBUS power; false: disable VBUS power
|
* enable - true: enable VBUS power; false: disable VBUS power
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -349,34 +353,37 @@ int sam_usbhost_initialize(void)
|
|||||||
***********************************************************************************/
|
***********************************************************************************/
|
||||||
|
|
||||||
#if HAVE_USBHOST
|
#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
|
/* Pick the PIO configuration associated with the selected root hub port */
|
||||||
if (iface == SAM_OHCI_IFACE)
|
|
||||||
|
switch (rhport)
|
||||||
{
|
{
|
||||||
uvdbg("OHCI: iface %d enable %d\n", iface, enable);
|
case SAM_RHPORT1:
|
||||||
pinset = PIO_USBC_VBUS_ENABLE;
|
#ifdef HAVE_USBDEV
|
||||||
}
|
udbg("ERROR: RHPort1 is not available in this configuration\n");
|
||||||
else
|
return;
|
||||||
|
#else
|
||||||
|
pinset = PIO_USBA_VBUS_ENABLE;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SAMA5_EHCI
|
case SAM_RHPORT2:
|
||||||
if (iface == SAM_EHCI_IFACE)
|
|
||||||
{
|
|
||||||
uvdbg("EHCI: iface %d enable %d\n", iface, enable);
|
|
||||||
pinset = PIO_USBB_VBUS_ENABLE;
|
pinset = PIO_USBB_VBUS_ENABLE;
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
case SAM_RHPORT3:
|
||||||
udbg("ERROR: Unsupported iface %d\n", iface);
|
pinset = PIO_USBC_VBUS_ENABLE;
|
||||||
return;
|
break;
|
||||||
}
|
|
||||||
|
default:
|
||||||
|
udbg("ERROR: RHPort%d is not supported\n", rhport+1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Then enable or disable VBUS power */
|
/* 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 */
|
/* Enable the Power Switch by driving the enable pin low */
|
||||||
|
|
||||||
sam_piowrite(pinset, false);
|
sam_piowrite(pinset, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Disable the Power Switch by driving the enable pin high */
|
/* Disable the Power Switch by driving the enable pin high */
|
||||||
|
|
||||||
sam_piowrite(pinset, false);
|
sam_piowrite(pinset, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
* Setup to receive an interrupt-level callback if an overcurrent condition is
|
||||||
* detected.
|
* 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:
|
* Input paramter:
|
||||||
* handler - New overcurrent interrupt handler
|
* handler - New overcurrent interrupt handler
|
||||||
*
|
*
|
||||||
@@ -413,12 +423,33 @@ void sam_usbhost_vbusdrive(int iface, bool enable)
|
|||||||
#if HAVE_USBHOST
|
#if HAVE_USBHOST
|
||||||
xcpt_t sam_setup_overcurrent(xcpt_t handler)
|
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
|
#if defined(CONFIG_SAMA5_PIOD_IRQ)
|
||||||
* both EHCI and OHCI drivers when this error occurs.
|
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;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
#define HAVE_HSMCI_MTD 1
|
#define HAVE_HSMCI_MTD 1
|
||||||
#define HAVE_AT25_MTD 1
|
#define HAVE_AT25_MTD 1
|
||||||
#define HAVE_USBHOST 1
|
#define HAVE_USBHOST 1
|
||||||
|
#define HAVE_USBDEV 1
|
||||||
|
|
||||||
/* HSMCI */
|
/* HSMCI */
|
||||||
/* Can't support MMC/SD if the card interface(s) are not enable */
|
/* Can't support MMC/SD if the card interface(s) are not enable */
|
||||||
@@ -120,12 +121,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(CONFIG_SAMA5_UDPHS)
|
#if !defined(CONFIG_SAMA5_UDPHS)
|
||||||
|
# undef HAVE_USBDEV
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* CONFIG_USBDEV and CONFIG_USBHOST must also be defined */
|
/* CONFIG_USBDEV and CONFIG_USBHOST must also be defined */
|
||||||
|
|
||||||
#if defined(CONFIG_USBDEV)
|
#if !defined(CONFIG_USBDEV)
|
||||||
#else
|
# undef HAVE_USBDEV
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_USBHOST)
|
#if defined(CONFIG_USBHOST)
|
||||||
@@ -137,11 +139,6 @@
|
|||||||
# undef CONFIG_SAMA5_EHCI
|
# undef CONFIG_SAMA5_EHCI
|
||||||
#endif
|
#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)
|
#if !defined(CONFIG_SAMA5_OHCI) && !defined(CONFIG_SAMA5_EHCI)
|
||||||
# undef HAVE_USBHOST
|
# undef HAVE_USBHOST
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user