omap3530/beagle_drivers/wb/api/src/cyaslep2pep.c
changeset 27 117faf51deac
equal deleted inserted replaced
26:b7e488c49d0d 27:117faf51deac
       
     1 /* Cypress West Bridge API source file (cyasusb.c)
       
     2 ## ===========================
       
     3 ##
       
     4 ##  Copyright Cypress Semiconductor Corporation, 2006-2009,
       
     5 ##  All Rights Reserved
       
     6 ##  UNPUBLISHED, LICENSED SOFTWARE.
       
     7 ##
       
     8 ##  CONFIDENTIAL AND PROPRIETARY INFORMATION
       
     9 ##  WHICH IS THE PROPERTY OF CYPRESS.
       
    10 ##
       
    11 ##  Use of this file is governed
       
    12 ##  by the license agreement included in the file
       
    13 ##
       
    14 ##     <install>/license/license.txt
       
    15 ##
       
    16 ##  where <install> is the Cypress software
       
    17 ##  installation root directory path.
       
    18 ##
       
    19 ## ===========================
       
    20 */
       
    21 
       
    22 #include "cyashal.h"
       
    23 #include "cyasusb.h"
       
    24 #include "cyaserr.h"
       
    25 #include "cyaslowlevel.h"
       
    26 #include "cyasdma.h"
       
    27 
       
    28 typedef enum CyAsPhysicalEndpointState
       
    29 {
       
    30     CyAsEPFree,
       
    31     CyAsEPIn,
       
    32     CyAsEPOut,
       
    33     CyAsEPIsoIn,
       
    34     CyAsEPIsoOut
       
    35 } CyAsPhysicalEndpointState;
       
    36 
       
    37 
       
    38 /*
       
    39 * This map is used to map an index between 1 and 10 to a logical endpoint number.  This
       
    40 * is used to map LEP register indexes into actual EP numbers.
       
    41 */
       
    42 static CyAsEndPointNumber_t EndPointMap[] = { 3, 5, 7, 9, 10, 11, 12, 13, 14, 15 } ;
       
    43 
       
    44 #define CY_AS_EPCFG_1024            (1 << 3)
       
    45 #define CY_AS_EPCFG_DBL             (0x02)
       
    46 #define CY_AS_EPCFG_TRIPLE          (0x03)
       
    47 #define CY_AS_EPCFG_QUAD            (0x00)
       
    48 
       
    49 /*
       
    50  * NB: This table contains the register values for PEP1 and PEP3.  PEP2 and PEP4 only
       
    51  *     have a bit to change the direction of the PEP and therefre are not represented
       
    52  *     in this table.
       
    53  */
       
    54 static uint8_t PepRegisterValues[12][4] =
       
    55 {
       
    56     /* Bit 1:0 buffering, 0 = quad, 2 = double, 3 = triple */
       
    57     /* Bit 3 size, 0 = 512, 1 = 1024 */
       
    58     { 
       
    59         CY_AS_EPCFG_DBL, 
       
    60         CY_AS_EPCFG_DBL, 
       
    61     },      /* Config 1  - PEP1 (2 * 512), PEP2 (2 * 512), PEP3 (2 * 512), PEP4 (2 * 512) */
       
    62     { 
       
    63         CY_AS_EPCFG_DBL, 
       
    64         CY_AS_EPCFG_QUAD, 
       
    65     },      /* Config 2  - PEP1 (2 * 512), PEP2 (2 * 512), PEP3 (4 * 512), PEP4 (N/A) */
       
    66     { 
       
    67         CY_AS_EPCFG_DBL, 
       
    68         CY_AS_EPCFG_DBL | CY_AS_EPCFG_1024, 
       
    69     },      /* Config 3  - PEP1 (2 * 512), PEP2 (2 * 512), PEP3 (2 * 1024), PEP4(N/A) */
       
    70     { 
       
    71         CY_AS_EPCFG_QUAD, 
       
    72         CY_AS_EPCFG_DBL, 
       
    73     },      /* Config 4  - PEP1 (4 * 512), PEP2 (N/A), PEP3 (2 * 512), PEP4 (2 * 512) */
       
    74     { 
       
    75         CY_AS_EPCFG_QUAD, 
       
    76         CY_AS_EPCFG_QUAD, 
       
    77     },      /* Config 5  - PEP1 (4 * 512), PEP2 (N/A), PEP3 (4 * 512), PEP4 (N/A) */
       
    78     { 
       
    79         CY_AS_EPCFG_QUAD, 
       
    80         CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, 
       
    81     },      /* Config 6  - PEP1 (4 * 512), PEP2 (N/A), PEP3 (2 * 1024), PEP4 (N/A) */
       
    82     { 
       
    83         CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, 
       
    84         CY_AS_EPCFG_DBL, 
       
    85     },      /* Config 7  - PEP1 (2 * 1024), PEP2 (N/A), PEP3 (2 * 512), PEP4 (2 * 512) */
       
    86     { 
       
    87         CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, 
       
    88         CY_AS_EPCFG_QUAD, 
       
    89     },      /* Config 8  - PEP1 (2 * 1024), PEP2 (N/A), PEP3 (4 * 512), PEP4 (N/A) */
       
    90     { 
       
    91         CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, 
       
    92         CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, 
       
    93     },      /* Config 9  - PEP1 (2 * 1024), PEP2 (N/A), PEP3 (2 * 1024), PEP4 (N/A)*/
       
    94     { 
       
    95         CY_AS_EPCFG_TRIPLE, 
       
    96         CY_AS_EPCFG_TRIPLE, 
       
    97     },      /* Config 10 - PEP1 (3 * 512), PEP2 (N/A), PEP3 (3 * 512), PEP4 (2 * 512)*/
       
    98     { 
       
    99         CY_AS_EPCFG_TRIPLE | CY_AS_EPCFG_1024, 
       
   100         CY_AS_EPCFG_DBL,
       
   101     },      /* Config 11 - PEP1 (3 * 1024), PEP2 (N/A), PEP3 (N/A), PEP4 (2 * 512) */
       
   102     { 
       
   103         CY_AS_EPCFG_QUAD | CY_AS_EPCFG_1024, 
       
   104         CY_AS_EPCFG_DBL,
       
   105     },      /* Config 12 - PEP1 (4 * 1024), PEP2 (N/A), PEP3 (N/A), PEP4 (N/A) */
       
   106 } ;
       
   107 
       
   108 static CyAsReturnStatus_t
       
   109 FindEndpointDirections(CyAsDevice *dev_p, CyAsPhysicalEndpointState epstate[4])
       
   110 {
       
   111     int i ;
       
   112     CyAsPhysicalEndpointState desired ;
       
   113 
       
   114     /*
       
   115      * Note, there is no error checking here becuase ISO error checking happens when
       
   116      * the API is called.
       
   117      */
       
   118     for(i = 0 ; i < 10 ; i++)
       
   119     {
       
   120         int epno = EndPointMap[i] ;
       
   121         if (dev_p->usb_config[epno].enabled)
       
   122         {
       
   123             int pep = dev_p->usb_config[epno].physical ;
       
   124             if (dev_p->usb_config[epno].type == CyAsUsbIso)
       
   125             {
       
   126                 /*
       
   127                  * Marking this as an ISO endpoint, removes the physical EP from consideration when
       
   128                  * mapping the remaining EPs.
       
   129                  */
       
   130                 if (dev_p->usb_config[epno].dir == CyAsUsbIn)
       
   131                     desired = CyAsEPIsoIn ;
       
   132                 else
       
   133                     desired = CyAsEPIsoOut ;
       
   134             }
       
   135             else
       
   136             {
       
   137                 if (dev_p->usb_config[epno].dir == CyAsUsbIn)
       
   138                     desired = CyAsEPIn ;
       
   139                 else
       
   140                     desired = CyAsEPOut ;
       
   141             }
       
   142 
       
   143             /* NB: Note the API calls insure that an ISO endpoint has a physical and logical
       
   144              *     EP number that are the same, therefore this condition is not enforced here.
       
   145              */
       
   146             if (epstate[pep - 1] != CyAsEPFree && epstate[pep - 1] != desired)
       
   147                 return CY_AS_ERROR_INVALID_CONFIGURATION ;
       
   148 
       
   149             epstate[pep - 1] = desired ;
       
   150         }
       
   151     }
       
   152 
       
   153     /*
       
   154      * Create the EP1 config values directly.
       
   155      * Both EP1OUT and EP1IN are invalid by default.
       
   156      */
       
   157     dev_p->usb_ep1cfg[0] = 0 ;
       
   158     dev_p->usb_ep1cfg[1] = 0 ;
       
   159     if (dev_p->usb_config[1].enabled)
       
   160     {
       
   161         if ((dev_p->usb_config[1].dir == CyAsUsbOut) || (dev_p->usb_config[1].dir == CyAsUsbInOut))
       
   162         {
       
   163             /* Set the valid bit and type field. */
       
   164             dev_p->usb_ep1cfg[0] = (1 << 7) ;
       
   165             if (dev_p->usb_config[1].type == CyAsUsbBulk)
       
   166                 dev_p->usb_ep1cfg[0] |= (2 << 4) ;
       
   167             else
       
   168                 dev_p->usb_ep1cfg[0] |= (3 << 4) ;
       
   169         }
       
   170 
       
   171         if ((dev_p->usb_config[1].dir == CyAsUsbIn) || (dev_p->usb_config[1].dir == CyAsUsbInOut))
       
   172         {
       
   173             /* Set the valid bit and type field. */
       
   174             dev_p->usb_ep1cfg[1] = (1 << 7) ;
       
   175             if (dev_p->usb_config[1].type == CyAsUsbBulk)
       
   176                 dev_p->usb_ep1cfg[1] |= (2 << 4) ;
       
   177             else
       
   178                 dev_p->usb_ep1cfg[1] |= (3 << 4) ;
       
   179         }
       
   180     }
       
   181 
       
   182     return CY_AS_ERROR_SUCCESS ;
       
   183 }
       
   184 
       
   185 static void
       
   186 CreateRegisterSettings(CyAsDevice *dev_p, CyAsPhysicalEndpointState epstate[4])
       
   187 {
       
   188     int i ;
       
   189     uint8_t v ;
       
   190 
       
   191     for(i = 0 ; i < 4 ; i++)
       
   192     {
       
   193         if (i == 0)
       
   194             dev_p->usb_pepcfg[i] = PepRegisterValues[dev_p->usb_phy_config - 1][0] ;    /* Start with the values that specify size */
       
   195         else if (i == 2)
       
   196             dev_p->usb_pepcfg[i] = PepRegisterValues[dev_p->usb_phy_config - 1][1] ;    /* Start with the values that specify size */
       
   197         else
       
   198             dev_p->usb_pepcfg[i] = 0 ;
       
   199 
       
   200         if (epstate[i] == CyAsEPIsoIn || epstate[i] == CyAsEPIn)
       
   201             dev_p->usb_pepcfg[i] |= (1 << 6) ;                                          /* Adjust direction if it is in */
       
   202     }
       
   203 
       
   204     /* Configure the logical EP registers */
       
   205     for(i = 0 ; i < 10 ; i++)
       
   206     {
       
   207         int val ;
       
   208         int epnum = EndPointMap[i] ;
       
   209 
       
   210         v = 0x10 ;      /* PEP 1, Bulk Endpoint, EP not valid */
       
   211         if (dev_p->usb_config[epnum].enabled)
       
   212         {
       
   213             v |= (1 << 7) ;                                             /* Enabled */
       
   214 
       
   215             val = dev_p->usb_config[epnum].physical - 1 ;
       
   216             CyAsHalAssert(val >= 0 && val <= 3) ;
       
   217             v |= (val << 5) ;
       
   218 
       
   219             switch(dev_p->usb_config[epnum].type)
       
   220             {
       
   221             case CyAsUsbBulk:
       
   222                 val = 2 ;
       
   223                 break ;
       
   224             case CyAsUsbInt:
       
   225                 val = 3 ;
       
   226                 break ;
       
   227             case CyAsUsbIso:
       
   228                 val = 1 ;
       
   229                 break ;
       
   230             default:
       
   231                 CyAsHalAssert(CyFalse) ;
       
   232                 break ;
       
   233             }
       
   234             v |= (val << 3) ;
       
   235         }
       
   236 
       
   237         dev_p->usb_lepcfg[i] = v ;
       
   238     }
       
   239 }
       
   240 
       
   241 
       
   242 CyAsReturnStatus_t
       
   243 CyAsUsbMapLogical2Physical(CyAsDevice *dev_p)
       
   244 {
       
   245     CyAsReturnStatus_t ret ;
       
   246 
       
   247     /* Physical EPs 3 5 7 9 respectively in the array */
       
   248     CyAsPhysicalEndpointState epstate[4] = { CyAsEPFree, CyAsEPFree, CyAsEPFree, CyAsEPFree } ;
       
   249 
       
   250     /* Find the direction for the endpoints */
       
   251     ret = FindEndpointDirections(dev_p, epstate) ;
       
   252     if (ret != CY_AS_ERROR_SUCCESS)
       
   253         return ret ;
       
   254 
       
   255     /*
       
   256      * Now create the register settings based on the given assigned of logical EPs to
       
   257      * physical endpoints.
       
   258      */
       
   259     CreateRegisterSettings(dev_p, epstate) ;
       
   260 
       
   261     return ret ;
       
   262 }
       
   263 
       
   264 static uint16_t
       
   265 GetMaxDmaSize(CyAsDevice *dev_p, CyAsEndPointNumber_t ep)
       
   266 {
       
   267     uint16_t size = dev_p->usb_config[ep].size ;
       
   268 
       
   269     if (size == 0)
       
   270     {
       
   271         switch(dev_p->usb_config[ep].type)
       
   272         {
       
   273         case CyAsUsbControl:
       
   274             size = 64 ;
       
   275             break ;
       
   276 
       
   277         case CyAsUsbBulk:
       
   278             size = CyAsDeviceIsUsbHighSpeed(dev_p) ? 512 : 64 ;
       
   279             break ;
       
   280 
       
   281         case CyAsUsbInt:
       
   282             size = CyAsDeviceIsUsbHighSpeed(dev_p) ? 1024 : 64 ;
       
   283             break ;
       
   284 
       
   285         case CyAsUsbIso:
       
   286             size = CyAsDeviceIsUsbHighSpeed(dev_p) ? 1024 : 1023 ;
       
   287             break ;
       
   288         }
       
   289     }
       
   290 
       
   291     return size ;
       
   292 }
       
   293 
       
   294 CyAsReturnStatus_t
       
   295 CyAsUsbSetDmaSizes(CyAsDevice *dev_p)
       
   296 {
       
   297     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   298     uint32_t i ;
       
   299 
       
   300     for(i = 0 ; i < 10 ; i++)
       
   301     {
       
   302         CyAsUsbEndPointConfig *config_p = &dev_p->usb_config[EndPointMap[i]] ;
       
   303         if (config_p->enabled)
       
   304         {
       
   305             ret = CyAsDmaSetMaxDmaSize(dev_p, EndPointMap[i], GetMaxDmaSize(dev_p, EndPointMap[i])) ;
       
   306             if (ret != CY_AS_ERROR_SUCCESS)
       
   307                 break ;
       
   308         }
       
   309     }
       
   310 
       
   311     return ret ;
       
   312 }
       
   313 
       
   314 CyAsReturnStatus_t
       
   315 CyAsUsbSetupDma(CyAsDevice *dev_p)
       
   316 {
       
   317     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   318     uint32_t i ;
       
   319 
       
   320     for(i = 0 ; i < 10 ; i++)
       
   321     {
       
   322         CyAsUsbEndPointConfig *config_p = &dev_p->usb_config[EndPointMap[i]] ;
       
   323         if (config_p->enabled)
       
   324         {
       
   325             /* Map the endpoint direction to the DMA direction */
       
   326             CyAsDmaDirection dir = CyAsDirectionOut ;
       
   327             if (config_p->dir == CyAsUsbIn)
       
   328                 dir = CyAsDirectionIn ;
       
   329 
       
   330             ret = CyAsDmaEnableEndPoint(dev_p, EndPointMap[i], CyTrue, dir) ;
       
   331             if (ret != CY_AS_ERROR_SUCCESS)
       
   332                 break ;
       
   333         }
       
   334     }
       
   335 
       
   336     return ret ;
       
   337 }