mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Merge branch 'next' of git://source.denx.de/u-boot-usb into next
- Tighten some USB dependencies and remove some unused code.
This commit is contained in:
@@ -17,6 +17,7 @@ comment "Platform Glue Driver Support"
|
||||
|
||||
config USB_DWC3_OMAP
|
||||
bool "Texas Instruments OMAP5 and similar Platforms"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
help
|
||||
Some platforms from Texas Instruments like OMAP5, DRA7xxx and
|
||||
AM437x use this IP for USB2/3 functionality.
|
||||
@@ -39,14 +40,14 @@ config SPL_USB_DWC3_GENERIC
|
||||
|
||||
config SPL_USB_DWC3_AM62
|
||||
bool "TI AM62 USB wrapper"
|
||||
depends on SPL_DM_USB && SPL_USB_DWC3_GENERIC && SPL_SYSCON
|
||||
depends on SPL_DM_USB && SPL_USB_DWC3_GENERIC && SPL_SYSCON && ARCH_K3
|
||||
help
|
||||
Select this for TI AM62 Platforms.
|
||||
This wrapper supports Host and Peripheral operation modes.
|
||||
|
||||
config USB_DWC3_AM62
|
||||
bool "TI AM62 USB wrapper"
|
||||
depends on DM_USB && USB_DWC3_GENERIC && SYSCON
|
||||
depends on DM_USB && USB_DWC3_GENERIC && SYSCON && ARCH_K3
|
||||
help
|
||||
Select this for TI AM62 Platforms.
|
||||
This wrapper supports Host and Peripheral operation modes.
|
||||
@@ -80,7 +81,7 @@ config USB_DWC3_UNIPHIER
|
||||
config USB_DWC3_LAYERSCAPE
|
||||
bool "Freescale Layerscape platform support"
|
||||
depends on DM_USB && USB_DWC3
|
||||
depends on !USB_XHCI_FSL
|
||||
depends on !USB_XHCI_FSL && ARM
|
||||
help
|
||||
Select this for Freescale Layerscape Platforms.
|
||||
|
||||
@@ -99,12 +100,14 @@ menu "PHY Subsystem"
|
||||
|
||||
config USB_DWC3_PHY_OMAP
|
||||
bool "TI OMAP SoC series USB DRD PHY driver"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
help
|
||||
Enable single driver for both USB2 PHY programming and USB3 PHY
|
||||
programming for TI SoCs.
|
||||
|
||||
config USB_DWC3_PHY_SAMSUNG
|
||||
bool "Exynos5 SoC series USB DRD PHY driver"
|
||||
depends on ARCH_EXYNOS
|
||||
help
|
||||
Enable USB DRD PHY support for Exynos 5 SoC series.
|
||||
This driver provides PHY interface for USB 3.0 DRD controller
|
||||
|
||||
@@ -93,16 +93,12 @@ config USB_GADGET_PRODUCT_NUM
|
||||
|
||||
config USB_GADGET_ATMEL_USBA
|
||||
bool "Atmel USBA"
|
||||
depends on ARCH_AT91
|
||||
select USB_GADGET_DUALSPEED
|
||||
help
|
||||
USBA is the integrated high-speed USB Device controller on
|
||||
the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
|
||||
|
||||
config USB_GADGET_BCM_UDC_OTG_PHY
|
||||
bool "Broadcom UDC OTG PHY"
|
||||
help
|
||||
Enable the Broadcom UDC OTG physical device interface.
|
||||
|
||||
config USB_GADGET_AT91
|
||||
bool "Atmel AT91 USB Gadget Controller"
|
||||
depends on ARCH_AT91
|
||||
@@ -156,12 +152,6 @@ config CI_UDC
|
||||
Say Y here to enable device controller functionality of the
|
||||
ChipIdea driver.
|
||||
|
||||
config USB_GADGET_MAX3420
|
||||
bool "MAX3420 USB Over SPI"
|
||||
depends on DM_SPI
|
||||
help
|
||||
MAX3420, from MAXIM, implements USB-over-SPI Full-Speed device controller.
|
||||
|
||||
config USB_GADGET_VBUS_DRAW
|
||||
int "Maximum VBUS Power usage (2-500 mA)"
|
||||
range 2 500
|
||||
|
||||
@@ -17,10 +17,8 @@ endif
|
||||
ifdef CONFIG_USB_GADGET
|
||||
obj-$(CONFIG_USB_GADGET_AT91) += at91_udc.o
|
||||
obj-$(CONFIG_USB_GADGET_ATMEL_USBA) += atmel_usba_udc.o
|
||||
obj-$(CONFIG_USB_GADGET_BCM_UDC_OTG_PHY) += bcm_udc_otg_phy.o
|
||||
obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o
|
||||
obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o
|
||||
obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o
|
||||
obj-$(CONFIG_USB_RENESAS_USBHS) += rcar/
|
||||
ifndef CONFIG_XPL_BUILD
|
||||
obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2015 Broadcom Corporation.
|
||||
*/
|
||||
|
||||
#ifndef __BCM_UDC_OTG_H
|
||||
#define __BCM_UDC_OTG_H
|
||||
|
||||
static inline void wfld_set(uintptr_t addr, uint32_t fld_val, uint32_t fld_mask)
|
||||
{
|
||||
writel(((readl(addr) & ~(fld_mask)) | (fld_val)), (addr));
|
||||
}
|
||||
|
||||
static inline void wfld_clear(uintptr_t addr, uint32_t fld_mask)
|
||||
{
|
||||
writel((readl(addr) & ~(fld_mask)), (addr));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Broadcom Corporation.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/sysmap.h>
|
||||
#include <asm/kona-common/clk.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "dwc2_udc_otg_priv.h"
|
||||
#include "bcm_udc_otg.h"
|
||||
|
||||
void otg_phy_init(struct dwc2_udc *dev)
|
||||
{
|
||||
/* turn on the USB OTG clocks */
|
||||
clk_usb_otg_enable((void *)HSOTG_BASE_ADDR);
|
||||
|
||||
/* set Phy to driving mode */
|
||||
wfld_clear(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
|
||||
HSOTG_CTRL_PHY_P1CTL_NON_DRIVING_MASK);
|
||||
|
||||
udelay(100);
|
||||
|
||||
/* clear Soft Disconnect */
|
||||
wfld_clear(HSOTG_BASE_ADDR + HSOTG_DCTL_OFFSET,
|
||||
HSOTG_DCTL_SFTDISCON_MASK);
|
||||
|
||||
/* invoke Reset (active low) */
|
||||
wfld_clear(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
|
||||
HSOTG_CTRL_PHY_P1CTL_SOFT_RESET_MASK);
|
||||
|
||||
/* Reset needs to be asserted for 2ms */
|
||||
udelay(2000);
|
||||
|
||||
/* release Reset */
|
||||
wfld_set(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
|
||||
HSOTG_CTRL_PHY_P1CTL_SOFT_RESET_MASK,
|
||||
HSOTG_CTRL_PHY_P1CTL_SOFT_RESET_MASK);
|
||||
}
|
||||
|
||||
void otg_phy_off(struct dwc2_udc *dev)
|
||||
{
|
||||
/* Soft Disconnect */
|
||||
wfld_set(HSOTG_BASE_ADDR + HSOTG_DCTL_OFFSET,
|
||||
HSOTG_DCTL_SFTDISCON_MASK,
|
||||
HSOTG_DCTL_SFTDISCON_MASK);
|
||||
|
||||
/* set Phy to non-driving (reset) mode */
|
||||
wfld_set(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
|
||||
HSOTG_CTRL_PHY_P1CTL_NON_DRIVING_MASK,
|
||||
HSOTG_CTRL_PHY_P1CTL_NON_DRIVING_MASK);
|
||||
}
|
||||
@@ -1,879 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <malloc.h>
|
||||
#include <spi.h>
|
||||
#include <dm.h>
|
||||
#include <g_dnl.h>
|
||||
|
||||
#define MAX3420_MAX_EPS 4
|
||||
#define EP_MAX_PACKET 64 /* Same for all Endpoints */
|
||||
#define EPNAME_SIZE 16 /* Buffer size for endpoint name */
|
||||
|
||||
#define MAX3420_SPI_DIR_RD 0 /* read register from MAX3420 */
|
||||
#define MAX3420_SPI_DIR_WR 1 /* write register to MAX3420 */
|
||||
|
||||
/* SPI commands: */
|
||||
#define MAX3420_SPI_ACK_MASK BIT(0)
|
||||
#define MAX3420_SPI_DIR_MASK BIT(1)
|
||||
#define MAX3420_SPI_REG_MASK GENMASK(7, 3)
|
||||
|
||||
#define MAX3420_REG_EP0FIFO 0
|
||||
#define MAX3420_REG_EP1FIFO 1
|
||||
#define MAX3420_REG_EP2FIFO 2
|
||||
#define MAX3420_REG_EP3FIFO 3
|
||||
#define MAX3420_REG_SUDFIFO 4
|
||||
#define MAX3420_REG_EP0BC 5
|
||||
#define MAX3420_REG_EP1BC 6
|
||||
#define MAX3420_REG_EP2BC 7
|
||||
#define MAX3420_REG_EP3BC 8
|
||||
|
||||
#define MAX3420_REG_EPSTALLS 9
|
||||
#define bACKSTAT BIT(6)
|
||||
#define bSTLSTAT BIT(5)
|
||||
#define bSTLEP3IN BIT(4)
|
||||
#define bSTLEP2IN BIT(3)
|
||||
#define bSTLEP1OUT BIT(2)
|
||||
#define bSTLEP0OUT BIT(1)
|
||||
#define bSTLEP0IN BIT(0)
|
||||
|
||||
#define MAX3420_REG_CLRTOGS 10
|
||||
#define bEP3DISAB BIT(7)
|
||||
#define bEP2DISAB BIT(6)
|
||||
#define bEP1DISAB BIT(5)
|
||||
#define bCTGEP3IN BIT(4)
|
||||
#define bCTGEP2IN BIT(3)
|
||||
#define bCTGEP1OUT BIT(2)
|
||||
|
||||
#define MAX3420_REG_EPIRQ 11
|
||||
#define MAX3420_REG_EPIEN 12
|
||||
#define bSUDAVIRQ BIT(5)
|
||||
#define bIN3BAVIRQ BIT(4)
|
||||
#define bIN2BAVIRQ BIT(3)
|
||||
#define bOUT1DAVIRQ BIT(2)
|
||||
#define bOUT0DAVIRQ BIT(1)
|
||||
#define bIN0BAVIRQ BIT(0)
|
||||
|
||||
#define MAX3420_REG_USBIRQ 13
|
||||
#define MAX3420_REG_USBIEN 14
|
||||
#define bOSCOKIRQ BIT(0)
|
||||
#define bRWUDNIRQ BIT(1)
|
||||
#define bBUSACTIRQ BIT(2)
|
||||
#define bURESIRQ BIT(3)
|
||||
#define bSUSPIRQ BIT(4)
|
||||
#define bNOVBUSIRQ BIT(5)
|
||||
#define bVBUSIRQ BIT(6)
|
||||
#define bURESDNIRQ BIT(7)
|
||||
|
||||
#define MAX3420_REG_USBCTL 15
|
||||
#define bHOSCSTEN BIT(7)
|
||||
#define bVBGATE BIT(6)
|
||||
#define bCHIPRES BIT(5)
|
||||
#define bPWRDOWN BIT(4)
|
||||
#define bCONNECT BIT(3)
|
||||
#define bSIGRWU BIT(2)
|
||||
|
||||
#define MAX3420_REG_CPUCTL 16
|
||||
#define bIE BIT(0)
|
||||
|
||||
#define MAX3420_REG_PINCTL 17
|
||||
#define bEP3INAK BIT(7)
|
||||
#define bEP2INAK BIT(6)
|
||||
#define bEP0INAK BIT(5)
|
||||
#define bFDUPSPI BIT(4)
|
||||
#define bINTLEVEL BIT(3)
|
||||
#define bPOSINT BIT(2)
|
||||
#define bGPXB BIT(1)
|
||||
#define bGPXA BIT(0)
|
||||
|
||||
#define MAX3420_REG_REVISION 18
|
||||
|
||||
#define MAX3420_REG_FNADDR 19
|
||||
#define FNADDR_MASK 0x7f
|
||||
|
||||
#define MAX3420_REG_IOPINS 20
|
||||
#define MAX3420_REG_IOPINS2 21
|
||||
#define MAX3420_REG_GPINIRQ 22
|
||||
#define MAX3420_REG_GPINIEN 23
|
||||
#define MAX3420_REG_GPINPOL 24
|
||||
#define MAX3420_REG_HIRQ 25
|
||||
#define MAX3420_REG_HIEN 26
|
||||
#define MAX3420_REG_MODE 27
|
||||
#define MAX3420_REG_PERADDR 28
|
||||
#define MAX3420_REG_HCTL 29
|
||||
#define MAX3420_REG_HXFR 30
|
||||
#define MAX3420_REG_HRSL 31
|
||||
|
||||
struct max3420_req {
|
||||
struct usb_request usb_req;
|
||||
struct list_head queue;
|
||||
struct max3420_ep *ep;
|
||||
};
|
||||
|
||||
struct max3420_ep {
|
||||
struct max3420_udc *udc;
|
||||
struct list_head queue;
|
||||
char name[EPNAME_SIZE];
|
||||
unsigned int maxpacket;
|
||||
struct usb_ep ep_usb;
|
||||
int halted;
|
||||
int id;
|
||||
};
|
||||
|
||||
struct max3420_udc {
|
||||
struct max3420_ep ep[MAX3420_MAX_EPS];
|
||||
struct usb_gadget_driver *driver;
|
||||
bool softconnect;
|
||||
struct usb_ctrlrequest setup;
|
||||
struct max3420_req ep0req;
|
||||
struct usb_gadget gadget;
|
||||
struct spi_slave *slave;
|
||||
struct udevice *dev;
|
||||
u8 ep0buf[64];
|
||||
int remote_wkp;
|
||||
bool suspended;
|
||||
};
|
||||
|
||||
#define to_max3420_req(r) container_of((r), struct max3420_req, usb_req)
|
||||
#define to_max3420_ep(e) container_of((e), struct max3420_ep, ep_usb)
|
||||
#define to_udc(g) container_of((g), struct max3420_udc, gadget)
|
||||
|
||||
static void spi_ack_ctrl(struct max3420_udc *udc)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[1];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_ACK_MASK, 1);
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_ONCE);
|
||||
}
|
||||
|
||||
static u8 spi_rd8_ack(struct max3420_udc *udc, u8 reg, int ackstat)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[2], rxdata[2];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_RD) |
|
||||
FIELD_PREP(MAX3420_SPI_ACK_MASK, ackstat ? 1 : 0);
|
||||
|
||||
rxdata[0] = 0;
|
||||
rxdata[1] = 0;
|
||||
spi_xfer(slave, sizeof(txdata), txdata, rxdata, SPI_XFER_ONCE);
|
||||
|
||||
return rxdata[1];
|
||||
}
|
||||
|
||||
static u8 spi_rd8(struct max3420_udc *udc, u8 reg)
|
||||
{
|
||||
return spi_rd8_ack(udc, reg, 0);
|
||||
}
|
||||
|
||||
static void spi_wr8_ack(struct max3420_udc *udc, u8 reg, u8 val, int ackstat)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[2];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_WR) |
|
||||
FIELD_PREP(MAX3420_SPI_ACK_MASK, ackstat ? 1 : 0);
|
||||
txdata[1] = val;
|
||||
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_ONCE);
|
||||
}
|
||||
|
||||
static void spi_wr8(struct max3420_udc *udc, u8 reg, u8 val)
|
||||
{
|
||||
spi_wr8_ack(udc, reg, val, 0);
|
||||
}
|
||||
|
||||
static void spi_rd_buf(struct max3420_udc *udc, u8 reg, void *buf, u8 len)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[1];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_RD);
|
||||
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_BEGIN);
|
||||
spi_xfer(slave, len * 8, NULL, buf, SPI_XFER_END);
|
||||
}
|
||||
|
||||
static void spi_wr_buf(struct max3420_udc *udc, u8 reg, void *buf, u8 len)
|
||||
{
|
||||
struct spi_slave *slave = udc->slave;
|
||||
u8 txdata[1];
|
||||
|
||||
txdata[0] = FIELD_PREP(MAX3420_SPI_REG_MASK, reg) |
|
||||
FIELD_PREP(MAX3420_SPI_DIR_MASK, MAX3420_SPI_DIR_WR);
|
||||
|
||||
spi_xfer(slave, sizeof(txdata), txdata, NULL, SPI_XFER_BEGIN);
|
||||
spi_xfer(slave, len * 8, buf, NULL, SPI_XFER_END);
|
||||
}
|
||||
|
||||
/* 0 if not-connected */
|
||||
int g_dnl_board_usb_cable_connected(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void spi_max3420_enable(struct max3420_ep *ep, int enable)
|
||||
{
|
||||
struct max3420_udc *udc = ep->udc;
|
||||
u8 epdis, epien;
|
||||
|
||||
if (ep->id == 0)
|
||||
return;
|
||||
|
||||
epien = spi_rd8(udc, MAX3420_REG_EPIEN);
|
||||
epdis = spi_rd8(udc, MAX3420_REG_CLRTOGS);
|
||||
|
||||
if (enable) {
|
||||
epdis &= ~BIT(ep->id + 4);
|
||||
epien |= BIT(ep->id + 1);
|
||||
} else {
|
||||
epdis |= BIT(ep->id + 4);
|
||||
epien &= ~BIT(ep->id + 1);
|
||||
}
|
||||
|
||||
spi_wr8(udc, MAX3420_REG_CLRTOGS, epdis);
|
||||
spi_wr8(udc, MAX3420_REG_EPIEN, epien);
|
||||
}
|
||||
|
||||
static int
|
||||
max3420_ep_enable(struct usb_ep *_ep,
|
||||
const struct usb_endpoint_descriptor *desc)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
|
||||
_ep->desc = desc;
|
||||
_ep->maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
|
||||
|
||||
spi_max3420_enable(ep, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void max3420_req_done(struct max3420_req *req, int status)
|
||||
{
|
||||
struct max3420_ep *ep = req->ep;
|
||||
|
||||
if (req->usb_req.status == -EINPROGRESS)
|
||||
req->usb_req.status = status;
|
||||
else
|
||||
status = req->usb_req.status;
|
||||
|
||||
if (status && status != -ESHUTDOWN)
|
||||
dev_err(ep->udc->dev, "%s done %p, status %d\n",
|
||||
ep->ep_usb.name, req, status);
|
||||
|
||||
if (req->usb_req.complete)
|
||||
req->usb_req.complete(&ep->ep_usb, &req->usb_req);
|
||||
}
|
||||
|
||||
static void max3420_ep_nuke(struct max3420_ep *ep, int status)
|
||||
{
|
||||
struct max3420_req *req, *r;
|
||||
|
||||
list_for_each_entry_safe(req, r, &ep->queue, queue) {
|
||||
list_del_init(&req->queue);
|
||||
max3420_req_done(req, status);
|
||||
}
|
||||
}
|
||||
|
||||
static int max3420_ep_disable(struct usb_ep *_ep)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
|
||||
_ep->desc = NULL;
|
||||
max3420_ep_nuke(ep, -ESHUTDOWN);
|
||||
spi_max3420_enable(ep, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_request *
|
||||
max3420_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
struct max3420_req *req = kzalloc(sizeof(*req), gfp_flags);
|
||||
|
||||
if (!req)
|
||||
return NULL;
|
||||
|
||||
req->ep = ep;
|
||||
INIT_LIST_HEAD(&req->queue);
|
||||
|
||||
return &req->usb_req;
|
||||
}
|
||||
|
||||
static void
|
||||
max3420_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
|
||||
{
|
||||
kfree(to_max3420_req(_req));
|
||||
}
|
||||
|
||||
static int
|
||||
max3420_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
||||
{
|
||||
struct max3420_req *req = to_max3420_req(_req);
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
|
||||
_req->status = -EINPROGRESS;
|
||||
_req->actual = 0;
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
||||
{
|
||||
struct max3420_req *req = to_max3420_req(_req);
|
||||
|
||||
list_del_init(&req->queue);
|
||||
max3420_req_done(req, -ECONNRESET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_ep_set_halt(struct usb_ep *_ep, int halt)
|
||||
{
|
||||
struct max3420_ep *ep = to_max3420_ep(_ep);
|
||||
struct max3420_udc *udc = ep->udc;
|
||||
u8 epstalls;
|
||||
|
||||
if (ep->id == 0) /* can't stall EP0 */
|
||||
return 0;
|
||||
|
||||
epstalls = spi_rd8(udc, MAX3420_REG_EPSTALLS);
|
||||
if (halt) {
|
||||
ep->halted = 1;
|
||||
epstalls |= BIT(ep->id + 1);
|
||||
} else {
|
||||
u8 clrtogs;
|
||||
|
||||
ep->halted = 0;
|
||||
epstalls &= ~BIT(ep->id + 1);
|
||||
clrtogs = spi_rd8(udc, MAX3420_REG_CLRTOGS);
|
||||
clrtogs |= BIT(ep->id + 1);
|
||||
spi_wr8(udc, MAX3420_REG_CLRTOGS, clrtogs);
|
||||
}
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS, epstalls | bACKSTAT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct usb_ep_ops max3420_ep_ops = {
|
||||
.enable = max3420_ep_enable,
|
||||
.disable = max3420_ep_disable,
|
||||
.alloc_request = max3420_ep_alloc_request,
|
||||
.free_request = max3420_ep_free_request,
|
||||
.queue = max3420_ep_queue,
|
||||
.dequeue = max3420_ep_dequeue,
|
||||
.set_halt = max3420_ep_set_halt,
|
||||
};
|
||||
|
||||
static void __max3420_stop(struct max3420_udc *udc)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
/* Disable IRQ to CPU */
|
||||
spi_wr8(udc, MAX3420_REG_CPUCTL, 0);
|
||||
|
||||
val = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
val |= bPWRDOWN;
|
||||
val |= bHOSCSTEN;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, val);
|
||||
}
|
||||
|
||||
static void __max3420_start(struct max3420_udc *udc)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
/* configure SPI */
|
||||
spi_wr8(udc, MAX3420_REG_PINCTL, bFDUPSPI);
|
||||
|
||||
/* Chip Reset */
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, bCHIPRES);
|
||||
mdelay(5);
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, 0);
|
||||
|
||||
/* Poll for OSC to stabilize */
|
||||
while (1) {
|
||||
val = spi_rd8(udc, MAX3420_REG_USBIRQ);
|
||||
if (val & bOSCOKIRQ)
|
||||
break;
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
/* Enable PULL-UP only when Vbus detected */
|
||||
val = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
val |= bVBGATE | bCONNECT;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, val);
|
||||
|
||||
val = bURESDNIRQ | bURESIRQ;
|
||||
spi_wr8(udc, MAX3420_REG_USBIEN, val);
|
||||
|
||||
/* Enable only EP0 interrupts */
|
||||
val = bIN0BAVIRQ | bOUT0DAVIRQ | bSUDAVIRQ;
|
||||
spi_wr8(udc, MAX3420_REG_EPIEN, val);
|
||||
|
||||
/* Enable IRQ to CPU */
|
||||
spi_wr8(udc, MAX3420_REG_CPUCTL, bIE);
|
||||
}
|
||||
|
||||
static int max3420_udc_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct max3420_udc *udc = to_udc(gadget);
|
||||
|
||||
udc->driver = driver;
|
||||
udc->remote_wkp = 0;
|
||||
udc->softconnect = true;
|
||||
|
||||
__max3420_start(udc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_udc_stop(struct usb_gadget *gadget)
|
||||
{
|
||||
struct max3420_udc *udc = to_udc(gadget);
|
||||
|
||||
udc->driver = NULL;
|
||||
udc->softconnect = false;
|
||||
|
||||
__max3420_stop(udc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_wakeup(struct usb_gadget *gadget)
|
||||
{
|
||||
struct max3420_udc *udc = to_udc(gadget);
|
||||
u8 usbctl;
|
||||
|
||||
/* Only if wakeup allowed by host */
|
||||
if (!udc->remote_wkp || !udc->suspended)
|
||||
return 0;
|
||||
|
||||
/* Set Remote-Wakeup Signal*/
|
||||
usbctl = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
usbctl |= bSIGRWU;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, usbctl);
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Clear Remote-WkUp Signal*/
|
||||
usbctl = spi_rd8(udc, MAX3420_REG_USBCTL);
|
||||
usbctl &= ~bSIGRWU;
|
||||
spi_wr8(udc, MAX3420_REG_USBCTL, usbctl);
|
||||
|
||||
udc->suspended = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct usb_gadget_ops max3420_udc_ops = {
|
||||
.udc_start = max3420_udc_start,
|
||||
.udc_stop = max3420_udc_stop,
|
||||
.wakeup = max3420_wakeup,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor ep0_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
|
||||
.wMaxPacketSize = cpu_to_le16(EP_MAX_PACKET),
|
||||
};
|
||||
|
||||
static void max3420_getstatus(struct max3420_udc *udc)
|
||||
{
|
||||
struct max3420_ep *ep;
|
||||
u16 status = 0;
|
||||
|
||||
switch (udc->setup.bRequestType & USB_RECIP_MASK) {
|
||||
case USB_RECIP_DEVICE:
|
||||
/* Get device status */
|
||||
status = 0 << USB_DEVICE_SELF_POWERED;
|
||||
status |= (udc->remote_wkp << USB_DEVICE_REMOTE_WAKEUP);
|
||||
break;
|
||||
case USB_RECIP_INTERFACE:
|
||||
if (udc->driver->setup(&udc->gadget, &udc->setup) < 0)
|
||||
goto stall;
|
||||
break;
|
||||
case USB_RECIP_ENDPOINT:
|
||||
ep = &udc->ep[udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK];
|
||||
if (ep->halted)
|
||||
status = 1 << USB_ENDPOINT_HALT;
|
||||
break;
|
||||
default:
|
||||
goto stall;
|
||||
}
|
||||
|
||||
status = cpu_to_le16(status);
|
||||
spi_wr_buf(udc, MAX3420_REG_EP0FIFO, &status, 2);
|
||||
spi_wr8_ack(udc, MAX3420_REG_EP0BC, 2, 1);
|
||||
return;
|
||||
stall:
|
||||
dev_err(udc->dev, "Can't respond to getstatus request\n");
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS, bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
|
||||
}
|
||||
|
||||
static void max3420_set_clear_feature(struct max3420_udc *udc)
|
||||
{
|
||||
int set = udc->setup.bRequest == USB_REQ_SET_FEATURE;
|
||||
struct max3420_ep *ep;
|
||||
int id;
|
||||
|
||||
switch (udc->setup.bRequestType) {
|
||||
case USB_RECIP_DEVICE:
|
||||
if (udc->setup.wValue != USB_DEVICE_REMOTE_WAKEUP)
|
||||
break;
|
||||
|
||||
if (udc->setup.bRequest == USB_REQ_SET_FEATURE)
|
||||
udc->remote_wkp = 1;
|
||||
else
|
||||
udc->remote_wkp = 0;
|
||||
|
||||
return spi_ack_ctrl(udc);
|
||||
|
||||
case USB_RECIP_ENDPOINT:
|
||||
if (udc->setup.wValue != USB_ENDPOINT_HALT)
|
||||
break;
|
||||
|
||||
id = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK;
|
||||
ep = &udc->ep[id];
|
||||
|
||||
max3420_ep_set_halt(&ep->ep_usb, set);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dev_err(udc->dev, "Can't respond to SET/CLEAR FEATURE\n");
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS, bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
|
||||
}
|
||||
|
||||
static void max3420_handle_setup(struct max3420_udc *udc)
|
||||
{
|
||||
struct usb_ctrlrequest setup;
|
||||
u8 addr;
|
||||
|
||||
spi_rd_buf(udc, MAX3420_REG_SUDFIFO, (void *)&setup, 8);
|
||||
|
||||
udc->setup = setup;
|
||||
udc->setup.wValue = cpu_to_le16(setup.wValue);
|
||||
udc->setup.wIndex = cpu_to_le16(setup.wIndex);
|
||||
udc->setup.wLength = cpu_to_le16(setup.wLength);
|
||||
|
||||
switch (udc->setup.bRequest) {
|
||||
case USB_REQ_GET_STATUS:
|
||||
/* Data+Status phase form udc */
|
||||
if ((udc->setup.bRequestType &
|
||||
(USB_DIR_IN | USB_TYPE_MASK)) !=
|
||||
(USB_DIR_IN | USB_TYPE_STANDARD)) {
|
||||
break;
|
||||
}
|
||||
return max3420_getstatus(udc);
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
/* Status phase from udc */
|
||||
if (udc->setup.bRequestType != (USB_DIR_OUT |
|
||||
USB_TYPE_STANDARD | USB_RECIP_DEVICE))
|
||||
break;
|
||||
addr = spi_rd8_ack(udc, MAX3420_REG_FNADDR, 1);
|
||||
dev_dbg(udc->dev, "Assigned Address=%d/%d\n",
|
||||
udc->setup.wValue, addr);
|
||||
return;
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
case USB_REQ_SET_FEATURE:
|
||||
/* Requests with no data phase, status phase from udc */
|
||||
if ((udc->setup.bRequestType & USB_TYPE_MASK)
|
||||
!= USB_TYPE_STANDARD)
|
||||
break;
|
||||
return max3420_set_clear_feature(udc);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (udc->driver->setup(&udc->gadget, &setup) < 0) {
|
||||
/* Stall EP0 */
|
||||
spi_wr8(udc, MAX3420_REG_EPSTALLS,
|
||||
bSTLEP0IN | bSTLEP0OUT | bSTLSTAT);
|
||||
}
|
||||
}
|
||||
|
||||
static int do_data(struct max3420_udc *udc, int ep_id, int in)
|
||||
{
|
||||
struct max3420_ep *ep = &udc->ep[ep_id];
|
||||
struct max3420_req *req;
|
||||
int done, length, psz;
|
||||
void *buf;
|
||||
|
||||
if (list_empty(&ep->queue))
|
||||
return 0;
|
||||
|
||||
req = list_first_entry(&ep->queue, struct max3420_req, queue);
|
||||
buf = req->usb_req.buf + req->usb_req.actual;
|
||||
|
||||
psz = ep->ep_usb.maxpacket;
|
||||
length = req->usb_req.length - req->usb_req.actual;
|
||||
length = min(length, psz);
|
||||
|
||||
if (length == 0) {
|
||||
done = 1;
|
||||
goto xfer_done;
|
||||
}
|
||||
|
||||
done = 0;
|
||||
if (in) {
|
||||
spi_wr_buf(udc, MAX3420_REG_EP0FIFO + ep_id, buf, length);
|
||||
spi_wr8(udc, MAX3420_REG_EP0BC + ep_id, length);
|
||||
if (length < psz)
|
||||
done = 1;
|
||||
} else {
|
||||
psz = spi_rd8(udc, MAX3420_REG_EP0BC + ep_id);
|
||||
length = min(length, psz);
|
||||
spi_rd_buf(udc, MAX3420_REG_EP0FIFO + ep_id, buf, length);
|
||||
if (length < ep->ep_usb.maxpacket)
|
||||
done = 1;
|
||||
}
|
||||
|
||||
req->usb_req.actual += length;
|
||||
|
||||
if (req->usb_req.actual == req->usb_req.length)
|
||||
done = 1;
|
||||
|
||||
xfer_done:
|
||||
if (done) {
|
||||
list_del_init(&req->queue);
|
||||
|
||||
if (ep_id == 0)
|
||||
spi_ack_ctrl(udc);
|
||||
|
||||
max3420_req_done(req, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int max3420_handle_irqs(struct max3420_udc *udc)
|
||||
{
|
||||
u8 epien, epirq, usbirq, usbien, reg[4];
|
||||
int ret = 0;
|
||||
|
||||
spi_rd_buf(udc, MAX3420_REG_EPIRQ, reg, 4);
|
||||
epirq = reg[0];
|
||||
epien = reg[1];
|
||||
usbirq = reg[2];
|
||||
usbien = reg[3];
|
||||
|
||||
usbirq &= usbien;
|
||||
epirq &= epien;
|
||||
|
||||
if (epirq & bSUDAVIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_EPIRQ, bSUDAVIRQ);
|
||||
max3420_handle_setup(udc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bVBUSIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bVBUSIRQ);
|
||||
dev_dbg(udc->dev, "Cable plugged in\n");
|
||||
g_dnl_clear_detach();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bNOVBUSIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bNOVBUSIRQ);
|
||||
dev_dbg(udc->dev, "Cable pulled out\n");
|
||||
g_dnl_trigger_detach();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bURESIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bURESIRQ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bURESDNIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bURESDNIRQ);
|
||||
spi_wr8(udc, MAX3420_REG_USBIEN, bURESDNIRQ | bURESIRQ);
|
||||
spi_wr8(udc, MAX3420_REG_EPIEN, bSUDAVIRQ
|
||||
| bIN0BAVIRQ | bOUT0DAVIRQ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bSUSPIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bSUSPIRQ);
|
||||
dev_dbg(udc->dev, "USB Suspend - Enter\n");
|
||||
udc->suspended = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bBUSACTIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bBUSACTIRQ);
|
||||
dev_dbg(udc->dev, "USB Suspend - Exit\n");
|
||||
udc->suspended = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bRWUDNIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bRWUDNIRQ);
|
||||
dev_dbg(udc->dev, "Asked Host to wakeup\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usbirq & bOSCOKIRQ) {
|
||||
spi_wr8(udc, MAX3420_REG_USBIRQ, bOSCOKIRQ);
|
||||
dev_dbg(udc->dev, "Osc stabilized, start work\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (epirq & bOUT0DAVIRQ && do_data(udc, 0, 0)) {
|
||||
spi_wr8_ack(udc, MAX3420_REG_EPIRQ, bOUT0DAVIRQ, 1);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (epirq & bIN0BAVIRQ && do_data(udc, 0, 1))
|
||||
ret = 1;
|
||||
|
||||
if (epirq & bOUT1DAVIRQ && do_data(udc, 1, 0)) {
|
||||
spi_wr8_ack(udc, MAX3420_REG_EPIRQ, bOUT1DAVIRQ, 1);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (epirq & bIN2BAVIRQ && do_data(udc, 2, 1))
|
||||
ret = 1;
|
||||
|
||||
if (epirq & bIN3BAVIRQ && do_data(udc, 3, 1))
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max3420_irq(struct max3420_udc *udc)
|
||||
{
|
||||
do_data(udc, 0, 1); /* get done with the EP0 ZLP */
|
||||
|
||||
return max3420_handle_irqs(udc);
|
||||
}
|
||||
|
||||
static void max3420_setup_eps(struct max3420_udc *udc)
|
||||
{
|
||||
int i;
|
||||
|
||||
INIT_LIST_HEAD(&udc->gadget.ep_list);
|
||||
INIT_LIST_HEAD(&udc->ep[0].ep_usb.ep_list);
|
||||
|
||||
for (i = 0; i < MAX3420_MAX_EPS; i++) {
|
||||
struct max3420_ep *ep = &udc->ep[i];
|
||||
|
||||
INIT_LIST_HEAD(&ep->queue);
|
||||
|
||||
ep->id = i;
|
||||
ep->udc = udc;
|
||||
ep->ep_usb.ops = &max3420_ep_ops;
|
||||
ep->ep_usb.name = ep->name;
|
||||
ep->ep_usb.maxpacket = EP_MAX_PACKET;
|
||||
|
||||
if (i == 0) {
|
||||
ep->ep_usb.desc = &ep0_desc;
|
||||
snprintf(ep->name, EPNAME_SIZE, "ep0");
|
||||
continue;
|
||||
}
|
||||
|
||||
list_add_tail(&ep->ep_usb.ep_list, &udc->gadget.ep_list);
|
||||
|
||||
if (i == 1)
|
||||
snprintf(ep->name, EPNAME_SIZE, "ep1out-bulk");
|
||||
else
|
||||
snprintf(ep->name, EPNAME_SIZE, "ep%din-bulk", i);
|
||||
};
|
||||
}
|
||||
|
||||
static void max3420_setup_spi(struct max3420_udc *udc)
|
||||
{
|
||||
u8 reg[8];
|
||||
|
||||
spi_claim_bus(udc->slave);
|
||||
spi_rd_buf(udc, MAX3420_REG_EPIRQ, reg, 8);
|
||||
/* configure SPI */
|
||||
spi_wr8(udc, MAX3420_REG_PINCTL, bFDUPSPI);
|
||||
}
|
||||
|
||||
static int max3420_udc_probe(struct udevice *dev)
|
||||
{
|
||||
struct max3420_udc *udc = dev_get_priv(dev);
|
||||
struct dm_spi_slave_plat *slave_pdata;
|
||||
struct udevice *bus = dev->parent;
|
||||
int busnum = dev_seq(bus);
|
||||
unsigned int cs;
|
||||
uint speed, mode;
|
||||
struct udevice *spid;
|
||||
|
||||
slave_pdata = dev_get_parent_plat(dev);
|
||||
cs = slave_pdata->cs;
|
||||
speed = slave_pdata->max_hz;
|
||||
mode = slave_pdata->mode;
|
||||
_spi_get_bus_and_cs(busnum, cs, speed, mode, false, "spi_generic_drv",
|
||||
NULL, &spid, &udc->slave);
|
||||
|
||||
udc->dev = dev;
|
||||
udc->gadget.ep0 = &udc->ep[0].ep_usb;
|
||||
udc->gadget.max_speed = USB_SPEED_FULL;
|
||||
udc->gadget.speed = USB_SPEED_FULL;
|
||||
udc->gadget.is_dualspeed = 0;
|
||||
udc->gadget.ops = &max3420_udc_ops;
|
||||
udc->gadget.name = "max3420-udc";
|
||||
|
||||
max3420_setup_eps(udc);
|
||||
max3420_setup_spi(udc);
|
||||
|
||||
usb_add_gadget_udc((struct device *)dev, &udc->gadget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_udc_remove(struct udevice *dev)
|
||||
{
|
||||
struct max3420_udc *udc = dev_get_priv(dev);
|
||||
|
||||
usb_del_gadget_udc(&udc->gadget);
|
||||
|
||||
spi_release_bus(udc->slave);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3420_gadget_handle_interrupts(struct udevice *dev)
|
||||
{
|
||||
struct max3420_udc *udc = dev_get_priv(dev);
|
||||
|
||||
return max3420_irq(udc);
|
||||
}
|
||||
|
||||
static const struct usb_gadget_generic_ops max3420_gadget_ops = {
|
||||
.handle_interrupts = max3420_gadget_handle_interrupts,
|
||||
};
|
||||
|
||||
static const struct udevice_id max3420_ids[] = {
|
||||
{ .compatible = "maxim,max3421-udc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(max3420_generic_udc) = {
|
||||
.name = "max3420-udc",
|
||||
.id = UCLASS_USB_GADGET_GENERIC,
|
||||
.of_match = max3420_ids,
|
||||
.ops = &max3420_gadget_ops,
|
||||
.probe = max3420_udc_probe,
|
||||
.remove = max3420_udc_remove,
|
||||
.priv_auto = sizeof(struct max3420_udc),
|
||||
};
|
||||
@@ -121,8 +121,9 @@ config USB_XHCI_DRA7XX_INDEX
|
||||
|
||||
config USB_XHCI_FSL
|
||||
bool "Support for NXP Layerscape on-chip xHCI USB controller"
|
||||
default y if ARCH_LS1021A || FSL_LSCH3 || FSL_LSCH2
|
||||
depends on ARCH_LS1021A || FSL_LSCH3 || FSL_LSCH2
|
||||
depends on !SPL_NO_USB
|
||||
default y
|
||||
help
|
||||
Enables support for the on-chip xHCI controller on NXP Layerscape SoCs.
|
||||
|
||||
@@ -286,7 +287,8 @@ config USB_EHCI_TEGRA
|
||||
|
||||
config USB_EHCI_ZYNQ
|
||||
bool "Support for Xilinx Zynq on-chip EHCI USB controller"
|
||||
default y if ARCH_ZYNQ
|
||||
depends on ARCH_ZYNQ
|
||||
default y
|
||||
select USB_EHCI_IS_TDI
|
||||
---help---
|
||||
Enable support for Zynq on-chip EHCI USB controller
|
||||
@@ -303,6 +305,7 @@ config EHCI_HCD_INIT_AFTER_RESET
|
||||
|
||||
config USB_EHCI_FSL
|
||||
bool "Support for FSL on-chip EHCI USB controller"
|
||||
depends on PPC
|
||||
select EHCI_HCD_INIT_AFTER_RESET
|
||||
select SYS_FSL_USB_INTERNAL_UTMI_PHY if MPC85xx && \
|
||||
!(ARCH_B4860 || ARCH_B4420 || ARCH_P4080 || ARCH_P1020 || ARCH_P2020)
|
||||
@@ -362,6 +365,7 @@ config USB_OHCI_GENERIC
|
||||
|
||||
config USB_OHCI_DA8XX
|
||||
bool "Support for da850 OHCI USB controller"
|
||||
depends on ARCH_DAVINCI
|
||||
help
|
||||
Enable support for the da850 USB controller.
|
||||
|
||||
|
||||
@@ -52,9 +52,11 @@ config USB_MUSB_OMAP2PLUS
|
||||
|
||||
config USB_MUSB_AM35X
|
||||
bool "AM35x"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
|
||||
config USB_MUSB_DSPS
|
||||
bool "TI DSPS platforms"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
|
||||
config USB_MUSB_MT85XX
|
||||
bool "Enable Mediatek MT85XX DRC USB controller"
|
||||
|
||||
Reference in New Issue
Block a user