]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - include/usb.h
Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / include / usb.h
index 9a2e72c9d01528d7b5679ba9cb35ecfeba5718d1..d7b082d9f4609e10e03f45e5816d68a9ead2101d 100644 (file)
 #define _USB_H_
 
 #include <usb_defs.h>
+#include <linux/usb/ch9.h>
+
+/*
+ * The EHCI spec says that we must align to at least 32 bytes.  However,
+ * some platforms require larger alignment.
+ */
+#if ARCH_DMA_MINALIGN > 32
+#define USB_DMA_MINALIGN       ARCH_DMA_MINALIGN
+#else
+#define USB_DMA_MINALIGN       32
+#endif
 
 /* Everything is aribtrary */
 #define USB_ALTSETTINGALLOC            4
 
 #define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
 
-/* String descriptor */
-struct usb_string_descriptor {
-       unsigned char  bLength;
-       unsigned char  bDescriptorType;
-       unsigned short wData[1];
-} __attribute__ ((packed));
+/*
+ * This is the timeout to allow for submitting an urb in ms. We allow more
+ * time for a BULK device to react - some are slow.
+ */
+#define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 1000)
 
 /* device request (setup) */
 struct devrequest {
-       unsigned char requesttype;
-       unsigned char request;
-       unsigned short value;
-       unsigned short index;
-       unsigned short length;
-} __attribute__ ((packed));
-
-
-/* All standard descriptors have these 2 fields in common */
-struct usb_descriptor_header {
-       unsigned char  bLength;
-       unsigned char  bDescriptorType;
+       unsigned char   requesttype;
+       unsigned char   request;
+       unsigned short  value;
+       unsigned short  index;
+       unsigned short  length;
 } __attribute__ ((packed));
 
-/* Device descriptor */
-struct usb_device_descriptor {
-       unsigned char  bLength;
-       unsigned char  bDescriptorType;
-       unsigned short bcdUSB;
-       unsigned char  bDeviceClass;
-       unsigned char  bDeviceSubClass;
-       unsigned char  bDeviceProtocol;
-       unsigned char  bMaxPacketSize0;
-       unsigned short idVendor;
-       unsigned short idProduct;
-       unsigned short bcdDevice;
-       unsigned char  iManufacturer;
-       unsigned char  iProduct;
-       unsigned char  iSerialNumber;
-       unsigned char  bNumConfigurations;
-} __attribute__ ((packed));
+/* Interface */
+struct usb_interface {
+       struct usb_interface_descriptor desc;
 
+       unsigned char   no_of_ep;
+       unsigned char   num_altsetting;
+       unsigned char   act_altsetting;
 
-/* Endpoint descriptor */
-struct usb_endpoint_descriptor {
-       unsigned char  bLength;
-       unsigned char  bDescriptorType;
-       unsigned char  bEndpointAddress;
-       unsigned char  bmAttributes;
-       unsigned short wMaxPacketSize;
-       unsigned char  bInterval;
-       unsigned char  bRefresh;
-       unsigned char  bSynchAddress;
-
-} __attribute__ ((packed));
-/* Interface descriptor */
-struct usb_interface_descriptor {
-       unsigned char  bLength;
-       unsigned char  bDescriptorType;
-       unsigned char  bInterfaceNumber;
-       unsigned char  bAlternateSetting;
-       unsigned char  bNumEndpoints;
-       unsigned char  bInterfaceClass;
-       unsigned char  bInterfaceSubClass;
-       unsigned char  bInterfaceProtocol;
-       unsigned char  iInterface;
-
-       unsigned char  no_of_ep;
-       unsigned char  num_altsetting;
-       unsigned char  act_altsetting;
        struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
+       /*
+        * Super Speed Device will have Super Speed Endpoint
+        * Companion Descriptor  (section 9.6.7 of usb 3.0 spec)
+        * Revision 1.0 June 6th 2011
+        */
+       struct usb_ss_ep_comp_descriptor ss_ep_comp_desc[USB_MAXENDPOINTS];
 } __attribute__ ((packed));
 
+/* Configuration information.. */
+struct usb_config {
+       struct usb_config_descriptor desc;
 
-/* Configuration descriptor information.. */
-struct usb_config_descriptor {
-       unsigned char  bLength;
-       unsigned char  bDescriptorType;
-       unsigned short wTotalLength;
-       unsigned char  bNumInterfaces;
-       unsigned char  bConfigurationValue;
-       unsigned char  iConfiguration;
-       unsigned char  bmAttributes;
-       unsigned char  MaxPower;
-
-       unsigned char  no_of_if;                /* number of interfaces */
-       struct usb_interface_descriptor if_desc[USB_MAXINTERFACES];
+       unsigned char   no_of_if;       /* number of interfaces */
+       struct usb_interface if_desc[USB_MAXINTERFACES];
 } __attribute__ ((packed));
 
 enum {
@@ -138,25 +101,28 @@ enum {
 };
 
 struct usb_device {
-       int devnum;                     /* Device number on USB bus */
-       int slow;                       /* Slow device? */
-       char mf[32];                    /* manufacturer */
-       char prod[32];                  /* product */
-       char serial[32];                /* serial number */
+       int     devnum;                 /* Device number on USB bus */
+       int     speed;                  /* full/low/high */
+       char    mf[32];                 /* manufacturer */
+       char    prod[32];               /* product */
+       char    serial[32];             /* serial number */
 
        /* Maximum packet size; one of: PACKET_SIZE_* */
        int maxpacketsize;
        /* one bit for each endpoint ([0] = IN, [1] = OUT) */
        unsigned int toggle[2];
-       /* endpoint halts; one bit per endpoint # & direction; */
+       /* endpoint halts; one bit per endpoint # & direction;
+        * [0] = IN, [1] = OUT
+        */
        unsigned int halted[2];
-                           /* [0] = IN, [1] = OUT */
        int epmaxpacketin[16];          /* INput endpoint specific maximums */
        int epmaxpacketout[16];         /* OUTput endpoint specific maximums */
 
        int configno;                   /* selected config number */
-       struct usb_device_descriptor descriptor; /* Device Descriptor */
-       struct usb_config_descriptor config; /* config descriptor */
+       /* Device Descriptor */
+       struct usb_device_descriptor descriptor
+               __attribute__((aligned(ARCH_DMA_MINALIGN)));
+       struct usb_config config; /* config descriptor */
 
        int have_langid;                /* whether string_langid is valid yet */
        int string_langid;              /* language ID for strings */
@@ -171,8 +137,11 @@ struct usb_device {
        unsigned long status;
        int act_len;                    /* transfered bytes */
        int maxchild;                   /* Number of ports if hub */
+       int portnr;
        struct usb_device *parent;
        struct usb_device *children[USB_MAXCHILDREN];
+
+       void *controller;               /* hardware controller private data */
 };
 
 /**********************************************************************
@@ -180,21 +149,38 @@ struct usb_device {
  */
 
 #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
-       defined(CONFIG_USB_OHCI_NEW) || defined (CONFIG_USB_SL811HS) || \
-       defined(CONFIG_USB_ISP116X_HCD) || defined(CONFIG_USB_R8A66597_HCD)
-
-int usb_lowlevel_init(void);
-int usb_lowlevel_stop(void);
-int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len);
+       defined(CONFIG_USB_EHCI) || defined(CONFIG_USB_OHCI_NEW) || \
+       defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
+       defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
+       defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
+       defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
+       defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
+       defined(CONFIG_USB_MUSB_OMAP2PLUS)
+
+int usb_lowlevel_init(int index, void **controller);
+int usb_lowlevel_stop(int index);
+
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+                       void *buffer, int transfer_len);
 int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                       int transfer_len,struct devrequest *setup);
+                       int transfer_len, struct devrequest *setup);
 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
                        int transfer_len, int interval);
-void usb_event_poll(void);
 
 /* Defines */
-#define USB_UHCI_VEND_ID 0x8086
-#define USB_UHCI_DEV_ID         0x7112
+#define USB_UHCI_VEND_ID       0x8086
+#define USB_UHCI_DEV_ID                0x7112
+
+/*
+ * PXA25x can only act as USB device. There are drivers
+ * which works with USB CDC gadgets implementations.
+ * Some of them have common routines which can be used
+ * in boards init functions e.g. udc_disconnect() used for
+ * forced device disconnection from host.
+ */
+#elif defined(CONFIG_USB_GADGET_PXA2XX)
+
+extern void udc_disconnect(void);
 
 #else
 #error USB Lowlevel not defined
@@ -209,6 +195,13 @@ int usb_stor_info(void);
 
 #endif
 
+#ifdef CONFIG_USB_HOST_ETHER
+
+#define USB_MAX_ETH_DEV 5
+int usb_host_eth_scan(int mode);
+
+#endif
+
 #ifdef CONFIG_USB_KEYBOARD
 
 int drv_usb_kbd_init(void);
@@ -221,8 +214,9 @@ int usb_stop(void); /* stop the USB Controller */
 
 
 int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
-int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id);
-struct usb_device * usb_get_dev_index(int index);
+int usb_set_idle(struct usb_device *dev, int ifnum, int duration,
+                       int report_id);
+struct usb_device *usb_get_dev_index(int index);
 int usb_control_msg(struct usb_device *dev, unsigned int pipe,
                        unsigned char request, unsigned char requesttype,
                        unsigned short value, unsigned short index,
@@ -230,14 +224,16 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
                        void *data, int len, int *actual_length, int timeout);
 int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
-                       void *buffer,int transfer_len, int interval);
-void usb_disable_asynch(int disable);
-int usb_maxpacket(struct usb_device *dev,unsigned long pipe);
-void __inline__ wait_ms(unsigned long ms);
-int usb_get_configuration_no(struct usb_device *dev,unsigned char *buffer,int cfgno);
-int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size);
+                       void *buffer, int transfer_len, int interval);
+int usb_disable_asynch(int disable);
+int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
+int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
+                               int cfgno);
+int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
+                       unsigned char id, void *buf, int size);
 int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
-               unsigned char type, unsigned char id, void *buf, int size);
+                       unsigned char type, unsigned char id, void *buf,
+                       int size);
 int usb_clear_halt(struct usb_device *dev, int pipe);
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size);
 int usb_set_interface(struct usb_device *dev, int interface, int alternate);
@@ -247,7 +243,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 #define __swap_16(x) \
        ({ unsigned short x_ = (unsigned short)x; \
         (unsigned short)( \
-               ((x_ & 0x00FFU) << 8) | ((x_ & 0xFF00U) >> 8) ); \
+               ((x_ & 0x00FFU) << 8) | ((x_ & 0xFF00U) >> 8)); \
        })
 #define __swap_32(x) \
        ({ unsigned long x_ = (unsigned long)x; \
@@ -255,16 +251,16 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
                ((x_ & 0x000000FFUL) << 24) | \
                ((x_ & 0x0000FF00UL) <<  8) | \
                ((x_ & 0x00FF0000UL) >>  8) | \
-               ((x_ & 0xFF000000UL) >> 24) ); \
+               ((x_ & 0xFF000000UL) >> 24)); \
        })
 
-#ifdef LITTLEENDIAN
+#ifdef __LITTLE_ENDIAN
 # define swap_16(x) (x)
 # define swap_32(x) (x)
 #else
 # define swap_16(x) __swap_16(x)
 # define swap_32(x) __swap_32(x)
-#endif /* LITTLEENDIAN */
+#endif
 
 /*
  * Calling this entity a "pipe" is glorifying it. A USB pipe
@@ -274,7 +270,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
  *  - endpoint number (4 bits)
  *  - current Data0/1 state (1 bit)
  *  - direction (1 bit)
- *  - speed (1 bit)
+ *  - speed (2 bits)
  *  - max packet size (2 bits: 8, 16, 32 or 64)
  *  - pipe type (2 bits: control, interrupt, bulk, isochronous)
  *
@@ -286,12 +282,13 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
  * unsigned int. The encoding is:
  *
  *  - max size:                bits 0-1        (00 = 8, 01 = 16, 10 = 32, 11 = 64)
- *  - direction:       bit 7           (0 = Host-to-Device [Out], 1 = Device-to-Host [In])
+ *  - direction:       bit 7           (0 = Host-to-Device [Out],
+ *                                     (1 = Device-to-Host [In])
  *  - device:          bits 8-14
  *  - endpoint:                bits 15-18
  *  - Data0/1:         bit 19
- *  - speed:           bit 26          (0 = Full, 1 = Low Speed)
- *  - pipe type:       bits 30-31      (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
+ *  - pipe type:       bits 30-31      (00 = isochronous, 01 = interrupt,
+ *                                      10 = control, 11 = bulk)
  *
  * Why? Because it's arbitrary, and whatever encoding we select is really
  * up to us. This one happens to share a lot of bit positions with the UHCI
@@ -300,24 +297,42 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
  */
 /* Create various pipes... */
 #define create_pipe(dev,endpoint) \
-               (((dev)->devnum << 8) | (endpoint << 15) | ((dev)->slow << 26) | (dev)->maxpacketsize)
-#define default_pipe(dev) ((dev)->slow <<26)
-
-#define usb_sndctrlpipe(dev,endpoint)  ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint))
-#define usb_rcvctrlpipe(dev,endpoint)  ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndisocpipe(dev,endpoint)  ((PIPE_ISOCHRONOUS << 30) | create_pipe(dev,endpoint))
-#define usb_rcvisocpipe(dev,endpoint)  ((PIPE_ISOCHRONOUS << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndbulkpipe(dev,endpoint)  ((PIPE_BULK << 30) | create_pipe(dev,endpoint))
-#define usb_rcvbulkpipe(dev,endpoint)  ((PIPE_BULK << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndintpipe(dev,endpoint)   ((PIPE_INTERRUPT << 30) | create_pipe(dev,endpoint))
-#define usb_rcvintpipe(dev,endpoint)   ((PIPE_INTERRUPT << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_snddefctrl(dev)            ((PIPE_CONTROL << 30) | default_pipe(dev))
-#define usb_rcvdefctrl(dev)            ((PIPE_CONTROL << 30) | default_pipe(dev) | USB_DIR_IN)
+               (((dev)->devnum << 8) | ((endpoint) << 15) | \
+               (dev)->maxpacketsize)
+#define default_pipe(dev) ((dev)->speed << 26)
+
+#define usb_sndctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \
+                                        create_pipe(dev, endpoint))
+#define usb_rcvctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \
+                                        create_pipe(dev, endpoint) | \
+                                        USB_DIR_IN)
+#define usb_sndisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \
+                                        create_pipe(dev, endpoint))
+#define usb_rcvisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \
+                                        create_pipe(dev, endpoint) | \
+                                        USB_DIR_IN)
+#define usb_sndbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \
+                                        create_pipe(dev, endpoint))
+#define usb_rcvbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \
+                                        create_pipe(dev, endpoint) | \
+                                        USB_DIR_IN)
+#define usb_sndintpipe(dev, endpoint)  ((PIPE_INTERRUPT << 30) | \
+                                        create_pipe(dev, endpoint))
+#define usb_rcvintpipe(dev, endpoint)  ((PIPE_INTERRUPT << 30) | \
+                                        create_pipe(dev, endpoint) | \
+                                        USB_DIR_IN)
+#define usb_snddefctrl(dev)            ((PIPE_CONTROL << 30) | \
+                                        default_pipe(dev))
+#define usb_rcvdefctrl(dev)            ((PIPE_CONTROL << 30) | \
+                                        default_pipe(dev) | \
+                                        USB_DIR_IN)
 
 /* The D0/D1 toggle bits */
 #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1)
 #define usb_dotoggle(dev, ep, out)  ((dev)->toggle[out] ^= (1 << ep))
-#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << ep)) | ((bit) << ep))
+#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = \
+                                               ((dev)->toggle[out] & \
+                                                ~(1 << ep)) | ((bit) << ep))
 
 /* Endpoint halt control/status */
 #define usb_endpoint_out(ep_dir)       (((ep_dir >> 7) & 1) ^ 1)
@@ -325,7 +340,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 #define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep)))
 #define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep)))
 
-#define usb_packetid(pipe)     (((pipe) & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT)
+#define usb_packetid(pipe)     (((pipe) & USB_DIR_IN) ? USB_PID_IN : \
+                                USB_PID_OUT)
 
 #define usb_pipeout(pipe)      ((((pipe) >> 7) & 1) ^ 1)
 #define usb_pipein(pipe)       (((pipe) >> 7) & 1)
@@ -333,7 +349,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 #define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff)
 #define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
 #define usb_pipedata(pipe)     (((pipe) >> 19) & 1)
-#define usb_pipeslow(pipe)     (((pipe) >> 26) & 1)
 #define usb_pipetype(pipe)     (((pipe) >> 30) & 3)
 #define usb_pipeisoc(pipe)     (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
 #define usb_pipeint(pipe)      (usb_pipetype((pipe)) == PIPE_INTERRUPT)
@@ -365,7 +380,7 @@ struct usb_hub_descriptor {
        unsigned char  bHubContrCurrent;
        unsigned char  DeviceRemovable[(USB_MAXCHILDREN+1+7)/8];
        unsigned char  PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8];
-               /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
+       /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
           bitmaps that hold max 255 entries. (bit0 is ignored) */
 } __attribute__ ((packed));
 
@@ -375,4 +390,14 @@ struct usb_hub_device {
        struct usb_hub_descriptor desc;
 };
 
+int usb_hub_probe(struct usb_device *dev, int ifnum);
+void usb_hub_reset(void);
+int hub_port_reset(struct usb_device *dev, int port,
+                         unsigned short *portstat);
+
+struct usb_device *usb_alloc_new_device(void *controller);
+
+int usb_new_device(struct usb_device *dev);
+void usb_free_device(void);
+
 #endif /*_USB_H_ */