]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/musb/musbdefs.h
musb_hdrc: Update peripheral side suspend support
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / musbdefs.h
index fe1803463a33a19a25f2a4b305d15ec2edc1bf06..d059be34ff0a6d5bca9ea8f5add3414f18e3c5a4 100644 (file)
 #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;
@@ -67,13 +69,13 @@ struct musb_ep;
 #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)
@@ -82,15 +84,8 @@ struct musb_ep;
 /* 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()
@@ -101,6 +96,15 @@ struct musb_ep;
 #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>
@@ -111,9 +115,6 @@ struct musb_ep;
 
 #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 *);
@@ -129,8 +130,6 @@ extern void musb_g_disconnect(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) {}
@@ -142,10 +141,6 @@ static inline void musb_g_disconnect(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 *);
@@ -160,8 +155,6 @@ static inline irqreturn_t musb_h_ep0_irq(struct musb *m) { return IRQ_NONE; }
 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
 
 
@@ -183,10 +176,13 @@ static inline void musb_root_disconnect(struct musb *musb) { BUG(); }
 #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 {
@@ -210,8 +206,7 @@ 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
@@ -235,50 +230,17 @@ enum musb_g_ep0_state {
 #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 ********************************/
 
@@ -377,15 +339,18 @@ static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep)
 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.
@@ -399,9 +364,13 @@ struct musb {
        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;
@@ -417,7 +386,6 @@ struct musb {
        u8                      int_usb;
        u16                     int_rx;
        u16                     int_tx;
-       struct pt_regs          *int_regs;
 
        struct otg_transceiver  xceiv;
 
@@ -426,6 +394,7 @@ struct musb {
        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;
@@ -436,10 +405,9 @@ struct musb {
        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 */
 
@@ -465,8 +433,19 @@ struct musb {
 #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;
@@ -480,7 +459,7 @@ struct musb {
 #endif
 
 #ifdef CONFIG_USB_MUSB_OTG
-       struct otg_machine      OtgMachine;
+       /* FIXME this can't be OTG-specific ... ? */
        u8 bDelayPortPowerOff;
 #endif
 
@@ -489,6 +468,11 @@ struct musb {
 #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)
 {
@@ -524,7 +508,7 @@ extern int musb_platform_get_vbus_status(struct musb *musb);
 #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 ---------------------*/