You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
USB: Add MUSB and TUSB support
This patch adds support for MUSB and TUSB controllers integrated into omap2430 and davinci. It also adds support for external tusb6010 controller. Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Tony Lindgren <tony@atomide.com> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f331e40ee8
commit
550a7375fe
@@ -2928,6 +2928,12 @@ M: jirislaby@gmail.com
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
|
||||
P: Felipe Balbi
|
||||
M: felipe.balbi@nokia.com
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
|
||||
P: Andrew Gallatin
|
||||
M: gallatin@myri.com
|
||||
|
||||
@@ -57,6 +57,7 @@ obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/
|
||||
obj-$(CONFIG_PARIDE) += block/paride/
|
||||
obj-$(CONFIG_TC) += tc/
|
||||
obj-$(CONFIG_USB) += usb/
|
||||
obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/
|
||||
obj-$(CONFIG_PCI) += usb/
|
||||
obj-$(CONFIG_USB_GADGET) += usb/gadget/
|
||||
obj-$(CONFIG_SERIO) += input/serio/
|
||||
|
||||
@@ -99,6 +99,8 @@ source "drivers/usb/mon/Kconfig"
|
||||
|
||||
source "drivers/usb/host/Kconfig"
|
||||
|
||||
source "drivers/usb/musb/Kconfig"
|
||||
|
||||
source "drivers/usb/class/Kconfig"
|
||||
|
||||
source "drivers/usb/storage/Kconfig"
|
||||
|
||||
@@ -284,6 +284,16 @@ config USB_LH7A40X
|
||||
default USB_GADGET
|
||||
select USB_GADGET_SELECTED
|
||||
|
||||
# built in ../musb along with host support
|
||||
config USB_GADGET_MUSB_HDRC
|
||||
boolean "Inventra HDRC USB Peripheral (TI, ...)"
|
||||
depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
|
||||
select USB_GADGET_DUALSPEED
|
||||
select USB_GADGET_SELECTED
|
||||
help
|
||||
This OTG-capable silicon IP is used in dual designs including
|
||||
the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
|
||||
|
||||
config USB_GADGET_OMAP
|
||||
boolean "OMAP USB Device Controller"
|
||||
depends on ARCH_OMAP
|
||||
|
||||
176
drivers/usb/musb/Kconfig
Normal file
176
drivers/usb/musb/Kconfig
Normal file
@@ -0,0 +1,176 @@
|
||||
#
|
||||
# USB Dual Role (OTG-ready) Controller Drivers
|
||||
# for silicon based on Mentor Graphics INVENTRA designs
|
||||
#
|
||||
|
||||
comment "Enable Host or Gadget support to see Inventra options"
|
||||
depends on !USB && USB_GADGET=n
|
||||
|
||||
# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
|
||||
config USB_MUSB_HDRC
|
||||
depends on (USB || USB_GADGET) && HAVE_CLK
|
||||
select TWL4030_USB if MACH_OMAP_3430SDP
|
||||
tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
|
||||
help
|
||||
Say Y here if your system has a dual role high speed USB
|
||||
controller based on the Mentor Graphics silicon IP. Then
|
||||
configure options to match your silicon and the board
|
||||
it's being used with, including the USB peripheral role,
|
||||
or the USB host role, or both.
|
||||
|
||||
Texas Instruments parts using this IP include DaVinci 644x,
|
||||
OMAP 243x, OMAP 343x, and TUSB 6010.
|
||||
|
||||
If you do not know what this is, please say N.
|
||||
|
||||
To compile this driver as a module, choose M here; the
|
||||
module will be called "musb_hdrc".
|
||||
|
||||
config USB_MUSB_SOC
|
||||
boolean
|
||||
depends on USB_MUSB_HDRC
|
||||
default y if ARCH_DAVINCI
|
||||
default y if ARCH_OMAP2430
|
||||
default y if ARCH_OMAP34XX
|
||||
help
|
||||
Use a static <asm/arch/hdrc_cnf.h> file to describe how the
|
||||
controller is configured (endpoints, mechanisms, etc) on the
|
||||
current iteration of a given system-on-chip.
|
||||
|
||||
comment "DaVinci 644x USB support"
|
||||
depends on USB_MUSB_HDRC && ARCH_DAVINCI
|
||||
|
||||
comment "OMAP 243x high speed USB support"
|
||||
depends on USB_MUSB_HDRC && ARCH_OMAP2430
|
||||
|
||||
comment "OMAP 343x high speed USB support"
|
||||
depends on USB_MUSB_HDRC && ARCH_OMAP34XX
|
||||
|
||||
config USB_TUSB6010
|
||||
boolean "TUSB 6010 support"
|
||||
depends on USB_MUSB_HDRC && !USB_MUSB_SOC
|
||||
default y
|
||||
help
|
||||
The TUSB 6010 chip, from Texas Instruments, connects a discrete
|
||||
HDRC core using a 16-bit parallel bus (NOR flash style) or VLYNQ
|
||||
(a high speed serial link). It can use system-specific external
|
||||
DMA controllers.
|
||||
|
||||
choice
|
||||
prompt "Driver Mode"
|
||||
depends on USB_MUSB_HDRC
|
||||
help
|
||||
Dual-Role devices can support both host and peripheral roles,
|
||||
as well as a the special "OTG Device" role which can switch
|
||||
between both roles as needed.
|
||||
|
||||
# use USB_MUSB_HDRC_HCD not USB_MUSB_HOST to #ifdef host side support;
|
||||
# OTG needs both roles, not just USB_MUSB_HOST.
|
||||
config USB_MUSB_HOST
|
||||
depends on USB
|
||||
bool "USB Host"
|
||||
help
|
||||
Say Y here if your system supports the USB host role.
|
||||
If it has a USB "A" (rectangular), "Mini-A" (uncommon),
|
||||
or "Mini-AB" connector, it supports the host role.
|
||||
(With a "Mini-AB" connector, you should enable USB OTG.)
|
||||
|
||||
# use USB_GADGET_MUSB_HDRC not USB_MUSB_PERIPHERAL to #ifdef peripheral
|
||||
# side support ... OTG needs both roles
|
||||
config USB_MUSB_PERIPHERAL
|
||||
depends on USB_GADGET
|
||||
bool "USB Peripheral (gadget stack)"
|
||||
select USB_GADGET_MUSB_HDRC
|
||||
help
|
||||
Say Y here if your system supports the USB peripheral role.
|
||||
If it has a USB "B" (squarish), "Mini-B", or "Mini-AB"
|
||||
connector, it supports the peripheral role.
|
||||
(With a "Mini-AB" connector, you should enable USB OTG.)
|
||||
|
||||
config USB_MUSB_OTG
|
||||
depends on USB && USB_GADGET && PM && EXPERIMENTAL
|
||||
bool "Both host and peripheral: USB OTG (On The Go) Device"
|
||||
select USB_GADGET_MUSB_HDRC
|
||||
select USB_OTG
|
||||
help
|
||||
The most notable feature of USB OTG is support for a
|
||||
"Dual-Role" device, which can act as either a device
|
||||
or a host. The initial role choice can be changed
|
||||
later, when two dual-role devices talk to each other.
|
||||
|
||||
At this writing, the OTG support in this driver is incomplete,
|
||||
omitting the mandatory HNP or SRP protocols. However, some
|
||||
of the cable based role switching works. (That is, grounding
|
||||
the ID pin switches the controller to host mode, while leaving
|
||||
it floating leaves it in peripheral mode.)
|
||||
|
||||
Select this if your system has a Mini-AB connector, or
|
||||
to simplify certain kinds of configuration.
|
||||
|
||||
To implement your OTG Targeted Peripherals List (TPL), enable
|
||||
USB_OTG_WHITELIST and update "drivers/usb/core/otg_whitelist.h"
|
||||
to match your requirements.
|
||||
|
||||
endchoice
|
||||
|
||||
# enable peripheral support (including with OTG)
|
||||
config USB_GADGET_MUSB_HDRC
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
|
||||
# default y
|
||||
# select USB_GADGET_DUALSPEED
|
||||
# select USB_GADGET_SELECTED
|
||||
|
||||
# enables host support (including with OTG)
|
||||
config USB_MUSB_HDRC_HCD
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && (USB_MUSB_HOST || USB_MUSB_OTG)
|
||||
select USB_OTG if USB_GADGET_MUSB_HDRC
|
||||
default y
|
||||
|
||||
|
||||
config MUSB_PIO_ONLY
|
||||
bool 'Disable DMA (always use PIO)'
|
||||
depends on USB_MUSB_HDRC
|
||||
default y if USB_TUSB6010
|
||||
help
|
||||
All data is copied between memory and FIFO by the CPU.
|
||||
DMA controllers are ignored.
|
||||
|
||||
Do not select 'n' here unless DMA support for your SOC or board
|
||||
is unavailable (or unstable). When DMA is enabled at compile time,
|
||||
you can still disable it at run time using the "use_dma=n" module
|
||||
parameter.
|
||||
|
||||
config USB_INVENTRA_DMA
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
||||
default ARCH_OMAP2430 || ARCH_OMAP34XX
|
||||
help
|
||||
Enable DMA transfers using Mentor's engine.
|
||||
|
||||
config USB_TI_CPPI_DMA
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
||||
default ARCH_DAVINCI
|
||||
help
|
||||
Enable DMA transfers when TI CPPI DMA is available.
|
||||
|
||||
config USB_TUSB_OMAP_DMA
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
||||
depends on USB_TUSB6010
|
||||
depends on ARCH_OMAP
|
||||
default y
|
||||
help
|
||||
Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
|
||||
|
||||
config USB_MUSB_LOGLEVEL
|
||||
depends on USB_MUSB_HDRC
|
||||
int 'Logging Level (0 - none / 3 - annoying / ... )'
|
||||
default 0
|
||||
help
|
||||
Set the logging level. 0 disables the debugging altogether,
|
||||
although when USB_DEBUG is set the value is at least 1.
|
||||
Starting at level 3, per-transfer (urb, usb_request, packet,
|
||||
or dma transfer) tracing may kick in.
|
||||
86
drivers/usb/musb/Makefile
Normal file
86
drivers/usb/musb/Makefile
Normal file
@@ -0,0 +1,86 @@
|
||||
#
|
||||
# for USB OTG silicon based on Mentor Graphics INVENTRA designs
|
||||
#
|
||||
|
||||
musb_hdrc-objs := musb_core.o
|
||||
|
||||
obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o
|
||||
|
||||
ifeq ($(CONFIG_ARCH_DAVINCI),y)
|
||||
musb_hdrc-objs += davinci.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USB_TUSB6010),y)
|
||||
musb_hdrc-objs += tusb6010.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_OMAP2430),y)
|
||||
musb_hdrc-objs += omap2430.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_OMAP3430),y)
|
||||
musb_hdrc-objs += omap2430.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
|
||||
musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USB_MUSB_HDRC_HCD),y)
|
||||
musb_hdrc-objs += musb_virthub.o musb_host.o
|
||||
endif
|
||||
|
||||
# the kconfig must guarantee that only one of the
|
||||
# possible I/O schemes will be enabled at a time ...
|
||||
# PIO only, or DMA (several potential schemes).
|
||||
# though PIO is always there to back up DMA, and for ep0
|
||||
|
||||
ifneq ($(CONFIG_MUSB_PIO_ONLY),y)
|
||||
|
||||
ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
|
||||
musb_hdrc-objs += musbhsdma.o
|
||||
|
||||
else
|
||||
ifeq ($(CONFIG_USB_TI_CPPI_DMA),y)
|
||||
musb_hdrc-objs += cppi_dma.o
|
||||
|
||||
else
|
||||
ifeq ($(CONFIG_USB_TUSB_OMAP_DMA),y)
|
||||
musb_hdrc-objs += tusb6010_omap.o
|
||||
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
# FIXME remove all these extra "-DMUSB_* things, stick to CONFIG_*
|
||||
|
||||
ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y)
|
||||
EXTRA_CFLAGS += -DMUSB_AHB_ID
|
||||
endif
|
||||
|
||||
# Debugging
|
||||
|
||||
MUSB_DEBUG:=$(CONFIG_USB_MUSB_LOGLEVEL)
|
||||
|
||||
ifeq ("$(strip $(MUSB_DEBUG))","")
|
||||
ifdef CONFIG_USB_DEBUG
|
||||
MUSB_DEBUG:=1
|
||||
else
|
||||
MUSB_DEBUG:=0
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(MUSB_DEBUG),0)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
|
||||
ifeq ($(CONFIG_PROC_FS),y)
|
||||
musb_hdrc-objs += musb_procfs.o
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
|
||||
1540
drivers/usb/musb/cppi_dma.c
Normal file
1540
drivers/usb/musb/cppi_dma.c
Normal file
File diff suppressed because it is too large
Load Diff
133
drivers/usb/musb/cppi_dma.h
Normal file
133
drivers/usb/musb/cppi_dma.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* Copyright (C) 2005-2006 by Texas Instruments */
|
||||
|
||||
#ifndef _CPPI_DMA_H_
|
||||
#define _CPPI_DMA_H_
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/dmapool.h>
|
||||
|
||||
#include "musb_dma.h"
|
||||
#include "musb_core.h"
|
||||
|
||||
|
||||
/* FIXME fully isolate CPPI from DaVinci ... the "CPPI generic" registers
|
||||
* would seem to be shared with the TUSB6020 (over VLYNQ).
|
||||
*/
|
||||
|
||||
#include "davinci.h"
|
||||
|
||||
|
||||
/* CPPI RX/TX state RAM */
|
||||
|
||||
struct cppi_tx_stateram {
|
||||
u32 tx_head; /* "DMA packet" head descriptor */
|
||||
u32 tx_buf;
|
||||
u32 tx_current; /* current descriptor */
|
||||
u32 tx_buf_current;
|
||||
u32 tx_info; /* flags, remaining buflen */
|
||||
u32 tx_rem_len;
|
||||
u32 tx_dummy; /* unused */
|
||||
u32 tx_complete;
|
||||
};
|
||||
|
||||
struct cppi_rx_stateram {
|
||||
u32 rx_skipbytes;
|
||||
u32 rx_head;
|
||||
u32 rx_sop; /* "DMA packet" head descriptor */
|
||||
u32 rx_current; /* current descriptor */
|
||||
u32 rx_buf_current;
|
||||
u32 rx_len_len;
|
||||
u32 rx_cnt_cnt;
|
||||
u32 rx_complete;
|
||||
};
|
||||
|
||||
/* hw_options bits in CPPI buffer descriptors */
|
||||
#define CPPI_SOP_SET ((u32)(1 << 31))
|
||||
#define CPPI_EOP_SET ((u32)(1 << 30))
|
||||
#define CPPI_OWN_SET ((u32)(1 << 29)) /* owned by cppi */
|
||||
#define CPPI_EOQ_MASK ((u32)(1 << 28))
|
||||
#define CPPI_ZERO_SET ((u32)(1 << 23)) /* rx saw zlp; tx issues one */
|
||||
#define CPPI_RXABT_MASK ((u32)(1 << 19)) /* need more rx buffers */
|
||||
|
||||
#define CPPI_RECV_PKTLEN_MASK 0xFFFF
|
||||
#define CPPI_BUFFER_LEN_MASK 0xFFFF
|
||||
|
||||
#define CPPI_TEAR_READY ((u32)(1 << 31))
|
||||
|
||||
/* CPPI data structure definitions */
|
||||
|
||||
#define CPPI_DESCRIPTOR_ALIGN 16 /* bytes; 5-dec docs say 4-byte align */
|
||||
|
||||
struct cppi_descriptor {
|
||||
/* hardware overlay */
|
||||
u32 hw_next; /* next buffer descriptor Pointer */
|
||||
u32 hw_bufp; /* i/o buffer pointer */
|
||||
u32 hw_off_len; /* buffer_offset16, buffer_length16 */
|
||||
u32 hw_options; /* flags: SOP, EOP etc*/
|
||||
|
||||
struct cppi_descriptor *next;
|
||||
dma_addr_t dma; /* address of this descriptor */
|
||||
u32 buflen; /* for RX: original buffer length */
|
||||
} __attribute__ ((aligned(CPPI_DESCRIPTOR_ALIGN)));
|
||||
|
||||
|
||||
struct cppi;
|
||||
|
||||
/* CPPI Channel Control structure */
|
||||
struct cppi_channel {
|
||||
struct dma_channel channel;
|
||||
|
||||
/* back pointer to the DMA controller structure */
|
||||
struct cppi *controller;
|
||||
|
||||
/* which direction of which endpoint? */
|
||||
struct musb_hw_ep *hw_ep;
|
||||
bool transmit;
|
||||
u8 index;
|
||||
|
||||
/* DMA modes: RNDIS or "transparent" */
|
||||
u8 is_rndis;
|
||||
|
||||
/* book keeping for current transfer request */
|
||||
dma_addr_t buf_dma;
|
||||
u32 buf_len;
|
||||
u32 maxpacket;
|
||||
u32 offset; /* dma requested */
|
||||
|
||||
void __iomem *state_ram; /* CPPI state */
|
||||
|
||||
struct cppi_descriptor *freelist;
|
||||
|
||||
/* BD management fields */
|
||||
struct cppi_descriptor *head;
|
||||
struct cppi_descriptor *tail;
|
||||
struct cppi_descriptor *last_processed;
|
||||
|
||||
/* use tx_complete in host role to track endpoints waiting for
|
||||
* FIFONOTEMPTY to clear.
|
||||
*/
|
||||
struct list_head tx_complete;
|
||||
};
|
||||
|
||||
/* CPPI DMA controller object */
|
||||
struct cppi {
|
||||
struct dma_controller controller;
|
||||
struct musb *musb;
|
||||
void __iomem *mregs; /* Mentor regs */
|
||||
void __iomem *tibase; /* TI/CPPI regs */
|
||||
|
||||
struct cppi_channel tx[MUSB_C_NUM_EPT - 1];
|
||||
struct cppi_channel rx[MUSB_C_NUM_EPR - 1];
|
||||
|
||||
struct dma_pool *pool;
|
||||
|
||||
struct list_head tx_complete;
|
||||
};
|
||||
|
||||
/* irq handling hook */
|
||||
extern void cppi_completion(struct musb *, u32 rx, u32 tx);
|
||||
|
||||
#endif /* end of ifndef _CPPI_DMA_H_ */
|
||||
462
drivers/usb/musb/davinci.c
Normal file
462
drivers/usb/musb/davinci.c
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2006 by Texas Instruments
|
||||
*
|
||||
* This file is part of the Inventra Controller Driver for Linux.
|
||||
*
|
||||
* The Inventra Controller Driver for Linux is free software; you
|
||||
* can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License version 2 as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* The Inventra Controller Driver for Linux is distributed in
|
||||
* the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with The Inventra Controller Driver for Linux ; if not,
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place,
|
||||
* Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/memory.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "musb_core.h"
|
||||
|
||||
#ifdef CONFIG_MACH_DAVINCI_EVM
|
||||
#include <asm/arch/i2c-client.h>
|
||||
#endif
|
||||
|
||||
#include "davinci.h"
|
||||
#include "cppi_dma.h"
|
||||
|
||||
|
||||
/* REVISIT (PM) we should be able to keep the PHY in low power mode most
|
||||
* of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
|
||||
* and, when in host mode, autosuspending idle root ports... PHYPLLON
|
||||
* (overriding SUSPENDM?) then likely needs to stay off.
|
||||
*/
|
||||
|
||||
static inline void phy_on(void)
|
||||
{
|
||||
/* start the on-chip PHY and its PLL */
|
||||
__raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON,
|
||||
(void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR));
|
||||
while ((__raw_readl((void __force __iomem *)
|
||||
IO_ADDRESS(USBPHY_CTL_PADDR))
|
||||
& USBPHY_PHYCLKGD) == 0)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static inline void phy_off(void)
|
||||
{
|
||||
/* powerdown the on-chip PHY and its oscillator */
|
||||
__raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *)
|
||||
IO_ADDRESS(USBPHY_CTL_PADDR));
|
||||
}
|
||||
|
||||
static int dma_off = 1;
|
||||
|
||||
void musb_platform_enable(struct musb *musb)
|
||||
{
|
||||
u32 tmp, old, val;
|
||||
|
||||
/* workaround: setup irqs through both register sets */
|
||||
tmp = (musb->epmask & DAVINCI_USB_TX_ENDPTS_MASK)
|
||||
<< DAVINCI_USB_TXINT_SHIFT;
|
||||
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
|
||||
old = tmp;
|
||||
tmp = (musb->epmask & (0xfffe & DAVINCI_USB_RX_ENDPTS_MASK))
|
||||
<< DAVINCI_USB_RXINT_SHIFT;
|
||||
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
|
||||
tmp |= old;
|
||||
|
||||
val = ~MUSB_INTR_SOF;
|
||||
tmp |= ((val & 0x01ff) << DAVINCI_USB_USBINT_SHIFT);
|
||||
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
|
||||
|
||||
if (is_dma_capable() && !dma_off)
|
||||
printk(KERN_WARNING "%s %s: dma not reactivated\n",
|
||||
__FILE__, __func__);
|
||||
else
|
||||
dma_off = 0;
|
||||
|
||||
/* force a DRVVBUS irq so we can start polling for ID change */
|
||||
if (is_otg_enabled(musb))
|
||||
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
|
||||
DAVINCI_INTR_DRVVBUS << DAVINCI_USB_USBINT_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the HDRC and flush interrupts
|
||||
*/
|
||||
void musb_platform_disable(struct musb *musb)
|
||||
{
|
||||
/* because we don't set CTRLR.UINT, "important" to:
|
||||
* - not read/write INTRUSB/INTRUSBE
|
||||
* - (except during initial setup, as workaround)
|
||||
* - use INTSETR/INTCLRR instead
|
||||
*/
|
||||
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_CLR_REG,
|
||||
DAVINCI_USB_USBINT_MASK
|
||||
| DAVINCI_USB_TXINT_MASK
|
||||
| DAVINCI_USB_RXINT_MASK);
|
||||
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
|
||||
musb_writel(musb->ctrl_base, DAVINCI_USB_EOI_REG, 0);
|
||||
|
||||
if (is_dma_capable() && !dma_off)
|
||||
WARNING("dma still active\n");
|
||||
}
|
||||
|
||||
|
||||
/* REVISIT it's not clear whether DaVinci can support full OTG. */
|
||||
|
||||
static int vbus_state = -1;
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_HDRC_HCD
|
||||
#define portstate(stmt) stmt
|
||||
#else
|
||||
#define portstate(stmt)
|
||||
#endif
|
||||
|
||||
|
||||
/* VBUS SWITCHING IS BOARD-SPECIFIC */
|
||||
|
||||
#ifdef CONFIG_MACH_DAVINCI_EVM
|
||||
#ifndef CONFIG_MACH_DAVINCI_EVM_OTG
|
||||
|
||||
/* I2C operations are always synchronous, and require a task context.
|
||||
* With unloaded systems, using the shared workqueue seems to suffice
|
||||
* to satisfy the 100msec A_WAIT_VRISE timeout...
|
||||
*/
|
||||
static void evm_deferred_drvvbus(struct work_struct *ignored)
|
||||
{
|
||||
davinci_i2c_expander_op(0x3a, USB_DRVVBUS, vbus_state);
|
||||
vbus_state = !vbus_state;
|
||||
}
|
||||
static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
|
||||
|
||||
#endif /* modified board */
|
||||
#endif /* EVM */
|
||||
|
||||
static void davinci_source_power(struct musb *musb, int is_on, int immediate)
|
||||
{
|
||||
if (is_on)
|
||||
is_on = 1;
|
||||
|
||||
if (vbus_state == is_on)
|
||||
return;
|
||||
vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */
|
||||
|
||||
#ifdef CONFIG_MACH_DAVINCI_EVM
|
||||
if (machine_is_davinci_evm()) {
|
||||
#ifdef CONFIG_MACH_DAVINCI_EVM_OTG
|
||||
/* modified EVM board switching VBUS with GPIO(6) not I2C
|
||||
* NOTE: PINMUX0.RGB888 (bit23) must be clear
|
||||
*/
|
||||
if (is_on)
|
||||
gpio_set(GPIO(6));
|
||||
else
|
||||
gpio_clear(GPIO(6));
|
||||
immediate = 1;
|
||||
#else
|
||||
if (immediate)
|
||||
davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
|
||||
else
|
||||
schedule_work(&evm_vbus_work);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (immediate)
|
||||
vbus_state = is_on;
|
||||
}
|
||||
|
||||
static void davinci_set_vbus(struct musb *musb, int is_on)
|
||||
{
|
||||
WARN_ON(is_on && is_peripheral_active(musb));
|
||||
davinci_source_power(musb, is_on, 0);
|
||||
}
|
||||
|
||||
|
||||
#define POLL_SECONDS 2
|
||||
|
||||
static struct timer_list otg_workaround;
|
||||
|
||||
static void otg_timer(unsigned long _musb)
|
||||
{
|
||||
struct musb *musb = (void *)_musb;
|
||||
void __iomem *mregs = musb->mregs;
|
||||
u8 devctl;
|
||||
unsigned long flags;
|
||||
|
||||
/* We poll because DaVinci's won't expose several OTG-critical
|
||||
* status change events (from the transceiver) otherwise.
|
||||
*/
|
||||
devctl = musb_readb(mregs, MUSB_DEVCTL);
|
||||
DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb));
|
||||
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
switch (musb->xceiv.state) {
|
||||
case OTG_STATE_A_WAIT_VFALL:
|
||||
/* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
|
||||
* seems to mis-handle session "start" otherwise (or in our
|
||||
* case "recover"), in routine "VBUS was valid by the time
|
||||
* VBUSERR got reported during enumeration" cases.
|
||||
*/
|
||||
if (devctl & MUSB_DEVCTL_VBUS) {
|
||||
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
|
||||
break;
|
||||
}
|
||||
musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
|
||||
musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
|
||||
MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT);
|
||||
break;
|
||||
case OTG_STATE_B_IDLE:
|
||||
if (!is_peripheral_enabled(musb))
|
||||
break;
|
||||
|
||||
/* There's no ID-changed IRQ, so we have no good way to tell
|
||||
* when to switch to the A-Default state machine (by setting
|
||||
* the DEVCTL.SESSION flag).
|
||||
*
|
||||
* Workaround: whenever we're in B_IDLE, try setting the
|
||||
* session flag every few seconds. If it works, ID was
|
||||
* grounded and we're now in the A-Default state machine.
|
||||
*
|
||||
* NOTE setting the session flag is _supposed_ to trigger
|
||||
* SRP, but clearly it doesn't.
|
||||
*/
|
||||
musb_writeb(mregs, MUSB_DEVCTL,
|
||||
devctl | MUSB_DEVCTL_SESSION);
|
||||
devctl = musb_readb(mregs, MUSB_DEVCTL);
|
||||
if (devctl & MUSB_DEVCTL_BDEVICE)
|
||||
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
|
||||
else
|
||||
musb->xceiv.state = OTG_STATE_A_IDLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
}
|
||||
|
||||
static irqreturn_t davinci_interrupt(int irq, void *__hci)
|
||||
{
|
||||
unsigned long flags;
|
||||
irqreturn_t retval = IRQ_NONE;
|
||||
struct musb *musb = __hci;
|
||||
void __iomem *tibase = musb->ctrl_base;
|
||||
u32 tmp;
|
||||
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
|
||||
/* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through
|
||||
* the Mentor registers (except for setup), use the TI ones and EOI.
|
||||
*
|
||||
* Docs describe irq "vector" registers asociated with the CPPI and
|
||||
* USB EOI registers. These hold a bitmask corresponding to the
|
||||
* current IRQ, not an irq handler address. Would using those bits
|
||||
* resolve some of the races observed in this dispatch code??
|
||||
*/
|
||||
|
||||
/* CPPI interrupts share the same IRQ line, but have their own
|
||||
* mask, state, "vector", and EOI registers.
|
||||
*/
|
||||
if (is_cppi_enabled()) {
|
||||
u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
|
||||
u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);
|
||||
|
||||
if (cppi_tx || cppi_rx) {
|
||||
DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx);
|
||||
cppi_completion(musb, cppi_rx, cppi_tx);
|
||||
retval = IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* ack and handle non-CPPI interrupts */
|
||||
tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG);
|
||||
musb_writel(tibase, DAVINCI_USB_INT_SRC_CLR_REG, tmp);
|
||||
DBG(4, "IRQ %08x\n", tmp);
|
||||
|
||||
musb->int_rx = (tmp & DAVINCI_USB_RXINT_MASK)
|
||||
>> DAVINCI_USB_RXINT_SHIFT;
|
||||
musb->int_tx = (tmp & DAVINCI_USB_TXINT_MASK)
|
||||
>> DAVINCI_USB_TXINT_SHIFT;
|
||||
musb->int_usb = (tmp & DAVINCI_USB_USBINT_MASK)
|
||||
>> DAVINCI_USB_USBINT_SHIFT;
|
||||
|
||||
/* DRVVBUS irqs are the only proxy we have (a very poor one!) for
|
||||
* DaVinci's missing ID change IRQ. We need an ID change IRQ to
|
||||
* switch appropriately between halves of the OTG state machine.
|
||||
* Managing DEVCTL.SESSION per Mentor docs requires we know its
|
||||
* value, but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
|
||||
* Also, DRVVBUS pulses for SRP (but not at 5V) ...
|
||||
*/
|
||||
if (tmp & (DAVINCI_INTR_DRVVBUS << DAVINCI_USB_USBINT_SHIFT)) {
|
||||
int drvvbus = musb_readl(tibase, DAVINCI_USB_STAT_REG);
|
||||
void __iomem *mregs = musb->mregs;
|
||||
u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
|
||||
int err = musb->int_usb & MUSB_INTR_VBUSERROR;
|
||||
|
||||
err = is_host_enabled(musb)
|
||||
&& (musb->int_usb & MUSB_INTR_VBUSERROR);
|
||||
if (err) {
|
||||
/* The Mentor core doesn't debounce VBUS as needed
|
||||
* to cope with device connect current spikes. This
|
||||
* means it's not uncommon for bus-powered devices
|
||||
* to get VBUS errors during enumeration.
|
||||
*
|
||||
* This is a workaround, but newer RTL from Mentor
|
||||
* seems to allow a better one: "re"starting sessions
|
||||
* without waiting (on EVM, a **long** time) for VBUS
|
||||
* to stop registering in devctl.
|
||||
*/
|
||||
musb->int_usb &= ~MUSB_INTR_VBUSERROR;
|
||||
musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
|
||||
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
|
||||
WARNING("VBUS error workaround (delay coming)\n");
|
||||
} else if (is_host_enabled(musb) && drvvbus) {
|
||||
musb->is_active = 1;
|
||||
MUSB_HST_MODE(musb);
|
||||
musb->xceiv.default_a = 1;
|
||||
musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
|
||||
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
|
||||
del_timer(&otg_workaround);
|
||||
} else {
|
||||
musb->is_active = 0;
|
||||
MUSB_DEV_MODE(musb);
|
||||
musb->xceiv.default_a = 0;
|
||||
musb->xceiv.state = OTG_STATE_B_IDLE;
|
||||
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
|
||||
}
|
||||
|
||||
/* NOTE: this must complete poweron within 100 msec */
|
||||
davinci_source_power(musb, drvvbus, 0);
|
||||
DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
|
||||
drvvbus ? "on" : "off",
|
||||
otg_state_string(musb),
|
||||
err ? " ERROR" : "",
|
||||
devctl);
|
||||
retval = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (musb->int_tx || musb->int_rx || musb->int_usb)
|
||||
retval |= musb_interrupt(musb);
|
||||
|
||||
/* irq stays asserted until EOI is written */
|
||||
musb_writel(tibase, DAVINCI_USB_EOI_REG, 0);
|
||||
|
||||
/* poll for ID change */
|
||||
if (is_otg_enabled(musb)
|
||||
&& musb->xceiv.state == OTG_STATE_B_IDLE)
|
||||
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
|
||||
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
|
||||
/* REVISIT we sometimes get unhandled IRQs
|
||||
* (e.g. ep0). not clear why...
|
||||
*/
|
||||
if (retval != IRQ_HANDLED)
|
||||
DBG(5, "unhandled? %08x\n", tmp);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int __init musb_platform_init(struct musb *musb)
|
||||
{
|
||||
void __iomem *tibase = musb->ctrl_base;
|
||||
u32 revision;
|
||||
|
||||
musb->mregs += DAVINCI_BASE_OFFSET;
|
||||
#if 0
|
||||
/* REVISIT there's something odd about clocking, this
|
||||
* didn't appear do the job ...
|
||||
*/
|
||||
musb->clock = clk_get(pDevice, "usb");
|
||||
if (IS_ERR(musb->clock))
|
||||
return PTR_ERR(musb->clock);
|
||||
|
||||
status = clk_enable(musb->clock);
|
||||
if (status < 0)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
/* returns zero if e.g. not clocked */
|
||||
revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
|
||||
if (revision == 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (is_host_enabled(musb))
|
||||
setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
|
||||
|
||||
musb->board_set_vbus = davinci_set_vbus;
|
||||
davinci_source_power(musb, 0, 1);
|
||||
|
||||
/* reset the controller */
|
||||
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
|
||||
|
||||
/* start the on-chip PHY and its PLL */
|
||||
phy_on();
|
||||
|
||||
msleep(5);
|
||||
|
||||
/* NOTE: irqs are in mixed mode, not bypass to pure-musb */
|
||||
pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
|
||||
revision, __raw_readl((void __force __iomem *)
|
||||
IO_ADDRESS(USBPHY_CTL_PADDR)),
|
||||
musb_readb(tibase, DAVINCI_USB_CTRL_REG));
|
||||
|
||||
musb->isr = davinci_interrupt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int musb_platform_exit(struct musb *musb)
|
||||
{
|
||||
if (is_host_enabled(musb))
|
||||
del_timer_sync(&otg_workaround);
|
||||
|
||||
davinci_source_power(musb, 0 /*off*/, 1);
|
||||
|
||||
/* delay, to avoid problems with module reload */
|
||||
if (is_host_enabled(musb) && musb->xceiv.default_a) {
|
||||
int maxdelay = 30;
|
||||
u8 devctl, warn = 0;
|
||||
|
||||
/* if there's no peripheral connected, this can take a
|
||||
* long time to fall, especially on EVM with huge C133.
|
||||
*/
|
||||
do {
|
||||
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
||||
if (!(devctl & MUSB_DEVCTL_VBUS))
|
||||
break;
|
||||
if ((devctl & MUSB_DEVCTL_VBUS) != warn) {
|
||||
warn = devctl & MUSB_DEVCTL_VBUS;
|
||||
DBG(1, "VBUS %d\n",
|
||||
warn >> MUSB_DEVCTL_VBUS_SHIFT);
|
||||
}
|
||||
msleep(1000);
|
||||
maxdelay--;
|
||||
} while (maxdelay > 0);
|
||||
|
||||
/* in OTG mode, another host might be connected */
|
||||
if (devctl & MUSB_DEVCTL_VBUS)
|
||||
DBG(1, "VBUS off timeout (devctl %02x)\n", devctl);
|
||||
}
|
||||
|
||||
phy_off();
|
||||
return 0;
|
||||
}
|
||||
100
drivers/usb/musb/davinci.h
Normal file
100
drivers/usb/musb/davinci.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2006 by Texas Instruments
|
||||
*
|
||||
* The Inventra Controller Driver for Linux is free software; you
|
||||
* can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License version 2 as published by the Free Software
|
||||
* Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __MUSB_HDRDF_H__
|
||||
#define __MUSB_HDRDF_H__
|
||||
|
||||
/*
|
||||
* DaVinci-specific definitions
|
||||
*/
|
||||
|
||||
/* Integrated highspeed/otg PHY */
|
||||
#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
|
||||
#define USBPHY_PHYCLKGD (1 << 8)
|
||||
#define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */
|
||||
#define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */
|
||||
#define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */
|
||||
#define USBPHY_CLKO1SEL (1 << 3)
|
||||
#define USBPHY_OSCPDWN (1 << 2)
|
||||
#define USBPHY_PHYPDWN (1 << 0)
|
||||
|
||||
/* For now include usb OTG module registers here */
|
||||
#define DAVINCI_USB_VERSION_REG 0x00
|
||||
#define DAVINCI_USB_CTRL_REG 0x04
|
||||
#define DAVINCI_USB_STAT_REG 0x08
|
||||
#define DAVINCI_RNDIS_REG 0x10
|
||||
#define DAVINCI_AUTOREQ_REG 0x14
|
||||
#define DAVINCI_USB_INT_SOURCE_REG 0x20
|
||||
#define DAVINCI_USB_INT_SET_REG 0x24
|
||||
#define DAVINCI_USB_INT_SRC_CLR_REG 0x28
|
||||
#define DAVINCI_USB_INT_MASK_REG 0x2c
|
||||
#define DAVINCI_USB_INT_MASK_SET_REG 0x30
|
||||
#define DAVINCI_USB_INT_MASK_CLR_REG 0x34
|
||||
#define DAVINCI_USB_INT_SRC_MASKED_REG 0x38
|
||||
#define DAVINCI_USB_EOI_REG 0x3c
|
||||
#define DAVINCI_USB_EOI_INTVEC 0x40
|
||||
|
||||
/* BEGIN CPPI-generic (?) */
|
||||
|
||||
/* CPPI related registers */
|
||||
#define DAVINCI_TXCPPI_CTRL_REG 0x80
|
||||
#define DAVINCI_TXCPPI_TEAR_REG 0x84
|
||||
#define DAVINCI_CPPI_EOI_REG 0x88
|
||||
#define DAVINCI_CPPI_INTVEC_REG 0x8c
|
||||
#define DAVINCI_TXCPPI_MASKED_REG 0x90
|
||||
#define DAVINCI_TXCPPI_RAW_REG 0x94
|
||||
#define DAVINCI_TXCPPI_INTENAB_REG 0x98
|
||||
#define DAVINCI_TXCPPI_INTCLR_REG 0x9c
|
||||
|
||||
#define DAVINCI_RXCPPI_CTRL_REG 0xC0
|
||||
#define DAVINCI_RXCPPI_MASKED_REG 0xD0
|
||||
#define DAVINCI_RXCPPI_RAW_REG 0xD4
|
||||
#define DAVINCI_RXCPPI_INTENAB_REG 0xD8
|
||||
#define DAVINCI_RXCPPI_INTCLR_REG 0xDC
|
||||
|
||||
#define DAVINCI_RXCPPI_BUFCNT0_REG 0xE0
|
||||
#define DAVINCI_RXCPPI_BUFCNT1_REG 0xE4
|
||||
#define DAVINCI_RXCPPI_BUFCNT2_REG 0xE8
|
||||
#define DAVINCI_RXCPPI_BUFCNT3_REG 0xEC
|
||||
|
||||
/* CPPI state RAM entries */
|
||||
#define DAVINCI_CPPI_STATERAM_BASE_OFFSET 0x100
|
||||
|
||||
#define DAVINCI_TXCPPI_STATERAM_OFFSET(chnum) \
|
||||
(DAVINCI_CPPI_STATERAM_BASE_OFFSET + ((chnum) * 0x40))
|
||||
#define DAVINCI_RXCPPI_STATERAM_OFFSET(chnum) \
|
||||
(DAVINCI_CPPI_STATERAM_BASE_OFFSET + 0x20 + ((chnum) * 0x40))
|
||||
|
||||
/* CPPI masks */
|
||||
#define DAVINCI_DMA_CTRL_ENABLE 1
|
||||
#define DAVINCI_DMA_CTRL_DISABLE 0
|
||||
|
||||
#define DAVINCI_DMA_ALL_CHANNELS_ENABLE 0xF
|
||||
#define DAVINCI_DMA_ALL_CHANNELS_DISABLE 0xF
|
||||
|
||||
/* END CPPI-generic (?) */
|
||||
|
||||
#define DAVINCI_USB_TX_ENDPTS_MASK 0x1f /* ep0 + 4 tx */
|
||||
#define DAVINCI_USB_RX_ENDPTS_MASK 0x1e /* 4 rx */
|
||||
|
||||
#define DAVINCI_USB_USBINT_SHIFT 16
|
||||
#define DAVINCI_USB_TXINT_SHIFT 0
|
||||
#define DAVINCI_USB_RXINT_SHIFT 8
|
||||
|
||||
#define DAVINCI_INTR_DRVVBUS 0x0100
|
||||
|
||||
#define DAVINCI_USB_USBINT_MASK 0x01ff0000 /* 8 Mentor, DRVVBUS */
|
||||
#define DAVINCI_USB_TXINT_MASK \
|
||||
(DAVINCI_USB_TX_ENDPTS_MASK << DAVINCI_USB_TXINT_SHIFT)
|
||||
#define DAVINCI_USB_RXINT_MASK \
|
||||
(DAVINCI_USB_RX_ENDPTS_MASK << DAVINCI_USB_RXINT_SHIFT)
|
||||
|
||||
#define DAVINCI_BASE_OFFSET 0x400
|
||||
|
||||
#endif /* __MUSB_HDRDF_H__ */
|
||||
2266
drivers/usb/musb/musb_core.c
Normal file
2266
drivers/usb/musb/musb_core.c
Normal file
File diff suppressed because it is too large
Load Diff
517
drivers/usb/musb/musb_core.h
Normal file
517
drivers/usb/musb/musb_core.h
Normal file
File diff suppressed because it is too large
Load Diff
66
drivers/usb/musb/musb_debug.h
Normal file
66
drivers/usb/musb/musb_debug.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* MUSB OTG driver debug defines
|
||||
*
|
||||
* Copyright 2005 Mentor Graphics Corporation
|
||||
* Copyright (C) 2005-2006 by Texas Instruments
|
||||
* Copyright (C) 2006-2007 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MUSB_LINUX_DEBUG_H__
|
||||
#define __MUSB_LINUX_DEBUG_H__
|
||||
|
||||
#define yprintk(facility, format, args...) \
|
||||
do { printk(facility "%s %d: " format , \
|
||||
__func__, __LINE__ , ## args); } while (0)
|
||||
#define WARNING(fmt, args...) yprintk(KERN_WARNING, fmt, ## args)
|
||||
#define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args)
|
||||
#define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args)
|
||||
|
||||
#define xprintk(level, facility, format, args...) do { \
|
||||
if (_dbg_level(level)) { \
|
||||
printk(facility "%s %d: " format , \
|
||||
__func__, __LINE__ , ## args); \
|
||||
} } while (0)
|
||||
|
||||
#if MUSB_DEBUG > 0
|
||||
extern unsigned debug;
|
||||
#else
|
||||
#define debug 0
|
||||
#endif
|
||||
|
||||
static inline int _dbg_level(unsigned l)
|
||||
{
|
||||
return debug >= l;
|
||||
}
|
||||
|
||||
#define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args)
|
||||
|
||||
extern const char *otg_state_string(struct musb *);
|
||||
|
||||
#endif /* __MUSB_LINUX_DEBUG_H__ */
|
||||
172
drivers/usb/musb/musb_dma.h
Normal file
172
drivers/usb/musb/musb_dma.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* MUSB OTG driver DMA controller abstraction
|
||||
*
|
||||
* Copyright 2005 Mentor Graphics Corporation
|
||||
* Copyright (C) 2005-2006 by Texas Instruments
|
||||
* Copyright (C) 2006-2007 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MUSB_DMA_H__
|
||||
#define __MUSB_DMA_H__
|
||||
|
||||
struct musb_hw_ep;
|
||||
|
||||
/*
|
||||
* DMA Controller Abstraction
|
||||
*
|
||||
* DMA Controllers are abstracted to allow use of a variety of different
|
||||
* implementations of DMA, as allowed by the Inventra USB cores. On the
|
||||
* host side, usbcore sets up the DMA mappings and flushes caches; on the
|
||||
* peripheral side, the gadget controller driver does. Responsibilities
|
||||
* of a DMA controller driver include:
|
||||
*
|
||||
* - Handling the details of moving multiple USB packets
|
||||
* in cooperation with the Inventra USB core, including especially
|
||||
* the correct RX side treatment of short packets and buffer-full
|
||||
* states (both of which terminate transfers).
|
||||
*
|
||||
* - Knowing the correlation between dma channels and the
|
||||
* Inventra core's local endpoint resources and data direction.
|
||||
*
|
||||
* - Maintaining a list of allocated/available channels.
|
||||
*
|
||||
* - Updating channel status on interrupts,
|
||||
* whether shared with the Inventra core or separate.
|
||||
*/
|
||||
|
||||
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
|
||||
|
||||
#ifndef CONFIG_MUSB_PIO_ONLY
|
||||
#define is_dma_capable() (1)
|
||||
#else
|
||||
#define is_dma_capable() (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_TI_CPPI_DMA
|
||||
#define is_cppi_enabled() 1
|
||||
#else
|
||||
#define is_cppi_enabled() 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_TUSB_OMAP_DMA
|
||||
#define tusb_dma_omap() 1
|
||||
#else
|
||||
#define tusb_dma_omap() 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DMA channel status ... updated by the dma controller driver whenever that
|
||||
* status changes, and protected by the overall controller spinlock.
|
||||
*/
|
||||
enum dma_channel_status {
|
||||
/* unallocated */
|
||||
MUSB_DMA_STATUS_UNKNOWN,
|
||||
/* allocated ... but not busy, no errors */
|
||||
MUSB_DMA_STATUS_FREE,
|
||||
/* busy ... transactions are active */
|
||||
MUSB_DMA_STATUS_BUSY,
|
||||
/* transaction(s) aborted due to ... dma or memory bus error */
|
||||
MUSB_DMA_STATUS_BUS_ABORT,
|
||||
/* transaction(s) aborted due to ... core error or USB fault */
|
||||
MUSB_DMA_STATUS_CORE_ABORT
|
||||
};
|
||||
|
||||
struct dma_controller;
|
||||
|
||||
/**
|
||||
* struct dma_channel - A DMA channel.
|
||||
* @private_data: channel-private data
|
||||
* @max_len: the maximum number of bytes the channel can move in one
|
||||
* transaction (typically representing many USB maximum-sized packets)
|
||||
* @actual_len: how many bytes have been transferred
|
||||
* @status: current channel status (updated e.g. on interrupt)
|
||||
* @desired_mode: true if mode 1 is desired; false if mode 0 is desired
|
||||
*
|
||||
* channels are associated with an endpoint for the duration of at least
|
||||
* one usb transfer.
|
||||
*/
|
||||
struct dma_channel {
|
||||
void *private_data;
|
||||
/* FIXME not void* private_data, but a dma_controller * */
|
||||
size_t max_len;
|
||||
size_t actual_len;
|
||||
enum dma_channel_status status;
|
||||
bool desired_mode;
|
||||
};
|
||||
|
||||
/*
|
||||
* dma_channel_status - return status of dma channel
|
||||
* @c: the channel
|
||||
*
|
||||
* Returns the software's view of the channel status. If that status is BUSY
|
||||
* then it's possible that the hardware has completed (or aborted) a transfer,
|
||||
* so the driver needs to update that status.
|
||||
*/
|
||||
static inline enum dma_channel_status
|
||||
dma_channel_status(struct dma_channel *c)
|
||||
{
|
||||
return (is_dma_capable() && c) ? c->status : MUSB_DMA_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct dma_controller - A DMA Controller.
|
||||
* @start: call this to start a DMA controller;
|
||||
* return 0 on success, else negative errno
|
||||
* @stop: call this to stop a DMA controller
|
||||
* return 0 on success, else negative errno
|
||||
* @channel_alloc: call this to allocate a DMA channel
|
||||
* @channel_release: call this to release a DMA channel
|
||||
* @channel_abort: call this to abort a pending DMA transaction,
|
||||
* returning it to FREE (but allocated) state
|
||||
*
|
||||
* Controllers manage dma channels.
|
||||
*/
|
||||
struct dma_controller {
|
||||
int (*start)(struct dma_controller *);
|
||||
int (*stop)(struct dma_controller *);
|
||||
struct dma_channel *(*channel_alloc)(struct dma_controller *,
|
||||
struct musb_hw_ep *, u8 is_tx);
|
||||
void (*channel_release)(struct dma_channel *);
|
||||
int (*channel_program)(struct dma_channel *channel,
|
||||
u16 maxpacket, u8 mode,
|
||||
dma_addr_t dma_addr,
|
||||
u32 length);
|
||||
int (*channel_abort)(struct dma_channel *);
|
||||
};
|
||||
|
||||
/* called after channel_program(), may indicate a fault */
|
||||
extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
|
||||
|
||||
|
||||
extern struct dma_controller *__init
|
||||
dma_controller_create(struct musb *, void __iomem *);
|
||||
|
||||
extern void dma_controller_destroy(struct dma_controller *);
|
||||
|
||||
#endif /* __MUSB_DMA_H__ */
|
||||
2033
drivers/usb/musb/musb_gadget.c
Normal file
2033
drivers/usb/musb/musb_gadget.c
Normal file
File diff suppressed because it is too large
Load Diff
108
drivers/usb/musb/musb_gadget.h
Normal file
108
drivers/usb/musb/musb_gadget.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* MUSB OTG driver peripheral defines
|
||||
*
|
||||
* Copyright 2005 Mentor Graphics Corporation
|
||||
* Copyright (C) 2005-2006 by Texas Instruments
|
||||
* Copyright (C) 2006-2007 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MUSB_GADGET_H
|
||||
#define __MUSB_GADGET_H
|
||||
|
||||
struct musb_request {
|
||||
struct usb_request request;
|
||||
struct musb_ep *ep;
|
||||
struct musb *musb;
|
||||
u8 tx; /* endpoint direction */
|
||||
u8 epnum;
|
||||
u8 mapped;
|
||||
};
|
||||
|
||||
static inline struct musb_request *to_musb_request(struct usb_request *req)
|
||||
{
|
||||
return req ? container_of(req, struct musb_request, request) : NULL;
|
||||
}
|
||||
|
||||
extern struct usb_request *
|
||||
musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
|
||||
extern void musb_free_request(struct usb_ep *ep, struct usb_request *req);
|
||||
|
||||
|
||||
/*
|
||||
* struct musb_ep - peripheral side view of endpoint rx or tx side
|
||||
*/
|
||||
struct musb_ep {
|
||||
/* stuff towards the head is basically write-once. */
|
||||
struct usb_ep end_point;
|
||||
char name[12];
|
||||
struct musb_hw_ep *hw_ep;
|
||||
struct musb *musb;
|
||||
u8 current_epnum;
|
||||
|
||||
/* ... when enabled/disabled ... */
|
||||
u8 type;
|
||||
u8 is_in;
|
||||
u16 packet_sz;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct dma_channel *dma;
|
||||
|
||||
/* later things are modified based on usage */
|
||||
struct list_head req_list;
|
||||
|
||||
/* true if lock must be dropped but req_list may not be advanced */
|
||||
u8 busy;
|
||||
};
|
||||
|
||||
static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
|
||||
{
|
||||
return ep ? container_of(ep, struct musb_ep, end_point) : NULL;
|
||||
}
|
||||
|
||||
static inline struct usb_request *next_request(struct musb_ep *ep)
|
||||
{
|
||||
struct list_head *queue = &ep->req_list;
|
||||
|
||||
if (list_empty(queue))
|
||||
return NULL;
|
||||
return container_of(queue->next, struct usb_request, list);
|
||||
}
|
||||
|
||||
extern void musb_g_tx(struct musb *musb, u8 epnum);
|
||||
extern void musb_g_rx(struct musb *musb, u8 epnum);
|
||||
|
||||
extern const struct usb_ep_ops musb_g_ep0_ops;
|
||||
|
||||
extern int musb_gadget_setup(struct musb *);
|
||||
extern void musb_gadget_cleanup(struct musb *);
|
||||
|
||||
extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
|
||||
|
||||
extern int musb_gadget_set_halt(struct usb_ep *ep, int value);
|
||||
|
||||
#endif /* __MUSB_GADGET_H */
|
||||
981
drivers/usb/musb/musb_gadget_ep0.c
Normal file
981
drivers/usb/musb/musb_gadget_ep0.c
Normal file
File diff suppressed because it is too large
Load Diff
2170
drivers/usb/musb/musb_host.c
Normal file
2170
drivers/usb/musb/musb_host.c
Normal file
File diff suppressed because it is too large
Load Diff
110
drivers/usb/musb/musb_host.h
Normal file
110
drivers/usb/musb/musb_host.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* MUSB OTG driver host defines
|
||||
*
|
||||
* Copyright 2005 Mentor Graphics Corporation
|
||||
* Copyright (C) 2005-2006 by Texas Instruments
|
||||
* Copyright (C) 2006-2007 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MUSB_HOST_H
|
||||
#define _MUSB_HOST_H
|
||||
|
||||
static inline struct usb_hcd *musb_to_hcd(struct musb *musb)
|
||||
{
|
||||
return container_of((void *) musb, struct usb_hcd, hcd_priv);
|
||||
}
|
||||
|
||||
static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
|
||||
{
|
||||
return (struct musb *) (hcd->hcd_priv);
|
||||
}
|
||||
|
||||
/* stored in "usb_host_endpoint.hcpriv" for scheduled endpoints */
|
||||
struct musb_qh {
|
||||
struct usb_host_endpoint *hep; /* usbcore info */
|
||||
struct usb_device *dev;
|
||||
struct musb_hw_ep *hw_ep; /* current binding */
|
||||
|
||||
struct list_head ring; /* of musb_qh */
|
||||
/* struct musb_qh *next; */ /* for periodic tree */
|
||||
|
||||
unsigned offset; /* in urb->transfer_buffer */
|
||||
unsigned segsize; /* current xfer fragment */
|
||||
|
||||
u8 type_reg; /* {rx,tx} type register */
|
||||
u8 intv_reg; /* {rx,tx} interval register */
|
||||
u8 addr_reg; /* device address register */
|
||||
u8 h_addr_reg; /* hub address register */
|
||||
u8 h_port_reg; /* hub port register */
|
||||
|
||||
u8 is_ready; /* safe to modify hw_ep */
|
||||
u8 type; /* XFERTYPE_* */
|
||||
u8 epnum;
|
||||
u16 maxpacket;
|
||||
u16 frame; /* for periodic schedule */
|
||||
unsigned iso_idx; /* in urb->iso_frame_desc[] */
|
||||
};
|
||||
|
||||
/* map from control or bulk queue head to the first qh on that ring */
|
||||
static inline struct musb_qh *first_qh(struct list_head *q)
|
||||
{
|
||||
if (list_empty(q))
|
||||
return NULL;
|
||||
return list_entry(q->next, struct musb_qh, ring);
|
||||
}
|
||||
|
||||
|
||||
extern void musb_root_disconnect(struct musb *musb);
|
||||
|
||||
struct usb_hcd;
|
||||
|
||||
extern int musb_hub_status_data(struct usb_hcd *hcd, char *buf);
|
||||
extern int musb_hub_control(struct usb_hcd *hcd,
|
||||
u16 typeReq, u16 wValue, u16 wIndex,
|
||||
char *buf, u16 wLength);
|
||||
|
||||
extern const struct hc_driver musb_hc_driver;
|
||||
|
||||
static inline struct urb *next_urb(struct musb_qh *qh)
|
||||
{
|
||||
#ifdef CONFIG_USB_MUSB_HDRC_HCD
|
||||
struct list_head *queue;
|
||||
|
||||
if (!qh)
|
||||
return NULL;
|
||||
queue = &qh->hep->urb_list;
|
||||
if (list_empty(queue))
|
||||
return NULL;
|
||||
return list_entry(queue->next, struct urb, urb_list);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _MUSB_HOST_H */
|
||||
115
drivers/usb/musb/musb_io.h
Normal file
115
drivers/usb/musb/musb_io.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* MUSB OTG driver register I/O
|
||||
*
|
||||
* Copyright 2005 Mentor Graphics Corporation
|
||||
* Copyright (C) 2005-2006 by Texas Instruments
|
||||
* Copyright (C) 2006-2007 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MUSB_LINUX_PLATFORM_ARCH_H__
|
||||
#define __MUSB_LINUX_PLATFORM_ARCH_H__
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
#ifndef CONFIG_ARM
|
||||
static inline void readsl(const void __iomem *addr, void *buf, int len)
|
||||
{ insl((unsigned long)addr, buf, len); }
|
||||
static inline void readsw(const void __iomem *addr, void *buf, int len)
|
||||
{ insw((unsigned long)addr, buf, len); }
|
||||
static inline void readsb(const void __iomem *addr, void *buf, int len)
|
||||
{ insb((unsigned long)addr, buf, len); }
|
||||
|
||||
static inline void writesl(const void __iomem *addr, const void *buf, int len)
|
||||
{ outsl((unsigned long)addr, buf, len); }
|
||||
static inline void writesw(const void __iomem *addr, const void *buf, int len)
|
||||
{ outsw((unsigned long)addr, buf, len); }
|
||||
static inline void writesb(const void __iomem *addr, const void *buf, int len)
|
||||
{ outsb((unsigned long)addr, buf, len); }
|
||||
|
||||
#endif
|
||||
|
||||
/* NOTE: these offsets are all in bytes */
|
||||
|
||||
static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
|
||||
{ return __raw_readw(addr + offset); }
|
||||
|
||||
static inline u32 musb_readl(const void __iomem *addr, unsigned offset)
|
||||
{ return __raw_readl(addr + offset); }
|
||||
|
||||
|
||||
static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
|
||||
{ __raw_writew(data, addr + offset); }
|
||||
|
||||
static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
|
||||
{ __raw_writel(data, addr + offset); }
|
||||
|
||||
|
||||
#ifdef CONFIG_USB_TUSB6010
|
||||
|
||||
/*
|
||||
* TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum.
|
||||
*/
|
||||
static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
|
||||
{
|
||||
u16 tmp;
|
||||
u8 val;
|
||||
|
||||
tmp = __raw_readw(addr + (offset & ~1));
|
||||
if (offset & 1)
|
||||
val = (tmp >> 8);
|
||||
else
|
||||
val = tmp & 0xff;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
|
||||
{
|
||||
u16 tmp;
|
||||
|
||||
tmp = __raw_readw(addr + (offset & ~1));
|
||||
if (offset & 1)
|
||||
tmp = (data << 8) | (tmp & 0xff);
|
||||
else
|
||||
tmp = (tmp & 0xff00) | data;
|
||||
|
||||
__raw_writew(tmp, addr + (offset & ~1));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
|
||||
{ return __raw_readb(addr + offset); }
|
||||
|
||||
static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
|
||||
{ __raw_writeb(data, addr + offset); }
|
||||
|
||||
#endif /* CONFIG_USB_TUSB6010 */
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user