--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/wb/api/src/cyaslep2pep.c Wed Mar 03 13:10:32 2010 +0000
@@ -0,0 +1,337 @@
+/* Cypress West Bridge API source file (cyasusb.c)
+## ===========================
+##
+## Copyright Cypress Semiconductor Corporation, 2006-2009,
+## All Rights Reserved
+## UNPUBLISHED, LICENSED SOFTWARE.
+##
+## CONFIDENTIAL AND PROPRIETARY INFORMATION
+## WHICH IS THE PROPERTY OF CYPRESS.
+##
+## Use of this file is governed
+## by the license agreement included in the file
+##
+## <install>/license/license.txt
+##
+## where <install> is the Cypress software
+## installation root directory path.
+##
+## ===========================
+*/
+
+#include "cyashal.h"
+#include "cyasusb.h"
+#include "cyaserr.h"
+#include "cyaslowlevel.h"
+#include "cyasdma.h"
+
+typedef enum CyAsPhysicalEndpointState
+{
+ CyAsEPFree,
+ CyAsEPIn,
+ CyAsEPOut,
+ CyAsEPIsoIn,
+ CyAsEPIsoOut
+} CyAsPhysicalEndpointState;
+
+
+/*
+* This map is used to map an index between 1 and 10 to a logical endpoint number. This
+* is used to map LEP register indexes into actual EP numbers.
+*/
+static CyAsEndPointNumber_t EndPointMap[] = { 3, 5, 7, 9, 10, 11, 12, 13, 14, 15 } ;
+
+#define CY_AS_EPCFG_1024 (1 << 3)
+#define CY_AS_EPCFG_DBL (0x02)
+#define CY_AS_EPCFG_TRIPLE (0x03)
+#define CY_AS_EPCFG_QUAD (0x00)
+
+/*
+ * NB: This table contains the register values for PEP1 and PEP3. PEP2 and PEP4 only
+ * have a bit to change the direction of the PEP and therefre are not represented
+ * in this table.
+ */
+static uint8_t PepRegisterValues[12][4] =
+{
+ /* Bit 1:0 buffering, 0 = quad, 2 = double, 3 = triple */
+ /* Bit 3 size, 0 = 512, 1 = 1024 */
+ {
+ CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_DBL,
+ }, /* Config 1 - PEP1 (2 * 512), PEP2 (2 * 512), PEP3 (2 * 512), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_QUAD,
+ }, /* Config 2 - PEP1 (2 * 512), PEP2 (2 * 512), PEP3 (4 * 512), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_DBL | CY_AS_EPCFG_1024,
+ }, /* Config 3 - PEP1 (2 * 512), PEP2 (2 * 512), PEP3 (2 * 1024), PEP4(N/A) */
+ {
+ CY_AS_EPCFG_QUAD,
+ CY_AS_EPCFG_DBL,
+ }, /* Config 4 - PEP1 (4 * 512), PEP2 (N/A), PEP3 (2 * 512), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_QUAD,
+ CY_AS_EPCFG_QUAD,
+ }, /* Config 5 - PEP1 (4 * 512), PEP2 (N/A), PEP3 (4 * 512), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_QUAD,
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ }, /* Config 6 - PEP1 (4 * 512), PEP2 (N/A), PEP3 (2 * 1024), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_DBL,
+ }, /* Config 7 - PEP1 (2 * 1024), PEP2 (N/A), PEP3 (2 * 512), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_QUAD,
+ }, /* Config 8 - PEP1 (2 * 1024), PEP2 (N/A), PEP3 (4 * 512), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ }, /* Config 9 - PEP1 (2 * 1024), PEP2 (N/A), PEP3 (2 * 1024), PEP4 (N/A)*/
+ {
+ CY_AS_EPCFG_TRIPLE,
+ CY_AS_EPCFG_TRIPLE,
+ }, /* Config 10 - PEP1 (3 * 512), PEP2 (N/A), PEP3 (3 * 512), PEP4 (2 * 512)*/
+ {
+ CY_AS_EPCFG_TRIPLE | CY_AS_EPCFG_1024,
+ CY_AS_EPCFG_DBL,
+ }, /* Config 11 - PEP1 (3 * 1024), PEP2 (N/A), PEP3 (N/A), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_QUAD | CY_AS_EPCFG_1024,
+ CY_AS_EPCFG_DBL,
+ }, /* Config 12 - PEP1 (4 * 1024), PEP2 (N/A), PEP3 (N/A), PEP4 (N/A) */
+} ;
+
+static CyAsReturnStatus_t
+FindEndpointDirections(CyAsDevice *dev_p, CyAsPhysicalEndpointState epstate[4])
+{
+ int i ;
+ CyAsPhysicalEndpointState desired ;
+
+ /*
+ * Note, there is no error checking here becuase ISO error checking happens when
+ * the API is called.
+ */
+ for(i = 0 ; i < 10 ; i++)
+ {
+ int epno = EndPointMap[i] ;
+ if (dev_p->usb_config[epno].enabled)
+ {
+ int pep = dev_p->usb_config[epno].physical ;
+ if (dev_p->usb_config[epno].type == CyAsUsbIso)
+ {
+ /*
+ * Marking this as an ISO endpoint, removes the physical EP from consideration when
+ * mapping the remaining EPs.
+ */
+ if (dev_p->usb_config[epno].dir == CyAsUsbIn)
+ desired = CyAsEPIsoIn ;
+ else
+ desired = CyAsEPIsoOut ;
+ }
+ else
+ {
+ if (dev_p->usb_config[epno].dir == CyAsUsbIn)
+ desired = CyAsEPIn ;
+ else
+ desired = CyAsEPOut ;
+ }
+
+ /* NB: Note the API calls insure that an ISO endpoint has a physical and logical
+ * EP number that are the same, therefore this condition is not enforced here.
+ */
+ if (epstate[pep - 1] != CyAsEPFree && epstate[pep - 1] != desired)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ epstate[pep - 1] = desired ;
+ }
+ }
+
+ /*
+ * Create the EP1 config values directly.
+ * Both EP1OUT and EP1IN are invalid by default.
+ */
+ dev_p->usb_ep1cfg[0] = 0 ;
+ dev_p->usb_ep1cfg[1] = 0 ;
+ if (dev_p->usb_config[1].enabled)
+ {
+ if ((dev_p->usb_config[1].dir == CyAsUsbOut) || (dev_p->usb_config[1].dir == CyAsUsbInOut))
+ {
+ /* Set the valid bit and type field. */
+ dev_p->usb_ep1cfg[0] = (1 << 7) ;
+ if (dev_p->usb_config[1].type == CyAsUsbBulk)
+ dev_p->usb_ep1cfg[0] |= (2 << 4) ;
+ else
+ dev_p->usb_ep1cfg[0] |= (3 << 4) ;
+ }
+
+ if ((dev_p->usb_config[1].dir == CyAsUsbIn) || (dev_p->usb_config[1].dir == CyAsUsbInOut))
+ {
+ /* Set the valid bit and type field. */
+ dev_p->usb_ep1cfg[1] = (1 << 7) ;
+ if (dev_p->usb_config[1].type == CyAsUsbBulk)
+ dev_p->usb_ep1cfg[1] |= (2 << 4) ;
+ else
+ dev_p->usb_ep1cfg[1] |= (3 << 4) ;
+ }
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+CreateRegisterSettings(CyAsDevice *dev_p, CyAsPhysicalEndpointState epstate[4])
+{
+ int i ;
+ uint8_t v ;
+
+ for(i = 0 ; i < 4 ; i++)
+ {
+ if (i == 0)
+ dev_p->usb_pepcfg[i] = PepRegisterValues[dev_p->usb_phy_config - 1][0] ; /* Start with the values that specify size */
+ else if (i == 2)
+ dev_p->usb_pepcfg[i] = PepRegisterValues[dev_p->usb_phy_config - 1][1] ; /* Start with the values that specify size */
+ else
+ dev_p->usb_pepcfg[i] = 0 ;
+
+ if (epstate[i] == CyAsEPIsoIn || epstate[i] == CyAsEPIn)
+ dev_p->usb_pepcfg[i] |= (1 << 6) ; /* Adjust direction if it is in */
+ }
+
+ /* Configure the logical EP registers */
+ for(i = 0 ; i < 10 ; i++)
+ {
+ int val ;
+ int epnum = EndPointMap[i] ;
+
+ v = 0x10 ; /* PEP 1, Bulk Endpoint, EP not valid */
+ if (dev_p->usb_config[epnum].enabled)
+ {
+ v |= (1 << 7) ; /* Enabled */
+
+ val = dev_p->usb_config[epnum].physical - 1 ;
+ CyAsHalAssert(val >= 0 && val <= 3) ;
+ v |= (val << 5) ;
+
+ switch(dev_p->usb_config[epnum].type)
+ {
+ case CyAsUsbBulk:
+ val = 2 ;
+ break ;
+ case CyAsUsbInt:
+ val = 3 ;
+ break ;
+ case CyAsUsbIso:
+ val = 1 ;
+ break ;
+ default:
+ CyAsHalAssert(CyFalse) ;
+ break ;
+ }
+ v |= (val << 3) ;
+ }
+
+ dev_p->usb_lepcfg[i] = v ;
+ }
+}
+
+
+CyAsReturnStatus_t
+CyAsUsbMapLogical2Physical(CyAsDevice *dev_p)
+{
+ CyAsReturnStatus_t ret ;
+
+ /* Physical EPs 3 5 7 9 respectively in the array */
+ CyAsPhysicalEndpointState epstate[4] = { CyAsEPFree, CyAsEPFree, CyAsEPFree, CyAsEPFree } ;
+
+ /* Find the direction for the endpoints */
+ ret = FindEndpointDirections(dev_p, epstate) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /*
+ * Now create the register settings based on the given assigned of logical EPs to
+ * physical endpoints.
+ */
+ CreateRegisterSettings(dev_p, epstate) ;
+
+ return ret ;
+}
+
+static uint16_t
+GetMaxDmaSize(CyAsDevice *dev_p, CyAsEndPointNumber_t ep)
+{
+ uint16_t size = dev_p->usb_config[ep].size ;
+
+ if (size == 0)
+ {
+ switch(dev_p->usb_config[ep].type)
+ {
+ case CyAsUsbControl:
+ size = 64 ;
+ break ;
+
+ case CyAsUsbBulk:
+ size = CyAsDeviceIsUsbHighSpeed(dev_p) ? 512 : 64 ;
+ break ;
+
+ case CyAsUsbInt:
+ size = CyAsDeviceIsUsbHighSpeed(dev_p) ? 1024 : 64 ;
+ break ;
+
+ case CyAsUsbIso:
+ size = CyAsDeviceIsUsbHighSpeed(dev_p) ? 1024 : 1023 ;
+ break ;
+ }
+ }
+
+ return size ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbSetDmaSizes(CyAsDevice *dev_p)
+{
+ CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+ uint32_t i ;
+
+ for(i = 0 ; i < 10 ; i++)
+ {
+ CyAsUsbEndPointConfig *config_p = &dev_p->usb_config[EndPointMap[i]] ;
+ if (config_p->enabled)
+ {
+ ret = CyAsDmaSetMaxDmaSize(dev_p, EndPointMap[i], GetMaxDmaSize(dev_p, EndPointMap[i])) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ break ;
+ }
+ }
+
+ return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbSetupDma(CyAsDevice *dev_p)
+{
+ CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+ uint32_t i ;
+
+ for(i = 0 ; i < 10 ; i++)
+ {
+ CyAsUsbEndPointConfig *config_p = &dev_p->usb_config[EndPointMap[i]] ;
+ if (config_p->enabled)
+ {
+ /* Map the endpoint direction to the DMA direction */
+ CyAsDmaDirection dir = CyAsDirectionOut ;
+ if (config_p->dir == CyAsUsbIn)
+ dir = CyAsDirectionIn ;
+
+ ret = CyAsDmaEnableEndPoint(dev_p, EndPointMap[i], CyTrue, dir) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ break ;
+ }
+ }
+
+ return ret ;
+}