dwc_otg_cfi.h

Go to the documentation of this file.
00001 /* ==========================================================================
00002  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
00003  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
00004  * otherwise expressly agreed to in writing between Synopsys and you.
00005  * 
00006  * The Software IS NOT an item of Licensed Software or Licensed Product under
00007  * any End User Software License Agreement or Agreement for Licensed Product
00008  * with Synopsys or any supplement thereto. You are permitted to use and
00009  * redistribute this Software in source and binary forms, with or without
00010  * modification, provided that redistributions of source code must retain this
00011  * notice. You may not view, use, disclose, copy or distribute this file or
00012  * any information contained herein except pursuant to this license grant from
00013  * Synopsys. If you do not agree with this notice, including the disclaimer
00014  * below, then you are not authorized to use the Software.
00015  * 
00016  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
00017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
00020  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00024  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00025  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00026  * DAMAGE.
00027  * ========================================================================== */
00028 
00029 #if !defined(__DWC_OTG_CFI_H__)
00030 #define __DWC_OTG_CFI_H__
00031 
00032 #include "dwc_otg_pcd.h"
00033 #include "dwc_cfi_common.h"
00034 
00043 struct dwc_otg_pcd;
00044 struct dwc_otg_pcd_ep;
00045 
00048 #define FT_ID_DMA_MODE                                  0x0001
00049 #define FT_ID_DMA_BUFFER_SETUP                  0x0002
00050 #define FT_ID_DMA_BUFF_ALIGN                    0x0003
00051 #define FT_ID_DMA_CONCAT_SETUP                  0x0004
00052 #define FT_ID_DMA_CIRCULAR                              0x0005
00053 #define FT_ID_THRESHOLD_SETUP                   0x0006
00054 #define FT_ID_DFIFO_DEPTH                               0x0007
00055 #define FT_ID_TX_FIFO_DEPTH                             0x0008
00056 #define FT_ID_RX_FIFO_DEPTH                             0x0009
00057 
00058 /**********************************************************/
00059 #define CFI_INFO_DEF
00060 
00061 #ifdef CFI_INFO_DEF
00062 #define CFI_INFO(fmt...)        DWC_PRINTF("CFI: " fmt);
00063 #else
00064 #define CFI_INFO(fmt...)
00065 #endif
00066 
00067 #define min(x,y) ({ \
00068         x < y ? x : y; })
00069 
00070 #define max(x,y) ({ \
00071         x > y ? x : y; })
00072 
00077 struct _ddma_sg_buffer_setup {
00078 #define BS_SG_VAL_DESC_LEN      6
00079         /* The OUT EP address */
00080         uint8_t bOutEndpointAddress;
00081         /* The IN EP address */
00082         uint8_t bInEndpointAddress;
00083         /* Number of bytes to put between transfer segments (must be DWORD boundaries) */
00084         uint8_t bOffset;
00085         /* The number of transfer segments (a DMA descriptors per each segment) */
00086         uint8_t bCount;
00087         /* Size (in byte) of each transfer segment */
00088         uint16_t wSize;
00089 } __attribute__ ((packed));
00090 typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t;
00091 
00093 struct _ddma_concat_buffer_setup_hdr {
00094 #define BS_CONCAT_VAL_HDR_LEN   4
00095         /* The endpoint for which the buffer is to be set up */
00096         uint8_t bEndpointAddress;
00097         /* The count of descriptors to be used */
00098         uint8_t bDescCount;
00099         /* The total size of the transfer */
00100         uint16_t wSize;
00101 } __attribute__ ((packed));
00102 typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t;
00103 
00105 struct _ddma_concat_buffer_setup {
00106         /* The SG header */
00107         ddma_concat_buffer_setup_hdr_t hdr;
00108 
00109         /* The XFER sizes pointer (allocated dynamically) */
00110         uint16_t *wTxBytes;
00111 } __attribute__ ((packed));
00112 typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t;
00113 
00115 struct _ddma_align_buffer_setup {
00116 #define BS_ALIGN_VAL_HDR_LEN    2
00117         uint8_t bEndpointAddress;
00118         uint8_t bAlign;
00119 } __attribute__ ((packed));
00120 typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t;
00121 
00123 struct _tx_fifo_size_setup {
00124         uint8_t bEndpointAddress;
00125         uint16_t wDepth;
00126 } __attribute__ ((packed));
00127 typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t;
00128 
00130 struct _rx_fifo_size_setup {
00131         uint16_t wDepth;
00132 } __attribute__ ((packed));
00133 typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t;
00134 
00140 struct cfi_usb_ctrlrequest {
00141         uint8_t bRequestType;
00142         uint8_t bRequest;
00143         uint16_t wValue;
00144         uint16_t wIndex;
00145         uint16_t wLength;
00146         uint8_t *data;
00147 } UPACKED;
00148 
00149 /*---------------------------------------------------------------------------*/
00150 
00156 struct cfi_ep {
00157         /* Entry for the list container */
00158         dwc_list_link_t lh;
00159         /* Pointer to the active PCD endpoint structure */
00160         struct dwc_otg_pcd_ep *ep;
00161         /* The last descriptor in the chain of DMA descriptors of the endpoint */
00162         struct dwc_otg_dma_desc *dma_desc_last;
00163         /* The SG feature value */
00164         ddma_sg_buffer_setup_t *bm_sg;
00165         /* The Circular feature value */
00166         ddma_sg_buffer_setup_t *bm_circ;
00167         /* The Concatenation feature value */
00168         ddma_concat_buffer_setup_t *bm_concat;
00169         /* The Alignment feature value */
00170         ddma_align_buffer_setup_t *bm_align;
00171         /* XFER length */
00172         uint32_t xfer_len;
00173         /* 
00174          * Count of DMA descriptors currently used.
00175          * The total should not exceed the MAX_DMA_DESCS_PER_EP value
00176          * defined in the dwc_otg_cil.h
00177          */
00178         uint32_t desc_count;
00179 };
00180 typedef struct cfi_ep cfi_ep_t;
00181 
00182 typedef struct cfi_dma_buff {
00183 #define CFI_IN_BUF_LEN  1024
00184 #define CFI_OUT_BUF_LEN 1024
00185         dma_addr_t addr;
00186         uint8_t *buf;
00187 } cfi_dma_buff_t;
00188 
00189 struct cfiobject;
00190 
00199 typedef struct cfi_ops {
00200         int (*ep_enable) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
00201                           struct dwc_otg_pcd_ep * ep);
00202         void *(*ep_alloc_buf) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
00203                                struct dwc_otg_pcd_ep * ep, dma_addr_t * dma,
00204                                unsigned size, gfp_t flags);
00205         void (*release) (struct cfiobject * cfi);
00206         int (*ctrl_write_complete) (struct cfiobject * cfi,
00207                                     struct dwc_otg_pcd * pcd);
00208         void (*build_descriptors) (struct cfiobject * cfi,
00209                                    struct dwc_otg_pcd * pcd,
00210                                    struct dwc_otg_pcd_ep * ep,
00211                                    dwc_otg_pcd_request_t * req);
00212 } cfi_ops_t;
00213 
00214 struct cfiobject {
00215         cfi_ops_t ops;
00216         struct dwc_otg_pcd *pcd;
00217         struct usb_gadget *gadget;
00218 
00219         /* Buffers used to send/receive CFI-related request data */
00220         cfi_dma_buff_t buf_in;
00221         cfi_dma_buff_t buf_out;
00222 
00223         /* CFI specific Control request wrapper */
00224         struct cfi_usb_ctrlrequest ctrl_req;
00225 
00226         /* The list of active EP's in the PCD of type cfi_ep_t */
00227         dwc_list_link_t active_eps;
00228 
00229         /* This flag shall control the propagation of a specific request
00230          * to the gadget's processing routines.
00231          * 0 - no gadget handling
00232          * 1 - the gadget needs to know about this request (w/o completing a status 
00233          * phase - just return a 0 to the _setup callback)
00234          */
00235         uint8_t need_gadget_att;
00236 
00237         /* Flag indicating whether the status IN phase needs to be 
00238          * completed by the PCD
00239          */
00240         uint8_t need_status_in_complete;
00241 };
00242 typedef struct cfiobject cfiobject_t;
00243 
00244 #define DUMP_MSG
00245 
00246 #if defined(DUMP_MSG)
00247 static inline void dump_msg(const u8 * buf, unsigned int length)
00248 {
00249         unsigned int start, num, i;
00250         char line[52], *p;
00251 
00252         if (length >= 512)
00253                 return;
00254 
00255         start = 0;
00256         while (length > 0) {
00257                 num = min(length, 16u);
00258                 p = line;
00259                 for (i = 0; i < num; ++i) {
00260                         if (i == 8)
00261                                 *p++ = ' ';
00262                         DWC_SPRINTF(p, " %02x", buf[i]);
00263                         p += 3;
00264                 }
00265                 *p = 0;
00266                 DWC_DEBUG("%6x: %s\n", start, line);
00267                 buf += num;
00268                 start += num;
00269                 length -= num;
00270         }
00271 }
00272 #else
00273 static inline void dump_msg(const u8 * buf, unsigned int length)
00274 {
00275 }
00276 #endif
00277 
00281 static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi,
00282                                                 uint8_t addr)
00283 {
00284         struct cfi_ep *pcfiep;
00285         dwc_list_link_t *tmp;
00286 
00287         DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
00288                 pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
00289 
00290                 if (pcfiep->ep->desc->bEndpointAddress == addr) {
00291                         return pcfiep;
00292                 }
00293         }
00294 
00295         return NULL;
00296 }
00297 
00302 static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi,
00303                                                   struct dwc_otg_pcd_ep *ep)
00304 {
00305         struct cfi_ep *pcfiep = NULL;
00306         dwc_list_link_t *tmp;
00307 
00308         DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
00309                 pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
00310                 if (pcfiep->ep == ep) {
00311                         return pcfiep;
00312                 }
00313         }
00314         return NULL;
00315 }
00316 
00317 int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl);
00318 
00319 #endif                          /* (__DWC_OTG_CFI_H__) */

Generated on Tue May 5 02:22:48 2009 for DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver by  doxygen 1.4.7