#include <linux/interrupt.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
+#include <linux/clk.h>
#include <linux/device.h>
-#include <linux/usb_ch9.h>
+#include <linux/usb/ch9.h>
#include <linux/usb_gadget.h>
#include <linux/usb.h>
#include <linux/usb/otg.h>
/* NOTE: otg and peripheral-only state machines start at B_IDLE.
* OTG or host-only go to A_IDLE when ID is sensed.
*/
-#define is_peripheral_active(m) (!(m)->bIsHost)
-#define is_host_active(m) ((m)->bIsHost)
+#define is_peripheral_active(m) (!(m)->is_host)
+#define is_host_active(m) ((m)->is_host)
#else
#define is_peripheral_enabled(musb) is_peripheral_capable()
extern void musb_g_reset(struct musb *);
extern void musb_g_suspend(struct musb *);
extern void musb_g_resume(struct musb *);
+extern void musb_g_wakeup(struct musb *);
extern void musb_g_disconnect(struct musb *);
#else
static inline void musb_g_reset(struct musb *m) {}
static inline void musb_g_suspend(struct musb *m) {}
static inline void musb_g_resume(struct musb *m) {}
+static inline void musb_g_wakeup(struct musb *m) {}
static inline void musb_g_disconnect(struct musb *m) {}
#endif
#endif
/* host side ep0 states */
-#define MGC_END0_START 0x0
-#define MGC_END0_OUT 0x2
-#define MGC_END0_IN 0x4
-#define MGC_END0_STATUS 0x8
+enum musb_h_ep0_state {
+ MGC_END0_IDLE,
+ MGC_END0_START, /* expect ack of setup */
+ MGC_END0_IN, /* expect IN DATA */
+ MGC_END0_OUT, /* expect ack of OUT DATA */
+ MGC_END0_STATUS, /* expect ack of STATUS */
+} __attribute__ ((packed));
/* peripheral side ep0 states */
enum musb_g_ep0_state {
* directly with the "flat" model, or after setting up an index register.
*/
-#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP243X)
+#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) || \
+ defined(CONFIG_ARCH_OMAP3430)
/* REVISIT indexed access seemed to
* misbehave (on DaVinci) for at least peripheral IN ...
*/
/* TUSB mapping: "flat" plus ep0 special cases */
#if defined(CONFIG_USB_TUSB6010)
-#define MGC_SelectEnd(_pBase, _bEnd) \
- musb_writeb((_pBase), MGC_O_HDRC_INDEX, (_bEnd))
+#define musb_ep_select(_mbase, _epnum) \
+ musb_writeb((_mbase), MGC_O_HDRC_INDEX, (_epnum))
#define MGC_END_OFFSET MGC_TUSB_OFFSET
/* "flat" mapping: each endpoint has its own i/o address */
#elif defined(MUSB_FLAT_REG)
-#define MGC_SelectEnd(_pBase, _bEnd) (((void)(_pBase)),((void)(_bEnd)))
+#define musb_ep_select(_mbase, _epnum) (((void)(_mbase)),((void)(_epnum)))
#define MGC_END_OFFSET MGC_FLAT_OFFSET
/* "indexed" mapping: INDEX register controls register bank select */
#else
-#define MGC_SelectEnd(_pBase, _bEnd) \
- musb_writeb((_pBase), MGC_O_HDRC_INDEX, (_bEnd))
+#define musb_ep_select(_mbase, _epnum) \
+ musb_writeb((_mbase), MGC_O_HDRC_INDEX, (_epnum))
#define MGC_END_OFFSET MGC_INDEXED_OFFSET
#endif
/****************************** FUNCTIONS ********************************/
-#define MUSB_HST_MODE(_pthis)\
- { (_pthis)->bIsHost=TRUE; }
-#define MUSB_DEV_MODE(_pthis) \
- { (_pthis)->bIsHost=FALSE; }
+#define MUSB_HST_MODE(_musb)\
+ { (_musb)->is_host=TRUE; }
+#define MUSB_DEV_MODE(_musb) \
+ { (_musb)->is_host=FALSE; }
#define test_devctl_hst_mode(_x) \
- (musb_readb((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM)
-
-#define MUSB_MODE(musb) ((musb)->bIsHost ? "Host" : "Peripheral")
-
-/************************** Ep Configuration ********************************/
-
-/** The End point descriptor */
-struct MUSB_EpFifoDescriptor {
- u8 bType; /* 0 for autoconfig, CNTR, ISOC, BULK, INTR */
- u8 bDir; /* 0 for autoconfig, INOUT, IN, OUT */
- int wSize; /* 0 for autoconfig, or the size */
-};
-
-#define MUSB_EPD_AUTOCONFIG 0
-
-#define MUSB_EPD_T_CNTRL 1
-#define MUSB_EPD_T_ISOC 2
-#define MUSB_EPD_T_BULK 3
-#define MUSB_EPD_T_INTR 4
+ (musb_readb((_x)->mregs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM)
-#define MUSB_EPD_D_INOUT 0
-#define MUSB_EPD_D_TX 1
-#define MUSB_EPD_D_RX 2
+#define MUSB_MODE(musb) ((musb)->is_host ? "Host" : "Peripheral")
/******************************** TYPES *************************************/
void __iomem *conf;
#endif
- /* index in musb->aLocalEnd[] */
- u8 bLocalEnd;
+ /* index in musb->endpoints[] */
+ u8 epnum;
/* hardware configuration, possibly dynamic */
- u8 bIsSharedFifo;
+ u8 is_shared_fifo;
u8 tx_double_buffered;
u8 rx_double_buffered;
- u16 wMaxPacketSizeTx;
+ u16 max_packet_sz_tx;
u16 wMaxPacketSizeRx;
struct dma_channel *tx_channel;
/* TUSB has "asynchronous" and "synchronous" dma modes */
dma_addr_t fifo_async;
dma_addr_t fifo_sync;
+ void __iomem *fifo_sync_va;
#endif
#ifdef CONFIG_USB_MUSB_HDRC_HCD
* struct musb - Driver instance data.
*/
struct musb {
- spinlock_t Lock;
+ spinlock_t lock;
struct clk *clock;
irqreturn_t (*isr)(int, void *);
struct work_struct irq_work;
u32 port1_status;
unsigned long rh_timer;
- u8 bEnd0Stage; /* end0 stage while in host */
+ enum musb_h_ep0_state ep0_stage;
/* bulk traffic normally dedicates endpoint hardware, and each
* direction has its own ring of host side endpoints.
struct device *controller;
void __iomem *ctrl_base;
- void __iomem *pRegs;
+ void __iomem *mregs;
#ifdef CONFIG_USB_TUSB6010
dma_addr_t async;
dma_addr_t sync;
+ void __iomem *sync_va;
#endif
/* passed down from chip/board specific irq handlers */
int nIrq;
- struct musb_hw_ep aLocalEnd[MUSB_C_NUM_EPS];
-#define control_ep aLocalEnd
+ struct musb_hw_ep endpoints[MUSB_C_NUM_EPS];
+#define control_ep endpoints
#define VBUSERR_RETRY_COUNT 3
u16 vbuserr_retry;
u16 wEndMask;
- u8 bEndCount;
+ u8 nr_endpoints;
u8 board_mode; /* enum musb_mode */
int (*board_set_power)(int state);
+ int (*set_clock)(struct clk *clk, int is_active);
+
u8 min_power; /* vbus for periph, in mA/2 */
/* active means connected and not suspended */
- unsigned is_active:1;
+ unsigned is_active:1;
unsigned bIsMultipoint:1;
- unsigned bIsHost:1;
+ unsigned is_host:1;
unsigned bIgnoreDisconnect:1; /* during bus resets */
+ int a_wait_bcon; /* VBUS timeout in msecs */
+ unsigned long idle_timeout; /* Next timeout in jiffies */
+
#ifdef C_MP_TX
unsigned bBulkSplit:1;
#define can_bulk_split(musb,type) \
#endif
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
- unsigned bIsSelfPowered:1;
- unsigned bMayWakeup:1;
+ /* is_suspended means USB B_PERIPHERAL suspend */
+ unsigned is_suspended:1;
+
+ /* may_wakeup means remote wakeup is enabled */
+ unsigned may_wakeup:1;
+
+ /* is_self_powered is reported in device status and the
+ * config descriptor. is_bus_powered means B_PERIPHERAL
+ * draws some VBUS current; both can be true.
+ */
+ unsigned is_self_powered:1;
+ unsigned is_bus_powered:1;
+
unsigned bSetAddress:1;
unsigned bTestMode:1;
unsigned softconnect:1;
extern const char musb_driver_name[];
-extern void musb_start(struct musb *pThis);
-extern void musb_stop(struct musb *pThis);
+extern void musb_start(struct musb *musb);
+extern void musb_stop(struct musb *musb);
extern void musb_write_fifo(struct musb_hw_ep *ep,
- u16 wCount, const u8 * pSource);
+ u16 len, const u8 * src);
extern void musb_read_fifo(struct musb_hw_ep *ep,
- u16 wCount, u8 * pDest);
+ u16 len, u8 * dst);
extern void musb_load_testpacket(struct musb *);
extern void musb_platform_enable(struct musb *musb);
extern void musb_platform_disable(struct musb *musb);
+extern void musb_hnp_stop(struct musb *musb);
+
#ifdef CONFIG_USB_TUSB6010
-extern void musb_platform_try_idle(struct musb *musb);
+extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
extern int musb_platform_get_vbus_status(struct musb *musb);
+extern void musb_platform_set_mode(struct musb *musb, u8 musb_mode);
#else
-#define musb_platform_try_idle(x) do {} while (0)
+#define musb_platform_try_idle(x, y) do {} while (0)
#define musb_platform_get_vbus_status(x) 0
+#define musb_platform_set_mode(x, y) do {} while (0)
#endif
extern int __init musb_platform_init(struct musb *musb);