#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/device.h>
-#include <linux/usb_ch9.h>
-#include <linux/usb_otg.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb_gadget.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
#include <linux/usb/musb.h>
struct musb;
#include "plat_arc.h"
#include "musbhdrc.h"
+#include "musb_gadget.h"
+#include "../core/hcd.h"
+#include "musb_host.h"
-/* REVISIT tune this */
-#define MIN_DMA_REQUEST 1 /* use PIO below this xfer size */
#ifdef CONFIG_USB_MUSB_OTG
-#include "otg.h"
#define is_peripheral_enabled(musb) ((musb)->board_mode != MUSB_HOST)
#define is_host_enabled(musb) ((musb)->board_mode != MUSB_PERIPHERAL)
/* 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) (is_peripheral_capable() && !(m)->bIsHost)
-#define is_host_active(m) (is_host_capable() && (m)->bIsHost)
-
-/* for some reason, the "select USB_GADGET_MUSB_HDRC" doesn't really
- * override that choice selection (often USB_GADGET_DUMMY_HCD).
- */
-#ifndef CONFIG_USB_GADGET_MUSB_HDRC
-#error bogus Kconfig output ... select CONFIG_USB_GADGET_MUSB_HDRC
-#endif
+#define is_peripheral_active(m) (!(m)->bIsHost)
+#define is_host_active(m) ((m)->bIsHost)
#else
#define is_peripheral_enabled(musb) is_peripheral_capable()
#define is_host_active(musb) is_host_capable()
#endif
+#if defined(CONFIG_USB_MUSB_OTG) || defined(CONFIG_USB_MUSB_PERIPHERAL)
+/* for some reason, the "select USB_GADGET_MUSB_HDRC" doesn't always
+ * override that choice selection (often USB_GADGET_DUMMY_HCD).
+ */
+#ifndef CONFIG_USB_GADGET_MUSB_HDRC
+#error bogus Kconfig output ... select CONFIG_USB_GADGET_MUSB_HDRC
+#endif
+#endif /* need MUSB gadget selection */
+
#ifdef CONFIG_PROC_FS
#include <linux/fs.h>
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-#include <linux/usb_gadget.h>
-#include "musb_gadget.h"
-
#define is_peripheral_capable() (1)
extern irqreturn_t musb_g_ep0_irq(struct musb *);
#define is_peripheral_capable() (0)
static inline irqreturn_t musb_g_ep0_irq(struct musb *m) { return IRQ_NONE; }
-static inline void musb_g_tx(struct musb *m, u8 e) {}
-static inline void musb_g_rx(struct musb *m, u8 e) {}
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) {}
#ifdef CONFIG_USB_MUSB_HDRC_HCD
-#include <linux/usb.h>
-#include "../core/hcd.h"
-#include "musb_host.h"
-
#define is_host_capable() (1)
extern irqreturn_t musb_h_ep0_irq(struct musb *);
static inline void musb_host_tx(struct musb *m, u8 e) {}
static inline void musb_host_rx(struct musb *m, u8 e) {}
-static inline void musb_root_disconnect(struct musb *musb) { BUG(); }
-
#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 {
*/
#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP243X)
-/* REVISIT "flat" takes about 1% more object code space and can't be very
- * noticeable for speed differences. But for now indexed access seems to
+/* REVISIT indexed access seemed to
* misbehave (on DaVinci) for at least peripheral IN ...
*/
#define MUSB_FLAT_REG
#define MGC_END_OFFSET MGC_INDEXED_OFFSET
#endif
-/* FIXME: replace with musb_readcsr(hw_ep *, REGNAME), etc
- * using hw_ep->regs, for all access except writing INDEX
- */
-#ifdef MUSB_FLAT_REG
-#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
- musb_readb((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)))
-#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
- musb_readw((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)))
-#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
- musb_writeb((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)), (_bData))
-#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
- musb_writew((_pBase), MGC_END_OFFSET((_bEnd), (_bOffset)), (_bData))
-#else
-#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
- musb_readb(_pBase, (_bOffset + 0x10))
-#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
- musb_readw(_pBase, (_bOffset + 0x10))
-#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
- musb_writeb(_pBase, (_bOffset + 0x10), _bData)
-#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
- musb_writew(_pBase, (_bOffset + 0x10), _bData)
-#endif
-
/****************************** FUNCTIONS ********************************/
#define MUSB_HST_MODE(_pthis)\
- { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; }
+ { (_pthis)->bIsHost=TRUE; }
#define MUSB_DEV_MODE(_pthis) \
- { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; }
-#define MUSB_OTG_MODE(_pthis) \
- { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; }
-
-#define MUSB_IS_HST(_x) ((_x)->bIsHost && !(_x)->bIsDevice)
-#define MUSB_IS_DEV(_x) (!(_x)->bIsHost && (_x)->bIsDevice)
-#define MUSB_IS_OTG(_x) (!(_x)->bIsHost && !(_x)->bIsDevice)
+ { (_pthis)->bIsHost=FALSE; }
#define test_devctl_hst_mode(_x) \
(musb_readb((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM)
-/* REVISIT OTG isn't a third non-error mode... */
-#define MUSB_MODE(_x) ( MUSB_IS_HST(_x)?"HOST" \
- :(MUSB_IS_DEV(_x)?"PERIPHERAL" \
- :(MUSB_IS_OTG(_x)?"UNCONNECTED" \
- :"ERROR")) )
+#define MUSB_MODE(musb) ((musb)->bIsHost ? "Host" : "Peripheral")
/************************** Ep Configuration ********************************/
struct musb {
spinlock_t Lock;
struct clk *clock;
- irqreturn_t (*isr)(int, void *, struct pt_regs *);
+ irqreturn_t (*isr)(int, void *);
struct work_struct irq_work;
#ifdef CONFIG_USB_MUSB_HDRC_HCD
+/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
+#define MUSB_PORT_STAT_RESUME (1 << 31)
+
u32 port1_status;
unsigned long rh_timer;
- u8 bEnd0Stage; /* end0 stage while in host */
+ enum musb_h_ep0_state bEnd0Stage;
/* bulk traffic normally dedicates endpoint hardware, and each
* direction has its own ring of host side endpoints.
struct list_head in_bulk; /* of musb_qh */
struct list_head out_bulk; /* of musb_qh */
struct musb_qh *periodic[32]; /* tree of interrupt+iso */
-
#endif
+ /* called with IRQs blocked; ON/nonzero implies starting a session,
+ * and waiting at least a_wait_vrise_tmout.
+ */
+ void (*board_set_vbus)(struct musb *, int is_on);
+
struct dma_controller *pDmaController;
struct device *controller;
u8 int_usb;
u16 int_rx;
u16 int_tx;
- struct pt_regs *int_regs;
struct otg_transceiver xceiv;
struct musb_hw_ep aLocalEnd[MUSB_C_NUM_EPS];
#define control_ep aLocalEnd
+#define VBUSERR_RETRY_COUNT 3
u16 vbuserr_retry;
u16 wEndMask;
u8 bEndCount;
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 bIsDevice:1;
unsigned bIsHost:1;
unsigned bIgnoreDisconnect:1; /* during bus resets */
#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;
#endif
#ifdef CONFIG_USB_MUSB_OTG
- struct otg_machine OtgMachine;
+ /* FIXME this can't be OTG-specific ... ? */
u8 bDelayPortPowerOff;
#endif
#endif
};
+static inline void musb_set_vbus(struct musb *musb, int is_on)
+{
+ musb->board_set_vbus(musb, is_on);
+}
+
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
static inline struct musb *gadget_to_musb(struct usb_gadget *g)
{
#define musb_platform_get_vbus_status(x) 0
#endif
-extern int __devinit musb_platform_init(struct musb *musb);
+extern int __init musb_platform_init(struct musb *musb);
extern int musb_platform_exit(struct musb *musb);
/*-------------------------- ProcFS definitions ---------------------*/