omap3530/beagle_drivers/wb/api/src/cyasmisc.c
changeset 27 117faf51deac
child 52 254b9435d75e
equal deleted inserted replaced
26:b7e488c49d0d 27:117faf51deac
       
     1 /* Cypress West Bridge API source file (cyasmisc.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 "cyasmisc.h"
       
    24 #include "cyasdma.h"
       
    25 #include "cyasintr.h"
       
    26 #include "cyaserr.h"
       
    27 #include "cyasregs.h"
       
    28 #include "cyaslowlevel.h"
       
    29 #include "cyasprotocol.h"
       
    30 
       
    31 /*
       
    32 * The device list, the only global in the API
       
    33 */
       
    34 static CyAsDevice *gDeviceList = 0 ;
       
    35 
       
    36 /*
       
    37  * The current debug level
       
    38  */
       
    39 static uint8_t DebugLevel = 0 ;
       
    40 
       
    41 /*
       
    42  * This function sets the debug level for the API
       
    43  *
       
    44  */
       
    45 void
       
    46 CyAsMiscSetLogLevel(uint8_t level)
       
    47 {
       
    48     DebugLevel = level ;
       
    49 }
       
    50 
       
    51 #ifdef CY_AS_LOG_SUPPORT
       
    52 
       
    53 /*
       
    54  * This function is a low level logger for the API.
       
    55  */
       
    56 void
       
    57 CyAsLogDebugMessage(int level, const char *str)
       
    58 {
       
    59     if (level <= DebugLevel)
       
    60         CyAsHalPrintMessage("Log %d: %s\n", level, str) ;
       
    61 }
       
    62 
       
    63 #endif
       
    64 
       
    65 #define CyAsCheckDeviceReady(dev_p)                                     \
       
    66 {                                                                       \
       
    67     if (!(dev_p) ||((dev_p)->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))     \
       
    68         return CY_AS_ERROR_INVALID_HANDLE ;                             \
       
    69                                                                         \
       
    70     if (!CyAsDeviceIsConfigured(dev_p))                                 \
       
    71         return CY_AS_ERROR_NOT_CONFIGURED ;                             \
       
    72                                                                         \
       
    73     if (!CyAsDeviceIsFirmwareLoaded(dev_p))                             \
       
    74         return CY_AS_ERROR_NO_FIRMWARE ;                                \
       
    75 }
       
    76 
       
    77 /* Find an West Bridge device based on a TAG */
       
    78 CyAsDevice *
       
    79 CyAsDeviceFindFromTag(CyAsHalDeviceTag tag)
       
    80 {
       
    81     CyAsDevice *dev_p ;
       
    82 
       
    83     for(dev_p = gDeviceList; dev_p != 0; dev_p = dev_p->next_p)
       
    84     {
       
    85         if (dev_p->tag == tag)
       
    86             return dev_p ;
       
    87     }
       
    88 
       
    89     return 0 ;
       
    90 }
       
    91 
       
    92 /* Map a pre-V1.2 media type to the V1.2+ bus number */
       
    93 static void
       
    94 CyAsBusFromMediaType(CyAsMediaType type,
       
    95                         CyAsBusNumber_t* bus)
       
    96 {
       
    97     if (type == CyAsMediaNand)
       
    98     {
       
    99         *bus = 0 ;
       
   100     }
       
   101     else
       
   102     {
       
   103         *bus = 1 ;
       
   104     }
       
   105 }
       
   106 
       
   107 static CyAsReturnStatus_t
       
   108 MyHandleResponseNoData(CyAsDevice* dev_p,
       
   109                          CyAsLLRequestResponse *req_p,
       
   110                          CyAsLLRequestResponse *reply_p)
       
   111 {
       
   112     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   113 
       
   114     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   115         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   116     else
       
   117         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   118 
       
   119     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   120     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   121 
       
   122     return ret ;
       
   123 }
       
   124 
       
   125 /*
       
   126 * Create a new West Bridge device
       
   127 */
       
   128 CyAsReturnStatus_t
       
   129 CyAsMiscCreateDevice(CyAsDeviceHandle *handle_p, CyAsHalDeviceTag tag)
       
   130 {
       
   131     CyAsDevice *dev_p ;
       
   132     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   133 
       
   134     CyAsLogDebugMessage(6, "CyAsMiscCreateDevice called") ;
       
   135 
       
   136     dev_p = (CyAsDevice *)CyAsHalAlloc(sizeof(CyAsDevice)) ;
       
   137     if (dev_p == 0)
       
   138         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   139     CyAsHalMemSet(dev_p, 0, sizeof(CyAsDevice)) ;
       
   140 
       
   141     /*
       
   142      * Dynamically allocating this buffer to ensure that it is
       
   143      * word aligned.
       
   144      */
       
   145     dev_p->usb_ep_data = (uint8_t *)CyAsHalAlloc(64 * sizeof(uint8_t)) ;
       
   146     if (dev_p->usb_ep_data == 0)
       
   147     {
       
   148         CyAsHalFree(dev_p) ;
       
   149         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   150     }
       
   151 
       
   152     dev_p->sig = CY_AS_DEVICE_HANDLE_SIGNATURE ;
       
   153     dev_p->tag = tag ;
       
   154     dev_p->usb_max_tx_size = 0x40 ;
       
   155 
       
   156     dev_p->storage_write_endpoint = CY_AS_P2S_WRITE_ENDPOINT ;
       
   157     dev_p->storage_read_endpoint = CY_AS_P2S_READ_ENDPOINT ;
       
   158 
       
   159     dev_p->func_cbs_misc = CyAsCreateCBQueue(CYAS_FUNC_CB) ;
       
   160     if(dev_p->func_cbs_misc == 0)
       
   161         goto destroy ;
       
   162 
       
   163     dev_p->func_cbs_res = CyAsCreateCBQueue(CYAS_FUNC_CB) ;
       
   164     if(dev_p->func_cbs_res == 0)
       
   165         goto destroy ;
       
   166 
       
   167     dev_p->func_cbs_stor = CyAsCreateCBQueue(CYAS_FUNC_CB) ;
       
   168     if(dev_p->func_cbs_stor == 0)
       
   169         goto destroy ;
       
   170 
       
   171     dev_p->func_cbs_usb = CyAsCreateCBQueue(CYAS_FUNC_CB) ;
       
   172     if(dev_p->func_cbs_usb == 0)
       
   173         goto destroy ;
       
   174 
       
   175     dev_p->func_cbs_mtp = CyAsCreateCBQueue(CYAS_FUNC_CB) ;
       
   176     if(dev_p->func_cbs_mtp == 0)
       
   177             goto destroy ;
       
   178 
       
   179     /*
       
   180      * Allocate memory for the DMA module here. It is then marked idle, and
       
   181      * will be activated when CyAsMiscConfigureDevice is called.
       
   182      */
       
   183     ret = CyAsDmaStart(dev_p) ;
       
   184     if (ret != CY_AS_ERROR_SUCCESS)
       
   185         goto destroy ;
       
   186 
       
   187     CyAsDeviceSetDmaStopped(dev_p) ;
       
   188 
       
   189     /*
       
   190      * Allocate memory for the low level module here. This module is also
       
   191      * activated only when CyAsMiscConfigureDevice is called.
       
   192      */
       
   193     ret = CyAsLLStart(dev_p) ;
       
   194     if (ret != CY_AS_ERROR_SUCCESS)
       
   195         goto destroy ;
       
   196 
       
   197     CyAsDeviceSetLowLevelStopped(dev_p) ;
       
   198 
       
   199     dev_p->next_p = gDeviceList ;
       
   200     gDeviceList = dev_p ;
       
   201 
       
   202     *handle_p = dev_p ;
       
   203     CyAsHalInitDevRegisters(tag, CyFalse) ;
       
   204     return CY_AS_ERROR_SUCCESS ;
       
   205 
       
   206 destroy:
       
   207     /* Free any queues that were successfully allocated. */
       
   208     if (dev_p->func_cbs_misc) CyAsDestroyCBQueue(dev_p->func_cbs_misc) ;
       
   209     if (dev_p->func_cbs_res)  CyAsDestroyCBQueue(dev_p->func_cbs_res) ;
       
   210     if (dev_p->func_cbs_stor) CyAsDestroyCBQueue(dev_p->func_cbs_stor) ;
       
   211     if (dev_p->func_cbs_usb)  CyAsDestroyCBQueue(dev_p->func_cbs_usb) ;
       
   212     if (dev_p->func_cbs_mtp)  CyAsDestroyCBQueue(dev_p->func_cbs_mtp) ;
       
   213 
       
   214     CyAsHalFree(dev_p->usb_ep_data) ;
       
   215     CyAsHalFree(dev_p) ;
       
   216 
       
   217     if (ret != CY_AS_ERROR_SUCCESS)
       
   218         return ret ;
       
   219     else
       
   220         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   221 }
       
   222 
       
   223 /*
       
   224 * Destroy an existing West Bridge device
       
   225 */
       
   226 CyAsReturnStatus_t
       
   227 CyAsMiscDestroyDevice(CyAsDeviceHandle handle)
       
   228 {
       
   229     CyAsReturnStatus_t ret ;
       
   230     CyAsDevice *dev_p ;
       
   231 
       
   232     CyAsLogDebugMessage(6, "CyAsMiscDestroyDevice called") ;
       
   233 
       
   234     dev_p = (CyAsDevice *)handle ;
       
   235     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   236         return CY_AS_ERROR_INVALID_HANDLE ;
       
   237 
       
   238     /*
       
   239     * If the USB stack is still running, it must be stopped first
       
   240     */
       
   241     if (dev_p->usb_count > 0)
       
   242         return CY_AS_ERROR_STILL_RUNNING ;
       
   243 
       
   244     /*
       
   245     * If the STORAGE stack is still running, it must be stopped first
       
   246     */
       
   247     if (dev_p->storage_count > 0)
       
   248         return CY_AS_ERROR_STILL_RUNNING ;
       
   249 
       
   250     if(CyAsDeviceIsIntrRunning(dev_p))
       
   251         ret = CyAsIntrStop(dev_p) ;
       
   252 
       
   253     ret = CyAsLLStop(dev_p) ;
       
   254     if (ret != CY_AS_ERROR_SUCCESS)
       
   255     {
       
   256         CyAsIntrStart(dev_p, dev_p->use_int_drq) ;
       
   257         return ret ;
       
   258     }
       
   259 
       
   260     ret = CyAsDmaStop(dev_p) ;
       
   261     if (ret != CY_AS_ERROR_SUCCESS)
       
   262     {
       
   263         CyAsIntrStart(dev_p, dev_p->use_int_drq) ;
       
   264         return ret ;
       
   265     }
       
   266 
       
   267     /* Reset the West Bridge device. */
       
   268     CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_RST_CTRL_REG, CY_AS_MEM_RST_CTRL_REG_HARD) ;
       
   269 
       
   270     /*
       
   271     * Remove the device from the device list
       
   272     */
       
   273     if (gDeviceList == dev_p)
       
   274     {
       
   275         gDeviceList = dev_p->next_p ;
       
   276     }
       
   277     else
       
   278     {
       
   279         CyAsDevice *tmp_p = gDeviceList ;
       
   280         while (tmp_p && tmp_p->next_p != dev_p)
       
   281             tmp_p = tmp_p->next_p ;
       
   282 
       
   283         CyAsHalAssert(tmp_p != 0) ;
       
   284         tmp_p->next_p = dev_p->next_p ;
       
   285     }
       
   286 
       
   287     /*
       
   288     * Reset the signature so this will not be detected
       
   289     * as a valid handle
       
   290     */
       
   291     dev_p->sig = 0 ;
       
   292 
       
   293     CyAsDestroyCBQueue(dev_p->func_cbs_misc) ;
       
   294     CyAsDestroyCBQueue(dev_p->func_cbs_res) ;
       
   295     CyAsDestroyCBQueue(dev_p->func_cbs_stor) ;
       
   296     CyAsDestroyCBQueue(dev_p->func_cbs_usb) ;
       
   297     CyAsDestroyCBQueue(dev_p->func_cbs_mtp) ;
       
   298 
       
   299     /*
       
   300     * Free the memory associated with the device
       
   301     */
       
   302     CyAsHalFree(dev_p->usb_ep_data) ;
       
   303     CyAsHalFree(dev_p) ;
       
   304 
       
   305     return CY_AS_ERROR_SUCCESS ;
       
   306 }
       
   307 
       
   308 /*
       
   309 * Determine the endian mode for the processor we are running on, then
       
   310 * set the endian mode register
       
   311 */
       
   312 static void
       
   313 CyAsSetupEndianMode(CyAsDevice *dev_p)
       
   314 {
       
   315     /*
       
   316     * BWG: In general, we always set West Bridge into the little endian mode.  This
       
   317     *      causes the data on bit 0 internally to come out on data line 0 externally
       
   318     *      and it is generally what we want regardless of the endian mode of the
       
   319     *      processor.  This capability in West Bridge should be labeled as a "SWAP" capability
       
   320     *      and can be used to swap the bytes of data in and out of West Bridge.  This is
       
   321     *      useful if there is DMA hardware that requires this for some reason I cannot
       
   322     *      imagine at this time.  Basically if the wires are connected correctly, we should
       
   323     *      never need to change the endian-ness of West Bridge.
       
   324     */
       
   325     CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_P0_ENDIAN, CY_AS_LITTLE_ENDIAN) ;
       
   326 }
       
   327 
       
   328 /*
       
   329 * Query the West Bridge device and determine if we are an standby mode
       
   330 */
       
   331 CyAsReturnStatus_t
       
   332 CyAsMiscInStandby(CyAsDeviceHandle handle, CyBool *standby)
       
   333 {
       
   334     CyAsDevice *dev_p ;
       
   335 
       
   336     CyAsLogDebugMessage(6, "CyAsMiscInStandby called") ;
       
   337 
       
   338     dev_p = (CyAsDevice *)handle ;
       
   339     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   340         return CY_AS_ERROR_INVALID_HANDLE ;
       
   341 
       
   342     if (CyAsDeviceIsPinStandby(dev_p) || CyAsDeviceIsRegisterStandby(dev_p))
       
   343     {
       
   344         *standby = CyTrue ;
       
   345     }
       
   346     else
       
   347         *standby = CyFalse ;
       
   348 
       
   349     return CY_AS_ERROR_SUCCESS ;
       
   350 }
       
   351 
       
   352 static void
       
   353 CyAsMiscFuncCallback(CyAsDevice *dev_p,
       
   354                         uint8_t context,
       
   355                         CyAsLLRequestResponse *rqt,
       
   356                         CyAsLLRequestResponse *resp,
       
   357                         CyAsReturnStatus_t ret) ;
       
   358 
       
   359 
       
   360 static void
       
   361 MyMiscCallback(CyAsDevice *dev_p, uint8_t context, CyAsLLRequestResponse *req_p, CyAsLLRequestResponse *resp_p,
       
   362                CyAsReturnStatus_t ret)
       
   363 {
       
   364     (void)resp_p ;
       
   365     (void)context ;
       
   366     (void)ret ;
       
   367 
       
   368     switch (CyAsLLRequestResponse_GetCode(req_p))
       
   369     {
       
   370         case CY_RQT_INITIALIZATION_COMPLETE:
       
   371             {
       
   372                 uint16_t v ;
       
   373 
       
   374                 CyAsLLSendStatusResponse(dev_p, CY_RQT_GENERAL_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   375                 CyAsDeviceSetFirmwareLoaded(dev_p) ;
       
   376 
       
   377                 if (CyAsDeviceIsWaking(dev_p))
       
   378                 {
       
   379                     /*
       
   380                      * This is a callback from a CyAsMiscLeaveStandby() request.  In this case we call the
       
   381                      * standby callback and clear the waking state.
       
   382                      */
       
   383                     if (dev_p->misc_event_cb)
       
   384                         dev_p->misc_event_cb((CyAsDeviceHandle)dev_p, CyAsEventMiscAwake, 0) ;
       
   385                     CyAsDeviceClearWaking(dev_p) ;
       
   386                 }
       
   387                 else
       
   388                 {
       
   389                     v = CyAsLLRequestResponse_GetWord(req_p, 3) ;
       
   390 
       
   391                     /*
       
   392                      * Store the media supported on each of the device buses.
       
   393                      */
       
   394                     dev_p->media_supported[0] = (uint8_t)(v & 0xFF) ;
       
   395                     dev_p->media_supported[1] = (uint8_t)((v >> 8) & 0xFF) ;
       
   396 
       
   397                     v = CyAsLLRequestResponse_GetWord(req_p, 4) ;
       
   398                     dev_p->is_mtp_firmware    = (CyBool)((v >> 8) & 0xFF) ;
       
   399 
       
   400                     if (dev_p->misc_event_cb)
       
   401                         dev_p->misc_event_cb((CyAsDeviceHandle)dev_p, CyAsEventMiscInitialized, 0) ;
       
   402                 }
       
   403 
       
   404                 v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_VM_SET) ;
       
   405                 if (v & CY_AS_MEM_P0_VM_SET_CFGMODE)
       
   406                     CyAsHalPrintMessage("Initialization Message Recieved, but config bit still set\n") ;
       
   407 
       
   408                 v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_RST_CTRL_REG) ;
       
   409                 if ((v & CY_AS_MEM_RST_RSTCMPT) ==0)
       
   410                     CyAsHalPrintMessage("Initialization Message Recieved, but reset complete bit still not set\n") ;
       
   411             }
       
   412             break ;
       
   413 
       
   414         case CY_RQT_OUT_OF_SUSPEND:
       
   415             CyAsLLSendStatusResponse(dev_p, CY_RQT_GENERAL_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   416             CyAsDeviceClearSuspendMode(dev_p) ;
       
   417 
       
   418             /*
       
   419              * If the wakeup was caused by an async CyAsMiscLeaveSuspend call, we have to
       
   420              * call the corresponding callback.
       
   421              */
       
   422             if (dev_p->func_cbs_misc->count > 0)
       
   423             {
       
   424                 CyAsFuncCBNode *node = (CyAsFuncCBNode*)dev_p->func_cbs_misc->head_p ;
       
   425                 CyAsHalAssert(node) ;
       
   426 
       
   427                 if (CyAsFunctCBTypeGetType(node->dataType) == CY_FUNCT_CB_MISC_LEAVESUSPEND)
       
   428                 {
       
   429                     CyAsHalAssert(node->cb_p != 0) ;
       
   430                     node->cb_p((CyAsDeviceHandle)dev_p, CY_AS_ERROR_SUCCESS, node->client_data,
       
   431                             CY_FUNCT_CB_MISC_LEAVESUSPEND, 0) ;
       
   432                     CyAsRemoveCBNode(dev_p->func_cbs_misc) ;
       
   433                 }
       
   434             }
       
   435 
       
   436             if (dev_p->misc_event_cb)
       
   437                 dev_p->misc_event_cb((CyAsDeviceHandle)dev_p, CyAsEventMiscWakeup, 0) ;
       
   438             break ;
       
   439 
       
   440         case CY_RQT_DEBUG_MESSAGE:
       
   441             if ((req_p->data[0] == 0) && (req_p->data[1] == 0) && (req_p->data[2] == 0))
       
   442             {
       
   443                 if (dev_p->misc_event_cb)
       
   444                     dev_p->misc_event_cb((CyAsDeviceHandle)dev_p, CyAsEventMiscHeartBeat, 0) ;
       
   445             }
       
   446             else
       
   447             {
       
   448                 CyAsHalPrintMessage("**** Debug Message: %02x %02x %02x %02x %02x %02x\n",
       
   449                         req_p->data[0] & 0xff, (req_p->data[0] >> 8) & 0xff,
       
   450                         req_p->data[1] & 0xff, (req_p->data[1] >> 8) & 0xff,
       
   451                         req_p->data[2] & 0xff, (req_p->data[2] >> 8) & 0xff) ;
       
   452             }
       
   453             break ;
       
   454 
       
   455         case CY_RQT_WB_DEVICE_MISMATCH:
       
   456             {
       
   457                 if (dev_p->misc_event_cb)
       
   458                     dev_p->misc_event_cb((CyAsDeviceHandle)dev_p, CyAsEventMiscDeviceMismatch, 0) ;
       
   459             }
       
   460             break ;
       
   461 
       
   462         case CY_RQT_BOOTLOAD_NO_FIRMWARE:
       
   463             {
       
   464                 /* TODO Handle case when firmware is not found during bootloading. */
       
   465                 CyAsHalPrintMessage("No firmware image found during bootload. Device not started\n") ;
       
   466             }
       
   467             break ;
       
   468 
       
   469         default:
       
   470             CyAsHalAssert (0) ;
       
   471     }
       
   472 }
       
   473 
       
   474 static CyBool
       
   475 IsValidSiliconId(uint16_t v)
       
   476 {
       
   477     CyBool idok = CyFalse ;
       
   478 
       
   479     /*
       
   480     * Remove the revision number from the ID value
       
   481     */
       
   482     v = v & CY_AS_MEM_CM_WB_CFG_ID_HDID_MASK ;
       
   483 
       
   484     /*
       
   485     * If this is West Bridge, then we are OK.
       
   486     */
       
   487     if (v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE ||
       
   488         v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE ||
       
   489         v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE)
       
   490         idok = CyTrue ;
       
   491 
       
   492     return idok ;
       
   493 }
       
   494 
       
   495 /*
       
   496 * Configure the West Bridge device hardware
       
   497 */
       
   498 CyAsReturnStatus_t
       
   499 CyAsMiscConfigureDevice(CyAsDeviceHandle handle, CyAsDeviceConfig *config_p)
       
   500 {
       
   501     CyAsReturnStatus_t ret ;
       
   502     CyBool standby ;
       
   503     CyAsDevice *dev_p ;
       
   504     uint16_t v ;
       
   505     uint16_t fw_present;
       
   506     CyAsLogDebugMessage(6, "CyAsMiscConfigureDevice called") ;
       
   507 
       
   508     dev_p = (CyAsDevice *)handle ;
       
   509     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   510         return CY_AS_ERROR_INVALID_HANDLE ;
       
   511 
       
   512     /* Setup big endian vs little endian */
       
   513     CyAsSetupEndianMode(dev_p) ;
       
   514 
       
   515     /* Now, confirm that we can talk to the West Bridge device */
       
   516     dev_p->silicon_id = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_CM_WB_CFG_ID) ;
       
   517     fw_present = CyAsHalReadRegister(dev_p->tag,CY_AS_MEM_RST_CTRL_REG ) ;
       
   518     if (!(fw_present & CY_AS_MEM_RST_RSTCMPT))
       
   519     {
       
   520         if (!IsValidSiliconId(dev_p->silicon_id))
       
   521             return CY_AS_ERROR_NO_ANTIOCH ;
       
   522     }
       
   523     /* Check for standby mode */
       
   524     ret = CyAsMiscInStandby(handle, &standby) ;
       
   525     if (ret != CY_AS_ERROR_SUCCESS)
       
   526         return ret ;
       
   527     if (ret)
       
   528         return CY_AS_ERROR_IN_STANDBY ;
       
   529 
       
   530     /* Setup P-port interface mode (CRAM / SRAM). */
       
   531     if (CyAsDeviceIsAstoriaDev(dev_p))
       
   532     {
       
   533         if (config_p->srammode)
       
   534             v = CY_AS_MEM_P0_VM_SET_VMTYPE_SRAM ;
       
   535         else
       
   536             v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM ;
       
   537     }
       
   538     else
       
   539         v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM ;
       
   540 
       
   541     /* Setup synchronous versus asynchronous mode */
       
   542     if (config_p->sync)
       
   543         v |= CY_AS_MEM_P0_VM_SET_IFMODE ;
       
   544     if (config_p->dackmode == CyAsDeviceDackAck)
       
   545         v |= CY_AS_MEM_P0_VM_SET_DACKEOB ;
       
   546     if (config_p->drqpol)
       
   547         v |= CY_AS_MEM_P0_VM_SET_DRQPOL ;
       
   548     if (config_p->dackpol)
       
   549         v |= CY_AS_MEM_P0_VM_SET_DACKPOL ;
       
   550     CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_P0_VM_SET, v) ;
       
   551 
       
   552     if (config_p->crystal)
       
   553         CyAsDeviceSetCrystal(dev_p) ;
       
   554     else
       
   555         CyAsDeviceSetExternalClock(dev_p) ;
       
   556 
       
   557     /* Register a callback to handle MISC requests from the firmware */
       
   558     CyAsLLRegisterRequestCallback(dev_p, CY_RQT_GENERAL_RQT_CONTEXT, MyMiscCallback) ;
       
   559 
       
   560     /* Now mark the DMA and low level modules as active. */
       
   561     CyAsDeviceSetDmaRunning(dev_p) ;
       
   562     CyAsDeviceSetLowLevelRunning(dev_p) ;
       
   563 
       
   564     /* Now, initialize the interrupt module */
       
   565     dev_p->use_int_drq = config_p->dmaintr ;
       
   566 
       
   567     ret = CyAsIntrStart(dev_p, config_p->dmaintr) ;
       
   568     if (ret != CY_AS_ERROR_SUCCESS)
       
   569         return ret ;
       
   570 
       
   571     /* Mark the interface as initialized */
       
   572     CyAsDeviceSetConfigured(dev_p) ;
       
   573 
       
   574     return CY_AS_ERROR_SUCCESS ;
       
   575 }
       
   576 
       
   577 static void
       
   578 MyDmaCallback(CyAsDevice *          dev_p,
       
   579               CyAsEndPointNumber_t  ep,
       
   580               void *                mem_p,
       
   581               uint32_t              size,
       
   582               CyAsReturnStatus_t    ret
       
   583               )
       
   584 {
       
   585     CyAsDmaEndPoint *ep_p ;
       
   586 
       
   587     (void)size ;
       
   588 
       
   589     /* Get the endpoint pointer based on the endpoint number */
       
   590     ep_p = CY_AS_NUM_EP(dev_p, ep) ;
       
   591 
       
   592     /* Check the queue to see if is drained */
       
   593     if (ep_p->queue_p == 0)
       
   594     {
       
   595         CyAsFuncCBNode* node = (CyAsFuncCBNode*)dev_p->func_cbs_misc->head_p ;
       
   596 
       
   597         CyAsHalAssert(node) ;
       
   598 
       
   599         if (ret == CY_AS_ERROR_SUCCESS)
       
   600         {
       
   601             /*
       
   602              * Disable endpoint 2.  The storage module will enable this EP if necessary.
       
   603              */
       
   604             CyAsDmaEnableEndPoint(dev_p, CY_AS_FIRMWARE_ENDPOINT, CyFalse, CyAsDirectionIn) ;
       
   605 
       
   606             /*
       
   607              * Clear the reset register.  This releases the Antioch micro-controller from
       
   608              * reset and begins running the code at address zero.
       
   609              */
       
   610             CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_RST_CTRL_REG, 0x00) ;
       
   611         }
       
   612 
       
   613         /* Call the user Callback */
       
   614         node->cb_p((CyAsDeviceHandle)dev_p, ret, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ;
       
   615         CyAsRemoveCBNode(dev_p->func_cbs_misc) ;
       
   616     }
       
   617     else
       
   618     {
       
   619         /* This is the header data that was allocated in the download firmware function,
       
   620         * and can be safely freed here. */
       
   621         uint32_t state = CyAsHalDisableInterrupts() ;
       
   622         CyAsHalCBFree(mem_p) ;
       
   623         CyAsHalEnableInterrupts(state) ;
       
   624     }
       
   625 }
       
   626 
       
   627 CyAsReturnStatus_t
       
   628 CyAsMiscDownloadFirmware(CyAsDeviceHandle handle,
       
   629                            const void *mem_p,
       
   630                            uint16_t size,
       
   631                            CyAsFunctionCallback cb,
       
   632                            uint32_t client)
       
   633 {
       
   634     uint8_t *header ;
       
   635     CyAsReturnStatus_t ret ;
       
   636     CyBool standby ;
       
   637     CyAsDevice *dev_p ;
       
   638     CyAsDmaCallback dmacb = 0 ;
       
   639     uint32_t state ;
       
   640 
       
   641     CyAsLogDebugMessage(6, "CyAsMiscDownloadFirmware called") ;
       
   642 
       
   643     /* Make sure we have a valid device */
       
   644     dev_p = (CyAsDevice *)handle ;
       
   645     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   646         return CY_AS_ERROR_INVALID_HANDLE ;
       
   647 
       
   648     /*
       
   649     * If the device has not been initialized, we cannot download firmware
       
   650     * to the device.
       
   651     */
       
   652     if (!CyAsDeviceIsConfigured(dev_p))
       
   653         return CY_AS_ERROR_NOT_CONFIGURED ;
       
   654 
       
   655     /*
       
   656     * Make sure West Bridge is not in standby
       
   657     */
       
   658     ret = CyAsMiscInStandby(dev_p, &standby) ;
       
   659     if (ret != CY_AS_ERROR_SUCCESS)
       
   660         return ret ;
       
   661 
       
   662     if (standby)
       
   663         return CY_AS_ERROR_IN_STANDBY ;
       
   664 
       
   665     if (CyAsDeviceIsInSuspendMode(dev_p))
       
   666         return CY_AS_ERROR_IN_SUSPEND ;
       
   667 
       
   668     /*
       
   669     * Make sure we are in configuration mode
       
   670     */
       
   671     if ((CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_VM_SET) & CY_AS_MEM_P0_VM_SET_CFGMODE) == 0)
       
   672         return CY_AS_ERROR_NOT_IN_CONFIG_MODE ;
       
   673 
       
   674     /* Maximum firmware size is 24k */
       
   675     if (size > CY_AS_MAXIMUM_FIRMWARE_SIZE)
       
   676         return CY_AS_ERROR_INVALID_SIZE ;
       
   677 
       
   678     /* Make sure the size is an even number of bytes as well */
       
   679     if (size & 0x01)
       
   680         return CY_AS_ERROR_ALIGNMENT_ERROR ;
       
   681 
       
   682     /*
       
   683      * Write the two word header that gives the base address and
       
   684      * size of the firmware image to download
       
   685      */
       
   686     state = CyAsHalDisableInterrupts() ;
       
   687     header = (uint8_t *)CyAsHalCBAlloc(4) ;
       
   688     CyAsHalEnableInterrupts(state) ;
       
   689     if (header == NULL)
       
   690         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   691 
       
   692     header[0] = 0x00 ;
       
   693     header[1] = 0x00 ;
       
   694     header[2] = (uint8_t)(size & 0xff) ;
       
   695     header[3] = (uint8_t)((size >> 8) & 0xff) ;
       
   696 
       
   697     /* Enable the firmware endpoint */
       
   698     ret = CyAsDmaEnableEndPoint(dev_p, CY_AS_FIRMWARE_ENDPOINT, CyTrue, CyAsDirectionIn) ;
       
   699     if (ret != CY_AS_ERROR_SUCCESS)
       
   700         return ret ;
       
   701 
       
   702     /*
       
   703     * Setup DMA for 64 byte packets.  This is the requirement for downloading
       
   704     * firmware to West Bridge.
       
   705     */
       
   706     CyAsDmaSetMaxDmaSize(dev_p, CY_AS_FIRMWARE_ENDPOINT, 64) ;
       
   707 
       
   708     if(cb)
       
   709     {
       
   710         dmacb = MyDmaCallback ;
       
   711     }
       
   712 
       
   713     ret = CyAsDmaQueueRequest(dev_p, CY_AS_FIRMWARE_ENDPOINT, header, 4, CyFalse, CyFalse, dmacb) ;
       
   714     if (ret != CY_AS_ERROR_SUCCESS)
       
   715         return ret ;
       
   716 
       
   717     /*
       
   718     * Write the firmware image to the West Bridge device
       
   719     */
       
   720     ret = CyAsDmaQueueRequest(dev_p, CY_AS_FIRMWARE_ENDPOINT, (void *)mem_p, size, CyFalse, CyFalse, dmacb) ;
       
   721     if (ret != CY_AS_ERROR_SUCCESS)
       
   722         return ret ;
       
   723 
       
   724     if(cb)
       
   725     {
       
   726         CyAsFuncCBNode* cbnode = CyAsCreateFuncCBNodeData(cb, client, CY_FUNCT_CB_MISC_DOWNLOADFIRMWARE, 0) ;
       
   727 
       
   728         if(cbnode == 0)
       
   729             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   730         else
       
   731             CyAsInsertCBNode(dev_p->func_cbs_misc, cbnode) ;
       
   732 
       
   733         ret = CyAsDmaKickStart(dev_p, CY_AS_FIRMWARE_ENDPOINT) ;
       
   734         if (ret != CY_AS_ERROR_SUCCESS)
       
   735             return ret ;
       
   736     }
       
   737     else
       
   738     {
       
   739 
       
   740         ret = CyAsDmaDrainQueue(dev_p, CY_AS_FIRMWARE_ENDPOINT, CyTrue) ;
       
   741 
       
   742         /* Free the header memory that was allocated earlier. */
       
   743         CyAsHalCBFree(header) ;
       
   744 
       
   745         if (ret != CY_AS_ERROR_SUCCESS)
       
   746         {
       
   747 			return ret ;
       
   748 		}
       
   749         /*
       
   750         * Disable endpoint 2.  The storage module will enable this EP if necessary.
       
   751         */
       
   752         CyAsDmaEnableEndPoint(dev_p, CY_AS_FIRMWARE_ENDPOINT, CyFalse, CyAsDirectionIn) ;
       
   753 
       
   754         /*
       
   755         * Clear the reset register.  This releases the West Bridge micro-controller from
       
   756         * reset and begins running the code at address zero.
       
   757         */
       
   758         CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_RST_CTRL_REG, 0x00) ;
       
   759     }
       
   760 
       
   761     /*
       
   762     * The firmware is not marked as loaded until the firmware initializes West Bridge and a request
       
   763     * is sent from West Bridge to the P port processor indicating that West Bridge is ready.
       
   764     */
       
   765     return CY_AS_ERROR_SUCCESS ;
       
   766 }
       
   767 
       
   768 
       
   769 static CyAsReturnStatus_t
       
   770 MyHandleResponseGetFirmwareVersion(CyAsDevice* dev_p,
       
   771                                    CyAsLLRequestResponse *req_p,
       
   772                                    CyAsLLRequestResponse *reply_p,
       
   773                                    CyAsGetFirmwareVersionData *data_p)
       
   774 {
       
   775 
       
   776     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   777     uint16_t val ;
       
   778 
       
   779     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_FIRMWARE_VERSION)
       
   780     {
       
   781         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   782         goto destroy ;
       
   783     }
       
   784 
       
   785     data_p->major = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   786     data_p->minor = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
       
   787     data_p->build = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
       
   788     val    = CyAsLLRequestResponse_GetWord(reply_p, 3) ;
       
   789     data_p->mediaType   = (uint8_t)(((val >> 8) & 0xFF) | (val & 0xFF)) ;
       
   790     val    = CyAsLLRequestResponse_GetWord(reply_p, 4) ;
       
   791     data_p->isDebugMode = (CyBool)(val & 0xFF) ;
       
   792 
       
   793 destroy :
       
   794     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   795     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   796 
       
   797     return ret ;
       
   798 }
       
   799 
       
   800 CyAsReturnStatus_t
       
   801 CyAsMiscGetFirmwareVersion(CyAsDeviceHandle handle,
       
   802                              CyAsGetFirmwareVersionData* data,
       
   803                              CyAsFunctionCallback cb,
       
   804                              uint32_t client)
       
   805 {
       
   806     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   807     CyBool standby ;
       
   808     CyAsLLRequestResponse *req_p, *reply_p ;
       
   809 
       
   810     CyAsDevice *dev_p ;
       
   811 
       
   812     (void)client ;
       
   813 
       
   814     CyAsLogDebugMessage(6, "CyAsMiscGetFirmwareVersion called") ;
       
   815 
       
   816     /* Make sure we have a valid device */
       
   817     dev_p = (CyAsDevice *)handle ;
       
   818     CyAsCheckDeviceReady(dev_p) ;
       
   819 
       
   820     /*
       
   821     * Make sure Antioch is not in standby
       
   822     */
       
   823     ret = CyAsMiscInStandby(dev_p, &standby) ;
       
   824     if (ret != CY_AS_ERROR_SUCCESS)
       
   825         return ret ;
       
   826     if (standby)
       
   827         return CY_AS_ERROR_IN_STANDBY ;
       
   828 
       
   829     /* Make sure the Antioch is not in suspend mode. */
       
   830     if (CyAsDeviceIsInSuspendMode(dev_p))
       
   831         return CY_AS_ERROR_IN_SUSPEND ;
       
   832 
       
   833     /* Create the request to send to the West Bridge device */
       
   834     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_GET_FIRMWARE_VERSION, CY_RQT_GENERAL_RQT_CONTEXT, 0) ;
       
   835     if (req_p == 0)
       
   836         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   837 
       
   838     /* Reserve space for the reply, the reply data will not exceed three words */
       
   839     reply_p = CyAsLLCreateResponse(dev_p, 5) ;
       
   840     if (reply_p == 0)
       
   841     {
       
   842         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   843         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   844     }
       
   845 
       
   846     if(cb == 0)
       
   847     {
       
   848         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   849         if (ret != CY_AS_ERROR_SUCCESS)
       
   850             goto destroy ;
       
   851 
       
   852         /* Request and response are freed in MyHandleResponseGetFirmwareVersion. */
       
   853         ret = MyHandleResponseGetFirmwareVersion(dev_p, req_p, reply_p, data) ;
       
   854         return ret ;
       
   855     }
       
   856     else
       
   857     {
       
   858 
       
   859         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_GETFIRMWAREVERSION,
       
   860             data, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p,
       
   861             reply_p, CyAsMiscFuncCallback) ;
       
   862 
       
   863         if (ret != CY_AS_ERROR_SUCCESS)
       
   864                 goto destroy ;
       
   865 
       
   866         /* The request and response are freed as part of the MiscFuncCallback */
       
   867         return ret ;
       
   868     }
       
   869 
       
   870 destroy:
       
   871     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   872     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   873 
       
   874     return ret ;
       
   875 }
       
   876 static CyAsReturnStatus_t
       
   877 MyHandleResponseReadMCURegister(CyAsDevice* dev_p,
       
   878                                    CyAsLLRequestResponse *req_p,
       
   879                                    CyAsLLRequestResponse *reply_p,
       
   880                                    uint8_t *data_p)
       
   881 {
       
   882 
       
   883     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   884 
       
   885     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_MCU_REGISTER_DATA)
       
   886     {
       
   887         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   888         goto destroy ;
       
   889     }
       
   890 
       
   891     *data_p = (uint8_t)(CyAsLLRequestResponse_GetWord(reply_p, 0)) ;
       
   892 
       
   893 destroy :
       
   894     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   895     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   896 
       
   897     return ret ;
       
   898 }
       
   899 
       
   900 static CyAsReturnStatus_t
       
   901 MyHandleResponseGetGpioValue(CyAsDevice* dev_p,
       
   902         CyAsLLRequestResponse *req_p,
       
   903         CyAsLLRequestResponse *reply_p,
       
   904         uint8_t *data_p)
       
   905 {
       
   906 
       
   907     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   908 
       
   909     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_GPIO_STATE)
       
   910     {
       
   911         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   912     }
       
   913     else
       
   914         *data_p = (uint8_t)(CyAsLLRequestResponse_GetWord(reply_p, 0)) ;
       
   915 
       
   916     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   917     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   918 
       
   919     return ret ;
       
   920 }
       
   921 
       
   922 
       
   923 CyAsReturnStatus_t CyAsMiscSetSDPowerPolarity(
       
   924     CyAsDeviceHandle handle,
       
   925     CyAsMiscSignalPolarity polarity,
       
   926     CyAsFunctionCallback cb,
       
   927     uint32_t client)
       
   928 {
       
   929     CyAsLLRequestResponse *req_p, *reply_p ;
       
   930     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   931     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
   932 
       
   933     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   934         return CY_AS_ERROR_INVALID_HANDLE ;
       
   935 
       
   936     if (!CyAsDeviceIsConfigured(dev_p))
       
   937         return CY_AS_ERROR_NOT_CONFIGURED ;
       
   938 
       
   939     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
   940         return CY_AS_ERROR_NO_FIRMWARE ;
       
   941 
       
   942     if (CyAsDeviceIsInSuspendMode(dev_p))
       
   943         return CY_AS_ERROR_IN_SUSPEND ;
       
   944 
       
   945 
       
   946     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDPOLARITY , CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
   947     if (req_p == 0)
       
   948     {
       
   949 
       
   950         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   951     }
       
   952     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)polarity) ;
       
   953 
       
   954     /* Reserve space for the reply, the reply data will not exceed one word */
       
   955     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   956     if (reply_p == 0)
       
   957     {
       
   958         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   959         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   960     }
       
   961 
       
   962     if(cb == 0)
       
   963     {
       
   964         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   965         if (ret != CY_AS_ERROR_SUCCESS)
       
   966             goto destroy ;
       
   967 
       
   968         return (MyHandleResponseNoData(dev_p, req_p, reply_p)) ;
       
   969     }
       
   970     else
       
   971     {
       
   972         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_SETSDPOLARITY,
       
   973             0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
       
   974                req_p, reply_p, CyAsMiscFuncCallback) ;
       
   975 
       
   976         if (ret != CY_AS_ERROR_SUCCESS)
       
   977             goto destroy ;
       
   978 
       
   979         /* The request and response are freed as part of the FuncCallback */
       
   980         return ret ;
       
   981     }
       
   982 
       
   983 destroy:
       
   984     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   985     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   986     return ret ;
       
   987 }
       
   988 
       
   989 
       
   990 
       
   991 
       
   992 
       
   993 CyAsReturnStatus_t
       
   994 CyAsMiscReadMCURegister(CyAsDeviceHandle handle,
       
   995                           uint16_t address,
       
   996                           uint8_t *value,
       
   997                           CyAsFunctionCallback cb,
       
   998                           uint32_t client)
       
   999 {
       
  1000     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1001     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1002 
       
  1003     CyAsDevice *dev_p ;
       
  1004 
       
  1005     CyAsLogDebugMessage(6, "CyAsMiscReadMCURegister called") ;
       
  1006 
       
  1007     dev_p = (CyAsDevice *)handle ;
       
  1008     CyAsCheckDeviceReady(dev_p) ;
       
  1009 
       
  1010     /* Check whether the firmware supports this command. */
       
  1011     if (CyAsDeviceIsNandStorageSupported(dev_p))
       
  1012         return CY_AS_ERROR_NOT_SUPPORTED ;
       
  1013 
       
  1014     /* Make sure the Antioch is not in suspend mode. */
       
  1015     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1016         return CY_AS_ERROR_IN_SUSPEND ;
       
  1017 
       
  1018     /* Create the request to send to the West Bridge device */
       
  1019     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_READ_MCU_REGISTER, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  1020     if (req_p == 0)
       
  1021         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1022 
       
  1023     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)address) ;
       
  1024 
       
  1025     /* Reserve space for the reply, the reply data will not exceed one word */
       
  1026     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1027     if (reply_p == 0)
       
  1028     {
       
  1029         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1030         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1031     }
       
  1032 
       
  1033     if(cb == 0)
       
  1034     {
       
  1035         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1036         if (ret != CY_AS_ERROR_SUCCESS)
       
  1037             goto destroy ;
       
  1038 
       
  1039         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_MCU_REGISTER_DATA)
       
  1040         {
       
  1041             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1042             goto destroy ;
       
  1043         }
       
  1044 
       
  1045         *value = (uint8_t)(CyAsLLRequestResponse_GetWord(reply_p, 0)) ;
       
  1046     }
       
  1047     else
       
  1048     {
       
  1049 
       
  1050         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_READMCUREGISTER,
       
  1051             value, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  1052             CyAsMiscFuncCallback) ;
       
  1053 
       
  1054         if (ret != CY_AS_ERROR_SUCCESS)
       
  1055                 goto destroy ;
       
  1056 
       
  1057         /* The request and response are freed as part of the MiscFuncCallback */
       
  1058         return ret ;
       
  1059     }
       
  1060 destroy:
       
  1061     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1062     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1063 
       
  1064     return ret ;
       
  1065 }
       
  1066 
       
  1067 
       
  1068 CyAsReturnStatus_t
       
  1069 CyAsMiscWriteMCURegister(CyAsDeviceHandle handle,
       
  1070                            uint16_t address,
       
  1071                            uint8_t mask,
       
  1072                            uint8_t value,
       
  1073                            CyAsFunctionCallback cb,
       
  1074                            uint32_t client)
       
  1075 {
       
  1076     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1077     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1078     CyAsDevice *dev_p ;
       
  1079 
       
  1080     CyAsLogDebugMessage(6, "CyAsMiscWriteMCURegister called") ;
       
  1081 
       
  1082     dev_p = (CyAsDevice *)handle ;
       
  1083     CyAsCheckDeviceReady(dev_p) ;
       
  1084 
       
  1085     /* Check whether the firmware supports this command. */
       
  1086     if (CyAsDeviceIsNandStorageSupported(dev_p))
       
  1087         return CY_AS_ERROR_NOT_SUPPORTED ;
       
  1088 
       
  1089     /* Make sure the Antioch is not in suspend mode. */
       
  1090     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1091         return CY_AS_ERROR_IN_SUSPEND ;
       
  1092 
       
  1093     /* Create the request to send to the West Bridge device */
       
  1094     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_WRITE_MCU_REGISTER, CY_RQT_GENERAL_RQT_CONTEXT, 2) ;
       
  1095     if (req_p == 0)
       
  1096         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1097 
       
  1098     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)address) ;
       
  1099     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((mask << 8) | value)) ;
       
  1100 
       
  1101     /* Reserve space for the reply, the reply data will not exceed one word */
       
  1102     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1103     if (reply_p == 0)
       
  1104     {
       
  1105         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1106         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1107     }
       
  1108 
       
  1109     if(cb == 0)
       
  1110     {
       
  1111         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1112         if (ret != CY_AS_ERROR_SUCCESS)
       
  1113             goto destroy ;
       
  1114 
       
  1115         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1116         {
       
  1117             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1118             goto destroy ;
       
  1119         }
       
  1120 
       
  1121         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1122     }
       
  1123     else
       
  1124     {
       
  1125         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_WRITEMCUREGISTER,
       
  1126             0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  1127             CyAsMiscFuncCallback) ;
       
  1128 
       
  1129         if (ret != CY_AS_ERROR_SUCCESS)
       
  1130             goto destroy ;
       
  1131 
       
  1132         /* The request and response are freed as part of the MiscFuncCallback */
       
  1133         return ret ;
       
  1134     }
       
  1135 
       
  1136 destroy:
       
  1137     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1138     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1139 
       
  1140     return ret ;
       
  1141 }
       
  1142 
       
  1143 CyAsReturnStatus_t
       
  1144 MyHandleResponseReset(CyAsDevice* dev_p,
       
  1145                       CyAsLLRequestResponse *req_p,
       
  1146                       CyAsLLRequestResponse *reply_p,
       
  1147                       CyAsResetType type)
       
  1148 {
       
  1149     uint16_t   v ;
       
  1150 
       
  1151     (void)req_p ;
       
  1152     (void)reply_p ;
       
  1153 
       
  1154     /*
       
  1155     * If the device is in suspend mode, it needs to be woken up so that the write
       
  1156     * to the reset control register succeeds. We need not however wait for the
       
  1157      * wake up procedure to be complete.
       
  1158      */
       
  1159     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1160     {
       
  1161         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_CM_WB_CFG_ID) ;
       
  1162         CyAsHalSleep (1) ;
       
  1163     }
       
  1164 
       
  1165     if (type == CyAsResetHard)
       
  1166     {
       
  1167         CyAsMiscCancelExRequests(dev_p) ;
       
  1168         CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_RST_CTRL_REG, CY_AS_MEM_RST_CTRL_REG_HARD) ;
       
  1169         CyAsDeviceSetUnconfigured(dev_p) ;
       
  1170         CyAsDeviceSetFirmwareNotLoaded(dev_p) ;
       
  1171         CyAsDeviceSetDmaStopped(dev_p) ;
       
  1172         CyAsDeviceSetLowLevelStopped(dev_p) ;
       
  1173         CyAsDeviceSetIntrStopped(dev_p) ;
       
  1174         CyAsDeviceClearSuspendMode(dev_p) ;
       
  1175         CyAsUsbCleanup(dev_p) ;
       
  1176         CyAsStorageCleanup(dev_p) ;
       
  1177 
       
  1178         /*
       
  1179          * Wait for a small amount of time to allow reset to be complete.
       
  1180          */
       
  1181         CyAsHalSleep(100) ;
       
  1182     }
       
  1183 
       
  1184     CyAsDeviceClearResetPending(dev_p) ;
       
  1185 
       
  1186     return CY_AS_ERROR_SUCCESS ;
       
  1187 }
       
  1188 
       
  1189 CyAsReturnStatus_t
       
  1190 CyAsMiscReset(CyAsDeviceHandle handle,
       
  1191                 CyAsResetType type,
       
  1192                 CyBool flush,
       
  1193                 CyAsFunctionCallback cb,
       
  1194                 uint32_t client)
       
  1195 {
       
  1196     CyAsDevice *dev_p ;
       
  1197     CyAsEndPointNumber_t i ;
       
  1198     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1199     (void)client ;
       
  1200     (void)cb ;
       
  1201 
       
  1202     CyAsLogDebugMessage(6, "CyAsMiscResetEX called") ;
       
  1203 
       
  1204     /* Make sure the device is ready for the command. */
       
  1205     dev_p = (CyAsDevice *)handle ;
       
  1206     CyAsCheckDeviceReady(dev_p) ;
       
  1207 
       
  1208     /*
       
  1209      * Soft reset is not supported until we close on the issues in the
       
  1210      * firmware with what needs to happen.
       
  1211      */
       
  1212     if (type == CyAsResetSoft)
       
  1213         return CY_AS_ERROR_NOT_YET_SUPPORTED ;
       
  1214 
       
  1215     CyAsDeviceSetResetPending(dev_p) ;
       
  1216 
       
  1217     if (flush)
       
  1218     {
       
  1219 
       
  1220         /* Unable to DrainQueues in polling mode */
       
  1221         if((dev_p->storage_cb || dev_p->storage_cb_ms) && CyAsHalIsPolling())
       
  1222             return CY_AS_ERROR_ASYNC_PENDING ;
       
  1223 
       
  1224         /*
       
  1225         * Shutdown the endpoints so no more traffic can be queued
       
  1226         */
       
  1227         for(i = 0; i < 15; i++)
       
  1228             CyAsDmaEnableEndPoint(dev_p, i, CyFalse, CyAsDirectionDontChange) ;
       
  1229 
       
  1230         /*
       
  1231          * If we are in normal mode, drain all traffic across all endpoints to be sure all traffic
       
  1232          * is flushed. If the device is suspended, data will not be coming in on any endpoint and
       
  1233          * all outstanding DMA operations can be canceled.
       
  1234          */
       
  1235         if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1236         {
       
  1237             for(i = 0; i < 15; i++)
       
  1238             {
       
  1239                 CyAsDmaCancel(dev_p, i, CY_AS_ERROR_CANCELED) ;
       
  1240             }
       
  1241         }
       
  1242         else
       
  1243         {
       
  1244             for(i = 0; i < 15; i++)
       
  1245             {
       
  1246                 if ((i == CY_AS_P2S_WRITE_ENDPOINT) || (i == CY_AS_P2S_READ_ENDPOINT))
       
  1247                     CyAsDmaDrainQueue(dev_p, i, CyFalse) ;
       
  1248                 else
       
  1249                     CyAsDmaDrainQueue(dev_p, i, CyTrue) ;
       
  1250             }
       
  1251         }
       
  1252     }
       
  1253     else
       
  1254     {
       
  1255         /* No flush was requested, so cancel any outstanding DMAs
       
  1256          * so the user callbacks are called as needed
       
  1257          */
       
  1258         if(CyAsDeviceIsStorageAsyncPending(dev_p))
       
  1259         {
       
  1260             for(i = 0; i < 15; i++)
       
  1261                 CyAsDmaCancel(dev_p, i, CY_AS_ERROR_CANCELED) ;
       
  1262         }
       
  1263     }
       
  1264 
       
  1265     ret = MyHandleResponseReset(dev_p, 0, 0, type) ;
       
  1266 
       
  1267     if(cb)
       
  1268         /* Even though no mailbox communication was needed, issue the callback so the
       
  1269         * user does not need to special case their code. */
       
  1270         cb((CyAsDeviceHandle)dev_p, ret, client, CY_FUNCT_CB_MISC_RESET, 0) ;
       
  1271 
       
  1272     /*
       
  1273      * Initialize any registers that may have been changed when the device was reset.
       
  1274      */
       
  1275     CyAsHalInitDevRegisters(dev_p->tag, CyFalse) ;
       
  1276 
       
  1277     return ret ;
       
  1278 }
       
  1279 
       
  1280 static CyAsReturnStatus_t
       
  1281 GetUnallocatedResource(CyAsDevice *dev_p, CyAsResourceType resource)
       
  1282 {
       
  1283     uint8_t shift = 0 ;
       
  1284     uint16_t v ;
       
  1285     CyAsReturnStatus_t ret = CY_AS_ERROR_NOT_ACQUIRED ;
       
  1286 
       
  1287     switch(resource)
       
  1288     {
       
  1289     case CyAsBusUSB:
       
  1290         shift = 4 ;
       
  1291         break ;
       
  1292     case CyAsBus_1:
       
  1293         shift = 0 ;
       
  1294         break ;
       
  1295     case CyAsBus_0:
       
  1296         shift = 2 ;
       
  1297         break ;
       
  1298     default:
       
  1299         CyAsHalAssert(CyFalse) ;
       
  1300         break ;
       
  1301     }
       
  1302 
       
  1303     /* Get the semaphore value for this resource */
       
  1304     v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE) ;
       
  1305     v = (v >> shift) & 0x03 ;
       
  1306 
       
  1307     if (v == 0x03)
       
  1308     {
       
  1309         ret = CY_AS_ERROR_RESOURCE_ALREADY_OWNED ;
       
  1310     }
       
  1311     else if ((v & 0x01) == 0)
       
  1312     {
       
  1313         /* The resource is not owned by anyone, we can try to get it */
       
  1314         CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_P0_RSE_MASK, (0x03 << shift)) ;
       
  1315         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_RSE_MASK) ;
       
  1316         CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE, (0x01 << shift)) ;
       
  1317         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_RSE_MASK) ;
       
  1318 
       
  1319         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE) ;
       
  1320         v = (v >> shift) & 0x03 ;
       
  1321         if (v == 0x03)
       
  1322             ret = CY_AS_ERROR_SUCCESS ;
       
  1323     }
       
  1324 
       
  1325     return ret ;
       
  1326 }
       
  1327 
       
  1328 static CyAsReturnStatus_t
       
  1329 MyHandleResponseAcquireResource(CyAsDevice* dev_p,
       
  1330                          CyAsLLRequestResponse *req_p,
       
  1331                          CyAsLLRequestResponse *reply_p,
       
  1332                          CyAsResourceType *resource)
       
  1333 {
       
  1334     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1335 
       
  1336     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1337     {
       
  1338         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1339         goto destroy ;
       
  1340     }
       
  1341 
       
  1342     if (ret == CY_AS_ERROR_SUCCESS)
       
  1343     {
       
  1344             ret = GetUnallocatedResource(dev_p, *resource) ;
       
  1345             if (ret != CY_AS_ERROR_NOT_ACQUIRED)
       
  1346                 ret = CY_AS_ERROR_SUCCESS ;
       
  1347     }
       
  1348 
       
  1349 destroy :
       
  1350     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1351     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1352 
       
  1353     return ret ;
       
  1354 }
       
  1355 
       
  1356 CyAsReturnStatus_t
       
  1357 CyAsMiscAcquireResource(CyAsDeviceHandle handle,
       
  1358                           CyAsResourceType *resource,
       
  1359                           CyBool force,
       
  1360                           CyAsFunctionCallback cb,
       
  1361                           uint32_t client)
       
  1362 {
       
  1363     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1364     CyAsReturnStatus_t ret ;
       
  1365 
       
  1366     CyAsDevice *dev_p ;
       
  1367 
       
  1368     (void)client ;
       
  1369 
       
  1370     CyAsLogDebugMessage(6, "CyAsMiscAcquireResource called") ;
       
  1371 
       
  1372     if (*resource != CyAsBusUSB && *resource != CyAsBus_0 && *resource != CyAsBus_1)
       
  1373             return CY_AS_ERROR_INVALID_RESOURCE ;
       
  1374 
       
  1375 
       
  1376     /* Make sure the device is ready to accept the command. */
       
  1377     dev_p = (CyAsDevice *)handle ;
       
  1378     CyAsCheckDeviceReady(dev_p) ;
       
  1379 
       
  1380     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1381         return CY_AS_ERROR_IN_SUSPEND ;
       
  1382 
       
  1383 
       
  1384     ret = GetUnallocatedResource(dev_p, *resource) ;
       
  1385 
       
  1386     /*
       
  1387      * Make sure that the callback is called if the resource is successfully
       
  1388      * acquired at this point.
       
  1389      */
       
  1390     if ((ret == CY_AS_ERROR_SUCCESS) && (cb != 0))
       
  1391         cb(handle, ret, client, CY_FUNCT_CB_MISC_ACQUIRERESOURCE, resource) ;
       
  1392 
       
  1393     if (ret != CY_AS_ERROR_NOT_ACQUIRED)
       
  1394         return ret ;
       
  1395 
       
  1396     if (!force)
       
  1397         return CY_AS_ERROR_NOT_ACQUIRED ;
       
  1398 
       
  1399     /* Create the request to acquire the resource */
       
  1400     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ACQUIRE_RESOURCE, CY_RQT_RESOURCE_RQT_CONTEXT, 1) ;
       
  1401     if (req_p == 0)
       
  1402         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1403 
       
  1404     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)(*resource)) ;
       
  1405 
       
  1406     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1407     if (reply_p == 0)
       
  1408     {
       
  1409         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1410         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1411     }
       
  1412 
       
  1413     if(cb == 0)
       
  1414     {
       
  1415         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1416         if (ret != CY_AS_ERROR_SUCCESS)
       
  1417             goto destroy ;
       
  1418 
       
  1419         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1420         {
       
  1421             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1422             goto destroy ;
       
  1423         }
       
  1424 
       
  1425         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1426     }
       
  1427     else
       
  1428     {
       
  1429             ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_ACQUIRERESOURCE,
       
  1430                 resource, dev_p->func_cbs_res, CY_AS_REQUEST_RESPONSE_EX, req_p,
       
  1431                 reply_p, CyAsMiscFuncCallback) ;
       
  1432 
       
  1433             if (ret != CY_AS_ERROR_SUCCESS)
       
  1434                     goto destroy ;
       
  1435 
       
  1436             /* The request and response are freed as part of the MiscFuncCallback */
       
  1437             return ret ;
       
  1438     }
       
  1439 
       
  1440 destroy:
       
  1441     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1442     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1443 
       
  1444     if (ret == CY_AS_ERROR_SUCCESS)
       
  1445     {
       
  1446             ret = GetUnallocatedResource(dev_p, *resource) ;
       
  1447             if (ret != CY_AS_ERROR_NOT_ACQUIRED)
       
  1448                 ret = CY_AS_ERROR_SUCCESS ;
       
  1449     }
       
  1450 
       
  1451     return ret ;
       
  1452 }
       
  1453 CyAsReturnStatus_t
       
  1454 CyAsMiscReleaseResource(CyAsDeviceHandle handle, CyAsResourceType resource)
       
  1455 {
       
  1456     uint8_t shift = 0 ;
       
  1457     uint16_t v ;
       
  1458 
       
  1459     CyAsDevice *dev_p ;
       
  1460 
       
  1461     CyAsLogDebugMessage(6, "CyAsMiscReleaseResource called") ;
       
  1462 
       
  1463     /* Make sure the device is ready for the command. */
       
  1464     dev_p = (CyAsDevice *)handle ;
       
  1465     CyAsCheckDeviceReady(dev_p) ;
       
  1466 
       
  1467     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1468         return CY_AS_ERROR_IN_SUSPEND ;
       
  1469 
       
  1470     if (resource != CyAsBusUSB && resource != CyAsBus_0 && resource != CyAsBus_1)
       
  1471         return CY_AS_ERROR_INVALID_RESOURCE ;
       
  1472 
       
  1473     switch(resource)
       
  1474     {
       
  1475         case CyAsBusUSB:
       
  1476             shift = 4 ;
       
  1477             break ;
       
  1478         case CyAsBus_1:
       
  1479             shift = 0 ;
       
  1480             break ;
       
  1481         case CyAsBus_0:
       
  1482             shift = 2 ;
       
  1483             break ;
       
  1484         default:
       
  1485             CyAsHalAssert(CyFalse) ;
       
  1486             break ;
       
  1487     }
       
  1488 
       
  1489     /* Get the semaphore value for this resource */
       
  1490     v = (CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE) >> shift) & 0x03 ;
       
  1491     if (v == 0 || v == 1 || v == 2)
       
  1492         return CY_AS_ERROR_RESOURCE_NOT_OWNED ;
       
  1493 
       
  1494     CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_P0_RSE_MASK, (0x03 << shift)) ;
       
  1495     CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE, (0x02 << shift)) ;
       
  1496     CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_P0_RSE_MASK, 0) ;
       
  1497 
       
  1498     return CY_AS_ERROR_SUCCESS ;
       
  1499 }
       
  1500 
       
  1501 CyAsReturnStatus_t
       
  1502 CyAsMiscSetTraceLevel(CyAsDeviceHandle handle,
       
  1503                         uint8_t level,
       
  1504                         CyAsBusNumber_t bus,
       
  1505                         uint32_t device,
       
  1506                         uint32_t unit,
       
  1507                         CyAsFunctionCallback cb,
       
  1508                         uint32_t client)
       
  1509 {
       
  1510     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1511     CyAsReturnStatus_t ret ;
       
  1512     CyAsDevice *dev_p ;
       
  1513 
       
  1514     CyAsLogDebugMessage(6, "CyAsMiscSetTraceLevel called") ;
       
  1515 
       
  1516     /* Make sure the device is ready for the command. */
       
  1517     dev_p = (CyAsDevice *)handle ;
       
  1518     CyAsCheckDeviceReady(dev_p) ;
       
  1519 
       
  1520     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1521         return CY_AS_ERROR_IN_SUSPEND ;
       
  1522 
       
  1523     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
  1524         return CY_AS_ERROR_NO_SUCH_BUS ;
       
  1525 
       
  1526     if (device >= CY_AS_MAX_STORAGE_DEVICES)
       
  1527         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  1528 
       
  1529     if (unit > 255)
       
  1530         return CY_AS_ERROR_NO_SUCH_UNIT ;
       
  1531 
       
  1532     if (level >= CYAS_FW_TRACE_MAX_LEVEL)
       
  1533         return CY_AS_ERROR_INVALID_TRACE_LEVEL ;
       
  1534 
       
  1535     /* Create the request to send to the West Bridge device */
       
  1536     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_TRACE_LEVEL, CY_RQT_GENERAL_RQT_CONTEXT, 2) ;
       
  1537     if (req_p == 0)
       
  1538         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1539 
       
  1540     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)level) ;
       
  1541     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((bus << 12) | (device << 8) | (unit))) ;
       
  1542 
       
  1543     /* Reserve space for the reply, the reply data will not exceed three words */
       
  1544     reply_p = CyAsLLCreateResponse(dev_p, 2) ;
       
  1545     if (reply_p == 0)
       
  1546     {
       
  1547         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1548         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1549     }
       
  1550 
       
  1551     if(cb == 0)
       
  1552     {
       
  1553         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1554         if (ret != CY_AS_ERROR_SUCCESS)
       
  1555             goto destroy ;
       
  1556 
       
  1557         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1558         {
       
  1559             ret = CY_AS_ERROR_NOT_SUPPORTED ;
       
  1560             goto destroy ;
       
  1561         }
       
  1562 
       
  1563         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1564     }
       
  1565     else
       
  1566     {
       
  1567 
       
  1568         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_SETTRACELEVEL,
       
  1569             0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  1570             CyAsMiscFuncCallback) ;
       
  1571 
       
  1572         if (ret != CY_AS_ERROR_SUCCESS)
       
  1573                 goto destroy ;
       
  1574 
       
  1575         /* The request and response are freed as part of the MiscFuncCallback */
       
  1576         return ret ;
       
  1577     }
       
  1578 
       
  1579 destroy:
       
  1580     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1581     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1582 
       
  1583     return ret ;
       
  1584 }
       
  1585 
       
  1586 CyAsReturnStatus_t
       
  1587 CyAsMiscHeartBeatControl(CyAsDeviceHandle handle,
       
  1588                            CyBool enable,
       
  1589                            CyAsFunctionCallback cb,
       
  1590                            uint32_t client)
       
  1591 {
       
  1592     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1593     CyAsReturnStatus_t ret ;
       
  1594     CyAsDevice *dev_p ;
       
  1595 
       
  1596     CyAsLogDebugMessage(6, "CyAsMiscHeartBeatControl called") ;
       
  1597 
       
  1598     /* Make sure the device is ready for the command. */
       
  1599     dev_p = (CyAsDevice *)handle ;
       
  1600     CyAsCheckDeviceReady(dev_p) ;
       
  1601 
       
  1602     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1603         return CY_AS_ERROR_IN_SUSPEND ;
       
  1604 
       
  1605     /* Create the request to send to the West Bridge device */
       
  1606     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CONTROL_ANTIOCH_HEARTBEAT, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  1607     if (req_p == 0)
       
  1608         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1609 
       
  1610     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)enable) ;
       
  1611 
       
  1612     /* Reserve space for the reply, the reply data will not exceed one word */
       
  1613     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1614     if (reply_p == 0)
       
  1615     {
       
  1616         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1617         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1618     }
       
  1619 
       
  1620     if(cb == 0)
       
  1621     {
       
  1622         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1623         if (ret != CY_AS_ERROR_SUCCESS)
       
  1624             goto destroy ;
       
  1625 
       
  1626         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1627         {
       
  1628             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1629             goto destroy ;
       
  1630         }
       
  1631 
       
  1632         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1633     }
       
  1634     else
       
  1635     {
       
  1636 
       
  1637         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_HEARTBEATCONTROL,
       
  1638             0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  1639             CyAsMiscFuncCallback) ;
       
  1640 
       
  1641         if (ret != CY_AS_ERROR_SUCCESS)
       
  1642                 goto destroy ;
       
  1643 
       
  1644         /* The request and response are freed as part of the MiscFuncCallback */
       
  1645         return ret ;
       
  1646     }
       
  1647 
       
  1648 destroy:
       
  1649     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1650     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1651 
       
  1652     return ret ;
       
  1653 }
       
  1654 
       
  1655 static CyAsReturnStatus_t
       
  1656 MySetSDClockFreq (
       
  1657         CyAsDevice          *dev_p,
       
  1658         uint8_t              cardType,
       
  1659         uint8_t              setting,
       
  1660         CyAsFunctionCallback cb,
       
  1661         uint32_t             client)
       
  1662 {
       
  1663     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1664     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1665 
       
  1666     if (CyAsDeviceIsInCallback(dev_p) && (cb == 0))
       
  1667         return CY_AS_ERROR_INVALID_IN_CALLBACK ;
       
  1668 
       
  1669     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_SD_CLOCK_FREQ, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  1670     if (req_p == 0)
       
  1671         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1672 
       
  1673     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)((cardType << 8) | setting)) ;
       
  1674 
       
  1675     /* Reserve space for the reply, which will not exceed one word. */
       
  1676     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1677     if (reply_p == 0)
       
  1678     {
       
  1679         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1680         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1681     }
       
  1682 
       
  1683     if (cb == 0)
       
  1684     {
       
  1685         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1686         if (ret != CY_AS_ERROR_SUCCESS)
       
  1687             goto destroy ;
       
  1688 
       
  1689         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1690         {
       
  1691             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1692             goto destroy ;
       
  1693         }
       
  1694 
       
  1695         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1696     }
       
  1697     else
       
  1698     {
       
  1699         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_SETSDFREQ, 0,
       
  1700             dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, CyAsMiscFuncCallback) ;
       
  1701 
       
  1702         if (ret != CY_AS_ERROR_SUCCESS)
       
  1703                 goto destroy ;
       
  1704 
       
  1705         /* The request and response are freed as part of the MiscFuncCallback */
       
  1706         return ret ;
       
  1707     }
       
  1708 
       
  1709 destroy:
       
  1710     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1711     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1712 
       
  1713     return ret ;
       
  1714 }
       
  1715 
       
  1716 CyAsReturnStatus_t
       
  1717 CyAsMiscSetLowSpeedSDFreq(
       
  1718         CyAsDeviceHandle     handle,
       
  1719         CyAsLowSpeedSDFreq   setting,
       
  1720         CyAsFunctionCallback cb,
       
  1721         uint32_t             client)
       
  1722 {
       
  1723     CyAsDevice *dev_p ;
       
  1724 
       
  1725     CyAsLogDebugMessage(6, "CyAsMiscSetLowSpeedSDFreq called") ;
       
  1726 
       
  1727     /* Make sure the device is ready for the command. */
       
  1728     dev_p = (CyAsDevice *)handle ;
       
  1729     CyAsCheckDeviceReady(dev_p) ;
       
  1730 
       
  1731     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1732         return CY_AS_ERROR_IN_SUSPEND ;
       
  1733 
       
  1734     if ((setting != CY_AS_SD_DEFAULT_FREQ) && (setting != CY_AS_SD_RATED_FREQ))
       
  1735         return CY_AS_ERROR_INVALID_PARAMETER ;
       
  1736 
       
  1737     return MySetSDClockFreq(dev_p, 0, (uint8_t)setting, cb, client) ;
       
  1738 }
       
  1739 
       
  1740 CyAsReturnStatus_t
       
  1741 CyAsMiscSetHighSpeedSDFreq(
       
  1742         CyAsDeviceHandle     handle,
       
  1743         CyAsHighSpeedSDFreq  setting,
       
  1744         CyAsFunctionCallback cb,
       
  1745         uint32_t             client)
       
  1746 {
       
  1747     CyAsDevice *dev_p ;
       
  1748 
       
  1749     CyAsLogDebugMessage(6, "CyAsMiscSetHighSpeedSDFreq called") ;
       
  1750 
       
  1751     /* Make sure the device is ready for the command. */
       
  1752     dev_p = (CyAsDevice *)handle ;
       
  1753     CyAsCheckDeviceReady(dev_p) ;
       
  1754 
       
  1755     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1756         return CY_AS_ERROR_IN_SUSPEND ;
       
  1757 
       
  1758     if ((setting != CY_AS_HS_SD_FREQ_24) && (setting != CY_AS_HS_SD_FREQ_48))
       
  1759         return CY_AS_ERROR_INVALID_PARAMETER ;
       
  1760 
       
  1761     return MySetSDClockFreq(dev_p, 1, (uint8_t)setting, cb, client) ;
       
  1762 }
       
  1763 
       
  1764 CyAsReturnStatus_t
       
  1765 CyAsMiscGetGpioValue(CyAsDeviceHandle handle,
       
  1766         CyAsMiscGpio pin,
       
  1767         uint8_t *value,
       
  1768         CyAsFunctionCallback cb,
       
  1769         uint32_t client)
       
  1770 {
       
  1771     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1772     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1773     CyAsDevice *dev_p ;
       
  1774     uint16_t v ;
       
  1775 
       
  1776     CyAsLogDebugMessage(6, "CyAsMiscGetGpioValue called") ;
       
  1777 
       
  1778     /* Make sure the device is ready for the command. */
       
  1779     dev_p = (CyAsDevice *)handle ;
       
  1780     CyAsCheckDeviceReady(dev_p) ;
       
  1781 
       
  1782     /* If the pin specified is UVALID, there is no need for firmware to be loaded. */
       
  1783     if (pin == CyAsMiscGpio_UValid)
       
  1784     {
       
  1785         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_PMU_UPDATE) ;
       
  1786         *value = (uint8_t)(v & CY_AS_MEM_PMU_UPDATE_UVALID) ;
       
  1787 
       
  1788         if (cb != 0)
       
  1789             cb(dev_p, ret, client, CY_FUNCT_CB_MISC_GETGPIOVALUE, value) ;
       
  1790 
       
  1791         return ret ;
       
  1792     }
       
  1793 
       
  1794     /* Check whether the firmware supports this command. */
       
  1795     if (CyAsDeviceIsNandStorageSupported(dev_p))
       
  1796         return CY_AS_ERROR_NOT_SUPPORTED ;
       
  1797 
       
  1798     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1799         return CY_AS_ERROR_IN_SUSPEND ;
       
  1800 
       
  1801     /* Make sure the pin selected is valid */
       
  1802     if ((pin != CyAsMiscGpio_1) && (pin != CyAsMiscGpio_0))
       
  1803         return CY_AS_ERROR_INVALID_PARAMETER ;
       
  1804 
       
  1805     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_GET_GPIO_STATE, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  1806     if (req_p == 0)
       
  1807         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1808 
       
  1809     CyAsLLRequestResponse_SetWord(req_p, 0, ((uint8_t)pin << 8)) ;
       
  1810 
       
  1811     /* Reserve space for the reply, which will not exceed one word. */
       
  1812     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1813     if (reply_p == 0)
       
  1814     {
       
  1815         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1816         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1817     }
       
  1818 
       
  1819     if (cb == 0)
       
  1820     {
       
  1821         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1822         if (ret != CY_AS_ERROR_SUCCESS)
       
  1823             goto destroy ;
       
  1824 
       
  1825         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_GPIO_STATE)
       
  1826         {
       
  1827             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1828             goto destroy ;
       
  1829         }
       
  1830 
       
  1831         *value = (uint8_t)CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1832     }
       
  1833     else
       
  1834     {
       
  1835 
       
  1836         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_GETGPIOVALUE,
       
  1837             value, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  1838             CyAsMiscFuncCallback) ;
       
  1839 
       
  1840         if (ret != CY_AS_ERROR_SUCCESS)
       
  1841                 goto destroy ;
       
  1842 
       
  1843         /* The request and response are freed as part of the MiscFuncCallback */
       
  1844         return ret ;
       
  1845     }
       
  1846 
       
  1847 destroy:
       
  1848     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1849     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1850 
       
  1851     return ret ;
       
  1852 }
       
  1853 
       
  1854 
       
  1855 CyAsReturnStatus_t
       
  1856 CyAsMiscSetGpioValue(CyAsDeviceHandle handle,
       
  1857         CyAsMiscGpio pin,
       
  1858         uint8_t value,
       
  1859         CyAsFunctionCallback cb,
       
  1860         uint32_t client)
       
  1861 {
       
  1862     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1863     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1864     CyAsDevice *dev_p ;
       
  1865     uint16_t v ;
       
  1866 
       
  1867     CyAsLogDebugMessage(6, "CyAsMiscSetGpioValue called") ;
       
  1868 
       
  1869     /* Make sure the device is ready for the command. */
       
  1870     dev_p = (CyAsDevice *)handle ;
       
  1871     CyAsCheckDeviceReady(dev_p) ;
       
  1872 
       
  1873     /* If the pin specified is UVALID, there is no need for firmware to be loaded. */
       
  1874     if (pin == CyAsMiscGpio_UValid)
       
  1875     {
       
  1876         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_PMU_UPDATE) ;
       
  1877         if (value)
       
  1878             CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_PMU_UPDATE, (v | CY_AS_MEM_PMU_UPDATE_UVALID)) ;
       
  1879         else
       
  1880             CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_PMU_UPDATE, (v & ~CY_AS_MEM_PMU_UPDATE_UVALID)) ;
       
  1881 
       
  1882         if (cb != 0)
       
  1883             cb(dev_p, ret, client, CY_FUNCT_CB_MISC_SETGPIOVALUE, 0) ;
       
  1884         return ret ;
       
  1885     }
       
  1886 
       
  1887     /* Check whether the firmware supports this command. */
       
  1888     if (CyAsDeviceIsNandStorageSupported(dev_p))
       
  1889         return CY_AS_ERROR_NOT_SUPPORTED ;
       
  1890 
       
  1891     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1892         return CY_AS_ERROR_IN_SUSPEND ;
       
  1893 
       
  1894     /* Make sure the pin selected is valid */
       
  1895     if ((pin < CyAsMiscGpio_0) || (pin > CyAsMiscGpio_UValid))
       
  1896         return CY_AS_ERROR_INVALID_PARAMETER ;
       
  1897 
       
  1898     /* Create and initialize the low level request to the firmware. */
       
  1899     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_GPIO_STATE, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  1900     if (req_p == 0)
       
  1901         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1902 
       
  1903     v = (uint16_t)(((uint8_t)pin << 8) | (value > 0)) ;
       
  1904     CyAsLLRequestResponse_SetWord(req_p, 0, v) ;
       
  1905 
       
  1906     /* Reserve space for the reply, which will not exceed one word. */
       
  1907     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1908     if (reply_p == 0)
       
  1909     {
       
  1910         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1911         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1912     }
       
  1913 
       
  1914     if (cb == 0)
       
  1915     {
       
  1916         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1917         if (ret != CY_AS_ERROR_SUCCESS)
       
  1918             goto destroy ;
       
  1919 
       
  1920         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1921         {
       
  1922             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1923             goto destroy ;
       
  1924         }
       
  1925 
       
  1926         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1927     }
       
  1928     else
       
  1929     {
       
  1930 
       
  1931         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_SETGPIOVALUE,
       
  1932             0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  1933             CyAsMiscFuncCallback) ;
       
  1934 
       
  1935         if (ret != CY_AS_ERROR_SUCCESS)
       
  1936                 goto destroy ;
       
  1937 
       
  1938         /* The request and response are freed as part of the MiscFuncCallback */
       
  1939         return ret ;
       
  1940     }
       
  1941 
       
  1942 destroy:
       
  1943     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1944     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1945 
       
  1946     return ret ;
       
  1947 }
       
  1948 
       
  1949 static CyAsReturnStatus_t
       
  1950 MyEnterStandby(CyAsDevice *dev_p, CyBool pin)
       
  1951 {
       
  1952     CyAsMiscCancelExRequests(dev_p) ;
       
  1953 
       
  1954     /* Save the current values in the critical P-port registers, where necessary. */
       
  1955     CyAsHalReadRegsBeforeStandby(dev_p->tag) ;
       
  1956 
       
  1957     if (pin)
       
  1958     {
       
  1959         if (CyAsHalSetWakeupPin(dev_p->tag, CyFalse))
       
  1960             CyAsDeviceSetPinStandby(dev_p) ;
       
  1961         else
       
  1962             return CY_AS_ERROR_SETTING_WAKEUP_PIN ;
       
  1963     }
       
  1964     else
       
  1965     {
       
  1966         /*
       
  1967          * Put antioch in the standby mode
       
  1968          */
       
  1969         CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT, 0x02) ;
       
  1970         CyAsDeviceSetRegisterStandby(dev_p) ;
       
  1971     }
       
  1972 
       
  1973     /*
       
  1974      * When the Antioch comes out of standby, we have to wait until
       
  1975      * the firmware initialization completes before sending other
       
  1976      * requests down.
       
  1977      */
       
  1978     CyAsDeviceSetFirmwareNotLoaded(dev_p) ;
       
  1979 
       
  1980     /*
       
  1981      * Keep West Bridge interrupt disabled until the device is being woken
       
  1982      * up from standby.
       
  1983      */
       
  1984     dev_p->stby_int_mask = CyAsHalDisableInterrupts ();
       
  1985 
       
  1986     return CY_AS_ERROR_SUCCESS ;
       
  1987 }
       
  1988 
       
  1989 static CyAsReturnStatus_t
       
  1990 MyHandleResponseEnterStandby(CyAsDevice* dev_p,
       
  1991                          CyAsLLRequestResponse *req_p,
       
  1992                          CyAsLLRequestResponse *reply_p,
       
  1993                          CyBool pin)
       
  1994 {
       
  1995     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1996 
       
  1997     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1998     {
       
  1999         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2000         goto destroy ;
       
  2001     }
       
  2002 
       
  2003     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2004 
       
  2005 destroy:
       
  2006     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2007     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2008 
       
  2009     if (ret != CY_AS_ERROR_SUCCESS)
       
  2010         return ret ;
       
  2011 
       
  2012     ret = MyEnterStandby(dev_p, pin) ;
       
  2013 
       
  2014     return ret ;
       
  2015 }
       
  2016 
       
  2017 CyAsReturnStatus_t
       
  2018 CyAsMiscEnterStandby(CyAsDeviceHandle handle,
       
  2019                         CyBool pin,
       
  2020                         CyAsFunctionCallback cb,
       
  2021                         uint32_t client)
       
  2022 {
       
  2023     CyAsDevice *dev_p ;
       
  2024     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2025     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2026     CyBool standby ;
       
  2027 
       
  2028     CyAsLogDebugMessage(6, "CyAsMiscEnterStandby called") ;
       
  2029 
       
  2030     /* Make sure we have a valid device */
       
  2031     dev_p = (CyAsDevice *)handle ;
       
  2032     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2033         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2034 
       
  2035     /*
       
  2036      * If we already are in standby, do not do it again and let the
       
  2037      * user know via the error return.
       
  2038      */
       
  2039     ret = CyAsMiscInStandby(handle, &standby) ;
       
  2040     if (ret != CY_AS_ERROR_SUCCESS)
       
  2041         return ret ;
       
  2042 
       
  2043     if (standby == CyTrue)
       
  2044         return CY_AS_ERROR_ALREADY_STANDBY ;
       
  2045 
       
  2046     /*
       
  2047      * If the user wants to transition from suspend mode to standby mode,
       
  2048      * the device needs to be woken up so that it can complete all pending
       
  2049      * operations.
       
  2050      */
       
  2051     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  2052         CyAsMiscLeaveSuspend(dev_p, 0, 0) ;
       
  2053 
       
  2054     if (dev_p->usb_count)
       
  2055     {
       
  2056         /*
       
  2057          * We do not allow West Bridge to go into standby mode when the
       
  2058          * USB stack is initialized.  You must stop the USB stack in
       
  2059          * order to enter standby mode.
       
  2060          */
       
  2061         return CY_AS_ERROR_USB_RUNNING ;
       
  2062     }
       
  2063 
       
  2064     /*
       
  2065      * If the storage stack is not running, the device can directly be put into
       
  2066      * sleep mode. Otherwise, the firmware needs to be signaled to prepare for
       
  2067      * going into sleep mode.
       
  2068      */
       
  2069     if (dev_p->storage_count)
       
  2070     {
       
  2071         /*
       
  2072          * If there are async storage operations pending, make one attempt to
       
  2073          * complete them.
       
  2074          */
       
  2075         if (CyAsDeviceIsStorageAsyncPending(dev_p))
       
  2076         {
       
  2077             /* DrainQueue will not work in polling mode */
       
  2078             if(CyAsHalIsPolling())
       
  2079                 return CY_AS_ERROR_ASYNC_PENDING ;
       
  2080 
       
  2081             CyAsDmaDrainQueue(dev_p, CY_AS_P2S_READ_ENDPOINT, CyFalse) ;
       
  2082             CyAsDmaDrainQueue(dev_p, CY_AS_P2S_WRITE_ENDPOINT, CyFalse) ;
       
  2083 
       
  2084             /*
       
  2085              * If more storage operations were queued at this stage, return
       
  2086              * an error.
       
  2087              */
       
  2088             if (CyAsDeviceIsStorageAsyncPending(dev_p))
       
  2089                 return CY_AS_ERROR_ASYNC_PENDING ;
       
  2090         }
       
  2091 
       
  2092         req_p = CyAsLLCreateRequest(dev_p, CY_RQT_PREPARE_FOR_STANDBY, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  2093         if (req_p == 0)
       
  2094             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2095 
       
  2096         reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  2097         if (reply_p == 0)
       
  2098         {
       
  2099             CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2100             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2101         }
       
  2102 
       
  2103         if(!cb)
       
  2104         {
       
  2105             ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2106             if (ret != CY_AS_ERROR_SUCCESS)
       
  2107                 goto destroy ;
       
  2108 
       
  2109             /* The request and response are freed in the HandleResponse */
       
  2110             return MyHandleResponseEnterStandby(dev_p, req_p, reply_p, pin) ;
       
  2111 
       
  2112         }
       
  2113         else
       
  2114         {
       
  2115             ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_ENTERSTANDBY,
       
  2116                 (void*)pin, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p,
       
  2117                 reply_p, CyAsMiscFuncCallback) ;
       
  2118 
       
  2119             if (ret != CY_AS_ERROR_SUCCESS)
       
  2120                 goto destroy ;
       
  2121 
       
  2122             /* The request and response are freed as part of the MiscFuncCallback */
       
  2123             return ret ;
       
  2124         }
       
  2125 destroy:
       
  2126         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2127         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2128     }
       
  2129     else
       
  2130     {
       
  2131         ret = MyEnterStandby(dev_p, pin) ;
       
  2132         if(cb)
       
  2133             /* Even though no mailbox communication was needed, issue the callback so the
       
  2134             * user does not need to special case their code. */
       
  2135             cb((CyAsDeviceHandle)dev_p, ret, client, CY_FUNCT_CB_MISC_ENTERSTANDBY, 0) ;
       
  2136     }
       
  2137 
       
  2138     return ret ;
       
  2139 }
       
  2140 
       
  2141 CyAsReturnStatus_t
       
  2142 CyAsMiscEnterStandbyEXU(CyAsDeviceHandle handle,
       
  2143                         CyBool pin,
       
  2144                         CyBool uvalid_special,
       
  2145                         CyAsFunctionCallback cb,
       
  2146                         uint32_t client)
       
  2147 {
       
  2148     CyAsDevice *dev_p ;
       
  2149 
       
  2150     dev_p = (CyAsDevice *)handle ;
       
  2151     if(uvalid_special)
       
  2152     {
       
  2153         CyAsHalWriteRegister(dev_p->tag, 0xc5, 0x4) ;
       
  2154     }
       
  2155 
       
  2156     return CyAsMiscEnterStandby(handle, pin, cb, client) ;
       
  2157 }
       
  2158 
       
  2159 CyAsReturnStatus_t
       
  2160 CyAsMiscLeaveStandby(CyAsDeviceHandle handle, CyAsResourceType resource)
       
  2161 {
       
  2162     CyAsDevice *dev_p ;
       
  2163     uint16_t v ;
       
  2164     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2165     uint32_t count = 8 ;
       
  2166     uint8_t  retry = 1 ;
       
  2167 
       
  2168     CyAsLogDebugMessage(6, "CyAsMiscLeaveStandby called") ;
       
  2169     (void)resource ;
       
  2170 
       
  2171     /* Make sure we have a valid device */
       
  2172     dev_p = (CyAsDevice *)handle ;
       
  2173     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2174         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2175 
       
  2176     if (CyAsDeviceIsRegisterStandby(dev_p))
       
  2177     {
       
  2178         /*
       
  2179          * Set a flag to indicate that the West Bridge is waking up from standby.
       
  2180          */
       
  2181         CyAsDeviceSetWaking(dev_p) ;
       
  2182 
       
  2183         /*
       
  2184          * The initial read will not succeed, but will just wake the West Bridge
       
  2185          * device from standby.  Successive reads should succeed and in that way
       
  2186          * we know West Bridge is awake.
       
  2187          */
       
  2188         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_CM_WB_CFG_ID) ;
       
  2189 
       
  2190         do
       
  2191         {
       
  2192             /*
       
  2193              * We have initiated the operation to leave standby, now we need to wait at least
       
  2194              * N ms before trying to access the West Bridge device to insure the PLLs have locked and we
       
  2195              * can talk to the device.
       
  2196              */
       
  2197             if (CyAsDeviceIsCrystal(dev_p))
       
  2198                 CyAsHalSleep(CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL) ;
       
  2199             else
       
  2200                 CyAsHalSleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
       
  2201             v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_CM_WB_CFG_ID) ;
       
  2202 
       
  2203             /*
       
  2204             * If the P-SPI interface mode is in use, there may be a need to re-synchronise the
       
  2205             * serial clock used for Astoria access.
       
  2206             */
       
  2207             if (!IsValidSiliconId(v))
       
  2208             {
       
  2209                 if (CyAsHalSyncDeviceClocks(dev_p->tag) != CyTrue)
       
  2210                 {
       
  2211                     CyAsHalEnableInterrupts (dev_p->stby_int_mask) ;
       
  2212                     return CY_AS_ERROR_TIMEOUT ;
       
  2213                 }
       
  2214             }
       
  2215         } while (!IsValidSiliconId(v) && count-- > 0) ;
       
  2216 
       
  2217         /*
       
  2218          * If we tried to read the register and could not, return a timeout
       
  2219          */
       
  2220         if (count == 0)
       
  2221         {
       
  2222             CyAsHalEnableInterrupts (dev_p->stby_int_mask) ;
       
  2223             return CY_AS_ERROR_TIMEOUT ;
       
  2224         }
       
  2225 
       
  2226         /*
       
  2227          * The standby flag is cleared here, after the action to exit standby has
       
  2228          * been taken. The wait for firmware initialization, is ensured by marking
       
  2229          * the firmware as not loaded until the init event is received.
       
  2230          */
       
  2231         CyAsDeviceClearRegisterStandby(dev_p) ;
       
  2232 
       
  2233         /*
       
  2234          * Initialize any registers that may have been changed while the device was in standby mode.
       
  2235          */
       
  2236         CyAsHalInitDevRegisters(dev_p->tag, CyTrue) ;
       
  2237     }
       
  2238     else if (CyAsDeviceIsPinStandby(dev_p))
       
  2239     {
       
  2240         /*
       
  2241          * Set a flag to indicate that the West Bridge is waking up from standby.
       
  2242          */
       
  2243         CyAsDeviceSetWaking(dev_p) ;
       
  2244 
       
  2245 TryWakeupAgain:
       
  2246         /*
       
  2247         * Try to set the wakeup pin, if this fails in the HAL layer, return this
       
  2248         * failure to the user.
       
  2249         */
       
  2250         if (!CyAsHalSetWakeupPin(dev_p->tag, CyTrue))
       
  2251         {
       
  2252             CyAsHalEnableInterrupts (dev_p->stby_int_mask) ;
       
  2253             return CY_AS_ERROR_SETTING_WAKEUP_PIN ;
       
  2254         }
       
  2255 
       
  2256         /*
       
  2257         * We have initiated the operation to leave standby, now we need to wait at least
       
  2258         * N ms before trying to access the West Bridge device to insure the PLLs have locked and we
       
  2259         * can talk to the device.
       
  2260         */
       
  2261         if (CyAsDeviceIsCrystal(dev_p))
       
  2262             CyAsHalSleep(CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL) ;
       
  2263         else
       
  2264             CyAsHalSleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
       
  2265 
       
  2266         /*
       
  2267          * Initialize any registers that may have been changed while the device was in standby mode.
       
  2268          */
       
  2269         CyAsHalInitDevRegisters(dev_p->tag, CyTrue) ;
       
  2270 
       
  2271         /*
       
  2272          * The standby flag is cleared here, after the action to exit standby has
       
  2273          * been taken. The wait for firmware initialization, is ensured by marking
       
  2274          * the firmware as not loaded until the init event is received.
       
  2275          */
       
  2276         CyAsDeviceClearPinStandby(dev_p) ;
       
  2277     }
       
  2278     else
       
  2279     {
       
  2280         return CY_AS_ERROR_NOT_IN_STANDBY ;
       
  2281     }
       
  2282 
       
  2283     /*
       
  2284      * The West Bridge interrupt can be enabled now.
       
  2285      */
       
  2286     CyAsHalEnableInterrupts (dev_p->stby_int_mask) ;
       
  2287 
       
  2288     /*
       
  2289      * Release the West Bridge Micro-Controller from reset, so that firmware initialization
       
  2290      * can complete.
       
  2291      * The attempt to release Antioch reset is made upto 8 times.
       
  2292      */
       
  2293     v     = 0x03 ;
       
  2294     count = 0x08 ;
       
  2295     while ((v & 0x03) && (count))
       
  2296     {
       
  2297         CyAsHalWriteRegister(dev_p->tag, CY_AS_MEM_RST_CTRL_REG, 0x00) ;
       
  2298         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_RST_CTRL_REG) ;
       
  2299         count-- ;
       
  2300     }
       
  2301 
       
  2302     if (v & 0x03)
       
  2303     {
       
  2304         CyAsHalPrintMessage("Failed to clear Antioch reset\n") ;
       
  2305         return CY_AS_ERROR_TIMEOUT ;
       
  2306     }
       
  2307 
       
  2308     /*
       
  2309      * If the wake-up pin is being used, wait here to make sure that the wake-up event
       
  2310      * is received within a reasonable delay. Otherwise, toggle the wake-up pin again
       
  2311      * in an attempt to start the firmware properly.
       
  2312      */
       
  2313     if (retry)
       
  2314     {
       
  2315         count = 10 ;
       
  2316         while (count)
       
  2317         {
       
  2318             /* If the wake-up event has been received, we can return. */
       
  2319             if (CyAsDeviceIsFirmwareLoaded (dev_p))
       
  2320                 break ;
       
  2321             /* If we are in polling mode, the interrupt may not have been serviced as yet.
       
  2322              * Read the interrupt status register. If a pending mailbox interrupt is seen,
       
  2323              * we can assume that the wake-up event will be received soon. */
       
  2324             v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_P0_INTR_REG) ;
       
  2325             if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
       
  2326                 break ;
       
  2327 
       
  2328             CyAsHalSleep (10) ;
       
  2329             count-- ;
       
  2330         }
       
  2331 
       
  2332         if (!count)
       
  2333         {
       
  2334             retry = 0 ;
       
  2335             dev_p->stby_int_mask = CyAsHalDisableInterrupts() ;
       
  2336             CyAsHalSetWakeupPin(dev_p->tag, CyFalse) ;
       
  2337             CyAsHalSleep (10) ;
       
  2338             goto TryWakeupAgain ;
       
  2339         }
       
  2340     }
       
  2341 
       
  2342     return ret ;
       
  2343 }
       
  2344 
       
  2345 CyAsReturnStatus_t
       
  2346 CyAsMiscRegisterCallback(
       
  2347                          CyAsDeviceHandle               handle,         /* Handle to the West Bridge device */
       
  2348                          CyAsMiscEventCallback  callback        /* The function to call */
       
  2349                          )
       
  2350 {
       
  2351     CyAsDevice *dev_p ;
       
  2352 
       
  2353     CyAsLogDebugMessage(6, "CyAsMiscRegisterCallback called") ;
       
  2354 
       
  2355     /* Make sure we have a valid device */
       
  2356     dev_p = (CyAsDevice *)handle ;
       
  2357     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2358         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2359 
       
  2360     dev_p->misc_event_cb = callback ;
       
  2361     return CY_AS_ERROR_SUCCESS ;
       
  2362 }
       
  2363 
       
  2364 CyAsReturnStatus_t
       
  2365 CyAsMiscStorageChanged(CyAsDeviceHandle handle,
       
  2366                          CyAsFunctionCallback   cb,
       
  2367                          uint32_t client)
       
  2368 {
       
  2369     CyAsDevice *dev_p ;
       
  2370     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2371     CyBool standby ;
       
  2372     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2373 
       
  2374     CyAsLogDebugMessage(6, "CyAsMiscStorageChanged called") ;
       
  2375 
       
  2376     /* Make sure the device is ready for the command. */
       
  2377     dev_p = (CyAsDevice *)handle ;
       
  2378     CyAsCheckDeviceReady(dev_p) ;
       
  2379 
       
  2380     /*
       
  2381     * Make sure Antioch is not in standby
       
  2382     */
       
  2383     ret = CyAsMiscInStandby(dev_p, &standby) ;
       
  2384     if (ret != CY_AS_ERROR_SUCCESS)
       
  2385         return ret ;
       
  2386 
       
  2387     if (standby)
       
  2388         return CY_AS_ERROR_IN_STANDBY ;
       
  2389 
       
  2390     /*
       
  2391      * Make sure Westbridge is not in suspend mode.
       
  2392      */
       
  2393     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  2394         return CY_AS_ERROR_IN_SUSPEND ;
       
  2395 
       
  2396     /* Create the request to send to the West Bridge device */
       
  2397     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_STORAGE_MEDIA_CHANGED, CY_RQT_GENERAL_RQT_CONTEXT, 0) ;
       
  2398     if (req_p == 0)
       
  2399         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2400 
       
  2401     /* Reserve space for the reply, the reply data will not exceed one word */
       
  2402     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  2403     if (reply_p == 0)
       
  2404     {
       
  2405         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2406         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2407     }
       
  2408 
       
  2409     if(cb == 0)
       
  2410     {
       
  2411         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2412         if (ret != CY_AS_ERROR_SUCCESS)
       
  2413             goto destroy ;
       
  2414 
       
  2415         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  2416         {
       
  2417             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2418             goto destroy ;
       
  2419         }
       
  2420 
       
  2421         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2422     }
       
  2423     else
       
  2424     {
       
  2425 
       
  2426         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_STORAGECHANGED,
       
  2427             0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  2428             CyAsMiscFuncCallback) ;
       
  2429 
       
  2430         if (ret != CY_AS_ERROR_SUCCESS)
       
  2431                 goto destroy ;
       
  2432 
       
  2433         /* The request and response are freed as part of the MiscFuncCallback */
       
  2434         return ret ;
       
  2435     }
       
  2436 
       
  2437 destroy:
       
  2438     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2439     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2440 
       
  2441     return ret ;
       
  2442 }
       
  2443 
       
  2444 
       
  2445 CyAsReturnStatus_t
       
  2446 CyAsMiscEnterSuspend(
       
  2447         CyAsDeviceHandle     handle,
       
  2448         CyBool               usb_wakeup_en,
       
  2449         CyBool               gpio_wakeup_en,
       
  2450         CyAsFunctionCallback cb,
       
  2451         uint32_t             client)
       
  2452 {
       
  2453     CyAsDevice *dev_p ;
       
  2454     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2455     CyBool standby ;
       
  2456     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2457     uint16_t value ;
       
  2458     uint32_t int_state ;
       
  2459 
       
  2460     CyAsLogDebugMessage(6, "CyAsMiscEnterSuspend called") ;
       
  2461 
       
  2462     /*
       
  2463      * Basic sanity checks to ensure that the device is initialised.
       
  2464      */
       
  2465     dev_p = (CyAsDevice *)handle ;
       
  2466     CyAsCheckDeviceReady(dev_p) ;
       
  2467 
       
  2468     /*
       
  2469      * Make sure West Bridge is not already in standby
       
  2470      */
       
  2471     CyAsMiscInStandby(dev_p, &standby) ;
       
  2472     if (standby)
       
  2473         return CY_AS_ERROR_IN_STANDBY ;
       
  2474 
       
  2475     /*
       
  2476      * Make sure that the device is not already in suspend mode.
       
  2477      */
       
  2478     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  2479         return CY_AS_ERROR_IN_SUSPEND ;
       
  2480 
       
  2481     /*
       
  2482      * Make sure there is no active USB connection.
       
  2483      */
       
  2484     if ((CyAsDeviceIsUsbConnected(dev_p)) && (dev_p->usb_last_event != CyAsEventUsbSuspend))
       
  2485         return CY_AS_ERROR_USB_CONNECTED ;
       
  2486 
       
  2487     /*
       
  2488      * Make sure that there are no async requests at this point in time.
       
  2489      */
       
  2490     int_state = CyAsHalDisableInterrupts() ;
       
  2491     if ((dev_p->func_cbs_misc->count) || (dev_p->func_cbs_res->count) ||
       
  2492             (dev_p->func_cbs_stor->count) || (dev_p->func_cbs_usb->count))
       
  2493     {
       
  2494         CyAsHalEnableInterrupts(int_state) ;
       
  2495         return CY_AS_ERROR_ASYNC_PENDING ;
       
  2496     }
       
  2497     CyAsHalEnableInterrupts(int_state) ;
       
  2498 
       
  2499     /* Create the request to send to the Antioch device */
       
  2500     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ENTER_SUSPEND_MODE, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  2501     if (req_p == 0)
       
  2502         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2503 
       
  2504     /* Reserve space for the reply, the reply data will not exceed one word */
       
  2505     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  2506     if (reply_p == 0)
       
  2507     {
       
  2508         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2509         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2510     }
       
  2511 
       
  2512     /* Wakeup control flags. */
       
  2513     value = 0x0001 ;
       
  2514     if (usb_wakeup_en)
       
  2515         value |= 0x04 ;
       
  2516     if (gpio_wakeup_en)
       
  2517         value |= 0x02 ;
       
  2518     CyAsLLRequestResponse_SetWord(req_p, 0, value) ;
       
  2519 
       
  2520     if (cb != 0)
       
  2521     {
       
  2522 
       
  2523         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_ENTERSUSPEND,
       
  2524             0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  2525             CyAsMiscFuncCallback) ;
       
  2526 
       
  2527         if (ret != CY_AS_ERROR_SUCCESS)
       
  2528                 goto destroy ;
       
  2529 
       
  2530         return CY_AS_ERROR_SUCCESS ;
       
  2531     }
       
  2532     else
       
  2533     {
       
  2534         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2535         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  2536             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2537         else
       
  2538             ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2539     }
       
  2540 
       
  2541 destroy:
       
  2542     if (ret == CY_AS_ERROR_SUCCESS)
       
  2543         CyAsDeviceSetSuspendMode(dev_p) ;
       
  2544 
       
  2545     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2546     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2547 
       
  2548     return ret ;
       
  2549 }
       
  2550 
       
  2551 CyAsReturnStatus_t
       
  2552 CyAsMiscLeaveSuspend(
       
  2553         CyAsDeviceHandle     handle,
       
  2554         CyAsFunctionCallback cb,
       
  2555         uint32_t             client)
       
  2556 {
       
  2557     CyAsDevice *dev_p ;
       
  2558     uint16_t v, count ;
       
  2559     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2560 
       
  2561     CyAsLogDebugMessage(6, "CyAsMiscLeaveSuspend called") ;
       
  2562 
       
  2563     /* Make sure we have a valid device */
       
  2564     dev_p = (CyAsDevice *)handle ;
       
  2565     CyAsCheckDeviceReady(dev_p) ;
       
  2566 
       
  2567     /* Make sure we are in suspend mode. */
       
  2568     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  2569     {
       
  2570         if (cb)
       
  2571         {
       
  2572             CyAsFuncCBNode *cbnode = CyAsCreateFuncCBNodeData(cb, client, CY_FUNCT_CB_MISC_LEAVESUSPEND, 0) ;
       
  2573             if (cbnode == 0)
       
  2574                 return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2575 
       
  2576             CyAsInsertCBNode(dev_p->func_cbs_misc, cbnode) ;
       
  2577         }
       
  2578 
       
  2579         /*
       
  2580          * Do a read from the ID register so that the CE assertion will wake West Bridge.
       
  2581          * The read is repeated until the read comes back with valid data.
       
  2582          */
       
  2583         count = 8 ;
       
  2584 
       
  2585         v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_CM_WB_CFG_ID) ;
       
  2586 
       
  2587         while (!IsValidSiliconId(v) && count-- > 0)
       
  2588         {
       
  2589             CyAsHalSleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
       
  2590             v = CyAsHalReadRegister(dev_p->tag, CY_AS_MEM_CM_WB_CFG_ID) ;
       
  2591         }
       
  2592 
       
  2593         /*
       
  2594          * If we tried to read the register and could not, return a timeout
       
  2595          */
       
  2596         if (count == 0)
       
  2597             return CY_AS_ERROR_TIMEOUT ;
       
  2598     }
       
  2599     else
       
  2600         return CY_AS_ERROR_NOT_IN_SUSPEND ;
       
  2601 
       
  2602     if (cb == 0)
       
  2603     {
       
  2604         /*
       
  2605          * Wait until the in suspend mode flag is cleared.
       
  2606          */
       
  2607         count = 20 ;
       
  2608         while ((CyAsDeviceIsInSuspendMode(dev_p)) && (count--))
       
  2609         {
       
  2610             CyAsHalSleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
       
  2611         }
       
  2612 
       
  2613         if (CyAsDeviceIsInSuspendMode(dev_p))
       
  2614             ret = CY_AS_ERROR_TIMEOUT ;
       
  2615     }
       
  2616 
       
  2617     return ret ;
       
  2618 }
       
  2619 
       
  2620 CyAsReturnStatus_t
       
  2621 CyAsMiscReserveLNABootArea(CyAsDeviceHandle handle,
       
  2622                            uint8_t numzones,
       
  2623                            CyAsFunctionCallback cb,
       
  2624                            uint32_t client)
       
  2625 {
       
  2626     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2627     CyBool standby ;
       
  2628     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2629 
       
  2630     CyAsDevice *dev_p ;
       
  2631 
       
  2632     (void)client ;
       
  2633 
       
  2634     CyAsLogDebugMessage(6, "CyAsMiscSwitchPnandMode called") ;
       
  2635 
       
  2636     /* Make sure we have a valid device */
       
  2637     dev_p = (CyAsDevice *)handle ;
       
  2638     CyAsCheckDeviceReady(dev_p) ;
       
  2639 
       
  2640     /*
       
  2641     * Make sure Antioch is not in standby
       
  2642     */
       
  2643     ret = CyAsMiscInStandby(dev_p, &standby) ;
       
  2644     if (ret != CY_AS_ERROR_SUCCESS)
       
  2645         return ret ;
       
  2646     if (standby)
       
  2647         return CY_AS_ERROR_IN_STANDBY ;
       
  2648 
       
  2649     /* Make sure the Antioch is not in suspend mode. */
       
  2650     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  2651         return CY_AS_ERROR_IN_SUSPEND ;
       
  2652 
       
  2653     /* Create the request to send to the West Bridge device */
       
  2654     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_RESERVE_LNA_BOOT_AREA, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  2655     if (req_p == 0)
       
  2656             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2657         CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)numzones) ;
       
  2658 
       
  2659     /* Reserve space for the reply, the reply data will not exceed one word */
       
  2660     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  2661     if (reply_p == 0)
       
  2662     {
       
  2663             CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2664             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2665     }
       
  2666 
       
  2667     if(cb == 0)
       
  2668     {
       
  2669             ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2670             if (ret != CY_AS_ERROR_SUCCESS)
       
  2671                 goto destroy ;
       
  2672 
       
  2673             if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  2674             {
       
  2675                 ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2676                 goto destroy ;
       
  2677             }
       
  2678 
       
  2679             ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2680     }
       
  2681     else
       
  2682     {
       
  2683 
       
  2684             ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MISC_RESERVELNABOOTAREA,
       
  2685                 0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, req_p,
       
  2686                 reply_p, CyAsMiscFuncCallback) ;
       
  2687 
       
  2688             if (ret != CY_AS_ERROR_SUCCESS)
       
  2689                     goto destroy ;
       
  2690 
       
  2691             /* The request and response are freed as part of the MiscFuncCallback */
       
  2692             return ret ;
       
  2693     }
       
  2694 
       
  2695 destroy:
       
  2696     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2697     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2698 
       
  2699     return ret ;
       
  2700 }
       
  2701 
       
  2702 CyAsFuncCBNode*
       
  2703 CyAsCreateFuncCBNodeData(CyAsFunctionCallback cb,
       
  2704                      uint32_t client,
       
  2705                      CyAsFunctCBType type,
       
  2706                      void* data)
       
  2707 {
       
  2708     uint32_t state = CyAsHalDisableInterrupts() ;
       
  2709     CyAsFuncCBNode* node = (CyAsFuncCBNode*)CyAsHalCBAlloc(sizeof(CyAsFuncCBNode)) ;
       
  2710     CyAsHalEnableInterrupts(state) ;
       
  2711     if(node != 0)
       
  2712     {
       
  2713         node->nodeType = CYAS_FUNC_CB ;
       
  2714         node->cb_p = cb ;
       
  2715         node->client_data = client ;
       
  2716         node->dataType = type ;
       
  2717         if(data != 0)
       
  2718             node->dataType |= CY_FUNCT_CB_DATA ;
       
  2719         else
       
  2720             node->dataType |= CY_FUNCT_CB_NODATA ;
       
  2721         node->data = data ;
       
  2722         node->next_p = 0 ;
       
  2723     }
       
  2724     return node ;
       
  2725 }
       
  2726 
       
  2727 CyAsFuncCBNode*
       
  2728 CyAsCreateFuncCBNode(CyAsFunctionCallback cb,
       
  2729                      uint32_t client)
       
  2730 {
       
  2731     return CyAsCreateFuncCBNodeData(cb, client, CY_FUNCT_CB_NODATA, 0) ;
       
  2732 }
       
  2733 
       
  2734 void
       
  2735 CyAsDestroyFuncCBNode(CyAsFuncCBNode* node)
       
  2736 {
       
  2737     uint32_t state ;
       
  2738 
       
  2739     node->nodeType = CYAS_INVALID ;
       
  2740     state = CyAsHalDisableInterrupts() ;
       
  2741     CyAsHalCBFree(node) ;
       
  2742     CyAsHalEnableInterrupts(state) ;
       
  2743 }
       
  2744 
       
  2745 CyAsUsbFuncCBNode*
       
  2746 CyAsCreateUsbFuncCBNode(CyAsUsbFunctionCallback cb, uint32_t client)
       
  2747 {
       
  2748     uint32_t state = CyAsHalDisableInterrupts() ;
       
  2749     CyAsUsbFuncCBNode * node = (CyAsUsbFuncCBNode *)CyAsHalCBAlloc(sizeof(CyAsUsbFuncCBNode)) ;
       
  2750     CyAsHalEnableInterrupts(state) ;
       
  2751     if(node != 0)
       
  2752     {
       
  2753         node->type = CYAS_USB_FUNC_CB ;
       
  2754         node->cb_p = cb ;
       
  2755         node->client_data = client ;
       
  2756         node->next_p = 0 ;
       
  2757     }
       
  2758     return node ;
       
  2759 }
       
  2760 
       
  2761 void
       
  2762 CyAsDestroyUsbFuncCBNode(CyAsUsbFuncCBNode* node)
       
  2763 {
       
  2764     uint32_t state ;
       
  2765 
       
  2766     node->type = CYAS_INVALID ;
       
  2767     state = CyAsHalDisableInterrupts() ;
       
  2768     CyAsHalCBFree(node) ;
       
  2769     CyAsHalEnableInterrupts(state) ;
       
  2770 }
       
  2771 
       
  2772 CyAsUsbIoCBNode*
       
  2773 CyAsCreateUsbIoCBNode(CyAsUsbIoCallback cb)
       
  2774 {
       
  2775     uint32_t state = CyAsHalDisableInterrupts() ;
       
  2776     CyAsUsbIoCBNode * node = (CyAsUsbIoCBNode *)CyAsHalCBAlloc(sizeof(CyAsUsbIoCBNode)) ;
       
  2777     CyAsHalEnableInterrupts(state) ;
       
  2778     if(node != 0)
       
  2779     {
       
  2780         node->type = CYAS_USB_IO_CB ;
       
  2781         node->cb_p = cb ;
       
  2782         node->next_p = 0 ;
       
  2783     }
       
  2784     return node ;
       
  2785 }
       
  2786 
       
  2787 void
       
  2788 CyAsDestroyUsbIoCBNode(CyAsUsbIoCBNode* node)
       
  2789 {
       
  2790     uint32_t state ;
       
  2791 
       
  2792     node->type = CYAS_INVALID ;
       
  2793 
       
  2794     state = CyAsHalDisableInterrupts() ;
       
  2795     CyAsHalCBFree(node) ;
       
  2796     CyAsHalEnableInterrupts(state) ;
       
  2797 }
       
  2798 
       
  2799 CyAsStorageIoCBNode*
       
  2800 CyAsCreateStorageIoCBNode(CyAsStorageCallback cb, CyAsMediaType media, uint32_t device_index,
       
  2801                           uint32_t unit, uint32_t block_addr, CyAsOperType oper,
       
  2802                           CyAsLLRequestResponse* req_p, CyAsLLRequestResponse* reply_p)
       
  2803 {
       
  2804     uint32_t state = CyAsHalDisableInterrupts() ;
       
  2805     CyAsStorageIoCBNode * node = (CyAsStorageIoCBNode *)CyAsHalCBAlloc(sizeof(CyAsStorageIoCBNode)) ;
       
  2806     CyAsHalEnableInterrupts(state) ;
       
  2807     if(node != 0)
       
  2808     {
       
  2809         node->type = CYAS_STORAGE_IO_CB ;
       
  2810         node->cb_p = cb ;
       
  2811         node->media = media ;
       
  2812         node->device_index = device_index ;
       
  2813         node->unit = unit ;
       
  2814         node->block_addr = block_addr ;
       
  2815         node->oper = oper ;
       
  2816         node->req_p = req_p ;
       
  2817         node->reply_p = reply_p ;
       
  2818         node->next_p = 0 ;
       
  2819     }
       
  2820     return node ;
       
  2821 }
       
  2822 
       
  2823 void
       
  2824 CyAsDestroyStorageIoCBNode(CyAsStorageIoCBNode* node)
       
  2825 {
       
  2826     uint32_t state ;
       
  2827     node->type = CYAS_INVALID ;
       
  2828     state = CyAsHalDisableInterrupts() ;
       
  2829     CyAsHalCBFree(node) ;
       
  2830     CyAsHalEnableInterrupts(state) ;
       
  2831 }
       
  2832 
       
  2833 CyAsCBQueue *
       
  2834 CyAsCreateCBQueue(CyAsCBNodeType type)
       
  2835 {
       
  2836     uint32_t state = CyAsHalDisableInterrupts() ;
       
  2837     CyAsCBQueue * queue = (CyAsCBQueue *)CyAsHalCBAlloc(sizeof(CyAsCBQueue)) ;
       
  2838     CyAsHalEnableInterrupts(state) ;
       
  2839     if(queue)
       
  2840     {
       
  2841         queue->type = type ;
       
  2842         queue->head_p = 0 ;
       
  2843         queue->tail_p = 0 ;
       
  2844         queue->count = 0 ;
       
  2845     }
       
  2846 
       
  2847     return queue ;
       
  2848 }
       
  2849 
       
  2850 void
       
  2851 CyAsDestroyCBQueue(CyAsCBQueue* queue)
       
  2852 {
       
  2853     uint32_t state ;
       
  2854     queue->type = CYAS_INVALID ;
       
  2855     queue->head_p = 0 ;
       
  2856     queue->tail_p = 0 ;
       
  2857     queue->count = 0 ;
       
  2858     state = CyAsHalDisableInterrupts() ;
       
  2859     CyAsHalCBFree(queue) ;
       
  2860     CyAsHalEnableInterrupts(state) ;
       
  2861 }
       
  2862 
       
  2863 /* Inserts a CyAsCBNode into the queue, the node type must match the queue type*/
       
  2864 void
       
  2865 CyAsInsertCBNode(CyAsCBQueue * queue_p, void* cbnode)
       
  2866 {
       
  2867     uint32_t int_state ;
       
  2868 
       
  2869     int_state = CyAsHalDisableInterrupts() ;
       
  2870 
       
  2871     CyAsHalAssert(queue_p != 0) ;
       
  2872 
       
  2873     switch (queue_p->type)
       
  2874     {
       
  2875         case CYAS_USB_FUNC_CB:
       
  2876             {
       
  2877                 CyAsUsbFuncCBNode* node = (CyAsUsbFuncCBNode*)cbnode ;
       
  2878                 CyAsUsbFuncCBNode* tail = (CyAsUsbFuncCBNode*)queue_p->tail_p ;
       
  2879 
       
  2880                 CyAsHalAssert(node->type == CYAS_USB_FUNC_CB) ;
       
  2881                 CyAsHalAssert(tail == 0 || tail->type == CYAS_USB_FUNC_CB) ;
       
  2882                 if(queue_p->head_p == 0)
       
  2883                     queue_p->head_p = node ;
       
  2884                 else
       
  2885                     tail->next_p = node ;
       
  2886 
       
  2887                 queue_p->tail_p = node ;
       
  2888             }
       
  2889             break ;
       
  2890 
       
  2891         case CYAS_USB_IO_CB:
       
  2892             {
       
  2893                 CyAsUsbIoCBNode* node = (CyAsUsbIoCBNode*)cbnode ;
       
  2894                 CyAsUsbIoCBNode* tail = (CyAsUsbIoCBNode*)queue_p->tail_p ;
       
  2895 
       
  2896                 CyAsHalAssert(node->type == CYAS_USB_IO_CB) ;
       
  2897                 CyAsHalAssert(tail == 0 || tail->type == CYAS_USB_IO_CB) ;
       
  2898                 if(queue_p->head_p == 0)
       
  2899                     queue_p->head_p = node ;
       
  2900                 else
       
  2901                     tail->next_p = node ;
       
  2902 
       
  2903                 queue_p->tail_p = node ;
       
  2904             }
       
  2905             break ;
       
  2906 
       
  2907         case CYAS_STORAGE_IO_CB:
       
  2908             {
       
  2909                 CyAsStorageIoCBNode* node = (CyAsStorageIoCBNode*)cbnode ;
       
  2910                 CyAsStorageIoCBNode* tail = (CyAsStorageIoCBNode*)queue_p->tail_p ;
       
  2911 
       
  2912                 CyAsHalAssert(node->type == CYAS_STORAGE_IO_CB) ;
       
  2913                 CyAsHalAssert(tail == 0 || tail->type == CYAS_STORAGE_IO_CB) ;
       
  2914                 if(queue_p->head_p == 0)
       
  2915                     queue_p->head_p = node ;
       
  2916                 else
       
  2917                     tail->next_p = node ;
       
  2918 
       
  2919                 queue_p->tail_p = node ;
       
  2920             }
       
  2921             break ;
       
  2922 
       
  2923         case CYAS_FUNC_CB:
       
  2924             {
       
  2925                 CyAsFuncCBNode* node = (CyAsFuncCBNode*)cbnode ;
       
  2926                 CyAsFuncCBNode* tail = (CyAsFuncCBNode*)queue_p->tail_p ;
       
  2927 
       
  2928                 CyAsHalAssert(node->nodeType == CYAS_FUNC_CB) ;
       
  2929                 CyAsHalAssert(tail == 0 || tail->nodeType == CYAS_FUNC_CB) ;
       
  2930                 if(queue_p->head_p == 0)
       
  2931                     queue_p->head_p = node ;
       
  2932                 else
       
  2933                     tail->next_p = node ;
       
  2934 
       
  2935                 queue_p->tail_p = node ;
       
  2936             }
       
  2937             break ;
       
  2938 
       
  2939         default:
       
  2940             CyAsHalAssert(CyFalse) ;
       
  2941             break ;
       
  2942     }
       
  2943 
       
  2944     queue_p->count++ ;
       
  2945 
       
  2946     CyAsHalEnableInterrupts(int_state) ;
       
  2947 }
       
  2948 
       
  2949 /* Removes the tail node from the queue and frees it */
       
  2950 void
       
  2951 CyAsRemoveCBTailNode(CyAsCBQueue *queue_p)
       
  2952 {
       
  2953     uint32_t int_state ;
       
  2954 
       
  2955     int_state = CyAsHalDisableInterrupts () ;
       
  2956 
       
  2957     if (queue_p->count > 0)
       
  2958     {
       
  2959         /*
       
  2960          * The worst case length of the queue should be under 10 elements, and the average
       
  2961          * case should be just 1 element. So, we just employ a linear search to find the node
       
  2962          * to be freed.
       
  2963          */
       
  2964         switch (queue_p->type)
       
  2965         {
       
  2966             case CYAS_FUNC_CB:
       
  2967                 {
       
  2968                     CyAsFuncCBNode* node = (CyAsFuncCBNode*)queue_p->head_p ;
       
  2969                     CyAsFuncCBNode* tail = (CyAsFuncCBNode*)queue_p->tail_p ;
       
  2970                     if (node != tail)
       
  2971                     {
       
  2972                         while (node->next_p != tail)
       
  2973                             node = node->next_p ;
       
  2974                         node->next_p = 0 ;
       
  2975                         queue_p->tail_p = node ;
       
  2976                     }
       
  2977                     CyAsDestroyFuncCBNode (tail) ;
       
  2978                 }
       
  2979                 break ;
       
  2980 
       
  2981             case CYAS_USB_FUNC_CB:
       
  2982                 {
       
  2983                     CyAsUsbFuncCBNode* node = (CyAsUsbFuncCBNode*)queue_p->head_p ;
       
  2984                     CyAsUsbFuncCBNode* tail = (CyAsUsbFuncCBNode*)queue_p->tail_p ;
       
  2985                     if (node != tail)
       
  2986                     {
       
  2987                         while (node->next_p != tail)
       
  2988                             node = node->next_p ;
       
  2989                         node->next_p = 0 ;
       
  2990                         queue_p->tail_p = node ;
       
  2991                     }
       
  2992 
       
  2993                     CyAsDestroyUsbFuncCBNode (tail) ;
       
  2994                 }
       
  2995                 break ;
       
  2996 
       
  2997             case CYAS_USB_IO_CB:
       
  2998                 {
       
  2999                     CyAsUsbIoCBNode* node = (CyAsUsbIoCBNode*)queue_p->head_p ;
       
  3000                     CyAsUsbIoCBNode* tail = (CyAsUsbIoCBNode*)queue_p->tail_p ;
       
  3001                     if (node != tail)
       
  3002                     {
       
  3003                         while (node->next_p != tail)
       
  3004                             node = node->next_p ;
       
  3005                         node->next_p = 0 ;
       
  3006                         queue_p->tail_p = node ;
       
  3007                     }
       
  3008                     CyAsDestroyUsbIoCBNode (tail) ;
       
  3009                 }
       
  3010                 break ;
       
  3011 
       
  3012             case CYAS_STORAGE_IO_CB:
       
  3013                 {
       
  3014                     CyAsStorageIoCBNode* node = (CyAsStorageIoCBNode*)queue_p->head_p ;
       
  3015                     CyAsStorageIoCBNode* tail = (CyAsStorageIoCBNode*)queue_p->tail_p ;
       
  3016                     if (node != tail)
       
  3017                     {
       
  3018                         while (node->next_p != tail)
       
  3019                             node = node->next_p ;
       
  3020                         node->next_p = 0 ;
       
  3021                         queue_p->tail_p = node ;
       
  3022                     }
       
  3023                     CyAsDestroyStorageIoCBNode (tail) ;
       
  3024                 }
       
  3025                 break ;
       
  3026 
       
  3027             default:
       
  3028                 CyAsHalAssert (CyFalse) ;
       
  3029         }
       
  3030 
       
  3031         queue_p->count-- ;
       
  3032         if (queue_p->count == 0)
       
  3033         {
       
  3034             queue_p->head_p = 0 ;
       
  3035             queue_p->tail_p = 0 ;
       
  3036         }
       
  3037     }
       
  3038 
       
  3039     CyAsHalEnableInterrupts (int_state) ;
       
  3040 }
       
  3041 
       
  3042 /* Removes the first CyAsCBNode from the queue and frees it */
       
  3043 void
       
  3044 CyAsRemoveCBNode(CyAsCBQueue * queue_p)
       
  3045 {
       
  3046     uint32_t int_state ;
       
  3047 
       
  3048     int_state = CyAsHalDisableInterrupts() ;
       
  3049 
       
  3050     CyAsHalAssert(queue_p->count >= 0) ;
       
  3051     if(queue_p->count > 0)
       
  3052     {
       
  3053         if(queue_p->type == CYAS_USB_FUNC_CB)
       
  3054         {
       
  3055             CyAsUsbFuncCBNode* node = (CyAsUsbFuncCBNode*)queue_p->head_p ;
       
  3056             queue_p->head_p = node->next_p ;
       
  3057             CyAsDestroyUsbFuncCBNode(node) ;
       
  3058         }
       
  3059         else if(queue_p->type == CYAS_USB_IO_CB)
       
  3060         {
       
  3061             CyAsUsbIoCBNode* node = (CyAsUsbIoCBNode*)queue_p->head_p ;
       
  3062             queue_p->head_p = node->next_p ;
       
  3063             CyAsDestroyUsbIoCBNode(node) ;
       
  3064         }
       
  3065         else if(queue_p->type == CYAS_STORAGE_IO_CB)
       
  3066         {
       
  3067             CyAsStorageIoCBNode* node = (CyAsStorageIoCBNode*)queue_p->head_p ;
       
  3068             queue_p->head_p = node->next_p ;
       
  3069             CyAsDestroyStorageIoCBNode(node) ;
       
  3070         }
       
  3071         else if(queue_p->type == CYAS_FUNC_CB)
       
  3072         {
       
  3073             CyAsFuncCBNode* node = (CyAsFuncCBNode*)queue_p->head_p ;
       
  3074             queue_p->head_p = node->next_p ;
       
  3075             CyAsDestroyFuncCBNode(node) ;
       
  3076         }
       
  3077         else
       
  3078         {
       
  3079             CyAsHalAssert(CyFalse) ;
       
  3080         }
       
  3081 
       
  3082         queue_p->count-- ;
       
  3083         if(queue_p->count == 0)
       
  3084         {
       
  3085             queue_p->head_p = 0 ;
       
  3086             queue_p->tail_p = 0 ;
       
  3087         }
       
  3088     }
       
  3089 
       
  3090     CyAsHalEnableInterrupts(int_state) ;
       
  3091 }
       
  3092 
       
  3093 void MyPrintFuncCBNode(CyAsFuncCBNode* node)
       
  3094 {
       
  3095     CyAsFunctCBType type = CyAsFunctCBTypeGetType(node->dataType) ;
       
  3096     CyAsHalPrintMessage("[cd:%2u dt:%2u cb:0x%08x d:0x%08x nt:%1i]",
       
  3097         node->client_data, type, (uint32_t)node->cb_p, (uint32_t)node->data, node->nodeType) ;
       
  3098 }
       
  3099 
       
  3100 void MyPrintCBQueue(CyAsCBQueue* queue_p)
       
  3101 {
       
  3102     uint32_t i = 0 ;
       
  3103 
       
  3104     CyAsHalPrintMessage("| Count: %u Type: ", queue_p->count) ;
       
  3105 
       
  3106     if(queue_p->type == CYAS_USB_FUNC_CB)
       
  3107     {
       
  3108         CyAsHalPrintMessage("USB_FUNC_CB\n") ;
       
  3109     }
       
  3110     else if(queue_p->type == CYAS_USB_IO_CB)
       
  3111     {
       
  3112         CyAsHalPrintMessage("USB_IO_CB\n") ;
       
  3113     }
       
  3114     else if(queue_p->type == CYAS_STORAGE_IO_CB)
       
  3115     {
       
  3116         CyAsHalPrintMessage("STORAGE_IO_CB\n") ;
       
  3117     }
       
  3118     else if(queue_p->type == CYAS_FUNC_CB)
       
  3119     {
       
  3120         CyAsFuncCBNode* node = (CyAsFuncCBNode*)queue_p->head_p ;
       
  3121         CyAsHalPrintMessage("FUNC_CB\n") ;
       
  3122         if(queue_p->count > 0)
       
  3123         {
       
  3124             CyAsHalPrintMessage("| Head->") ;
       
  3125 
       
  3126             for(i = 0; i < queue_p->count; i++)
       
  3127             {
       
  3128                 if(node)
       
  3129                 {
       
  3130                     CyAsHalPrintMessage("->") ;
       
  3131                     MyPrintFuncCBNode(node) ;
       
  3132                     node = node->next_p ;
       
  3133                 }
       
  3134                 else
       
  3135                     CyAsHalPrintMessage("->[NULL]\n") ;
       
  3136             }
       
  3137 
       
  3138             CyAsHalPrintMessage("\n| Tail->") ;
       
  3139             MyPrintFuncCBNode((CyAsFuncCBNode*)queue_p->tail_p) ;
       
  3140             CyAsHalPrintMessage("\n") ;
       
  3141         }
       
  3142     }
       
  3143     else
       
  3144     {
       
  3145         CyAsHalPrintMessage("INVALID\n") ;
       
  3146     }
       
  3147 
       
  3148     CyAsHalPrintMessage("|----------\n") ;
       
  3149 }
       
  3150 
       
  3151 
       
  3152 /* Removes and frees all pending callbacks */
       
  3153 void
       
  3154 CyAsClearCBQueue(CyAsCBQueue * queue_p)
       
  3155 {
       
  3156     uint32_t int_state = CyAsHalDisableInterrupts() ;
       
  3157 
       
  3158     while(queue_p->count != 0)
       
  3159         CyAsRemoveCBNode(queue_p) ;
       
  3160 
       
  3161     CyAsHalEnableInterrupts(int_state) ;
       
  3162 }
       
  3163 
       
  3164 CyAsReturnStatus_t
       
  3165 CyAsMiscSendRequest(CyAsDevice* dev_p,
       
  3166                       CyAsFunctionCallback cb,
       
  3167                       uint32_t client,
       
  3168                       CyAsFunctCBType type,
       
  3169                       void* data,
       
  3170                       CyAsCBQueue* queue,
       
  3171                       uint16_t req_type,
       
  3172                       CyAsLLRequestResponse *req_p,
       
  3173                       CyAsLLRequestResponse *reply_p,
       
  3174                       CyAsResponseCallback rcb)
       
  3175 {
       
  3176 
       
  3177     CyAsFuncCBNode* cbnode = CyAsCreateFuncCBNodeData(cb, client, type, data) ;
       
  3178     CyAsReturnStatus_t ret ;
       
  3179 
       
  3180     if(cbnode == 0)
       
  3181         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3182     else
       
  3183         CyAsInsertCBNode(queue, cbnode) ;
       
  3184 
       
  3185     req_p->flags |= req_type ;
       
  3186 
       
  3187     ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, rcb) ;
       
  3188     if (ret != CY_AS_ERROR_SUCCESS)
       
  3189     {
       
  3190         CyAsRemoveCBTailNode(queue) ;
       
  3191     }
       
  3192 
       
  3193     return ret ;
       
  3194 }
       
  3195 
       
  3196 void
       
  3197 CyAsMiscCancelExRequests(CyAsDevice *dev_p)
       
  3198 {
       
  3199     int i ;
       
  3200     for(i = 0; i < CY_RQT_CONTEXT_COUNT; i++)
       
  3201         CyAsLLRemoveAllRequests(dev_p, dev_p->context[i]) ;
       
  3202 }
       
  3203 
       
  3204 
       
  3205 static void
       
  3206 CyAsMiscFuncCallback(CyAsDevice *dev_p,
       
  3207                         uint8_t context,
       
  3208                         CyAsLLRequestResponse *rqt,
       
  3209                         CyAsLLRequestResponse *resp,
       
  3210                         CyAsReturnStatus_t stat)
       
  3211 {
       
  3212     CyAsFuncCBNode* node = NULL ;
       
  3213     CyAsReturnStatus_t ret ;
       
  3214 
       
  3215     CyBool              exRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX) == CY_AS_REQUEST_RESPONSE_EX ;
       
  3216     CyBool              msRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS) == CY_AS_REQUEST_RESPONSE_MS ;
       
  3217     uint8_t             code ;
       
  3218     uint32_t            type ;
       
  3219     uint8_t             cntxt ;
       
  3220 
       
  3221     CyAsHalAssert(exRequest || msRequest) ;
       
  3222     (void) exRequest;
       
  3223     (void) msRequest;
       
  3224     (void)context ;
       
  3225 
       
  3226     cntxt = CyAsLLRequestResponse_GetContext(rqt) ;
       
  3227     code = CyAsLLRequestResponse_GetCode(rqt) ;
       
  3228 
       
  3229     switch(cntxt)
       
  3230     {
       
  3231     case CY_RQT_GENERAL_RQT_CONTEXT:
       
  3232         CyAsHalAssert(dev_p->func_cbs_misc->count != 0) ;
       
  3233         CyAsHalAssert(dev_p->func_cbs_misc->type == CYAS_FUNC_CB) ;
       
  3234         node = (CyAsFuncCBNode*)dev_p->func_cbs_misc->head_p ;
       
  3235         type = CyAsFunctCBTypeGetType(node->dataType) ;
       
  3236 
       
  3237         switch(code)
       
  3238         {
       
  3239         case CY_RQT_GET_FIRMWARE_VERSION:
       
  3240             CyAsHalAssert(node->data != 0) ;
       
  3241             CyAsHalAssert(type == CY_FUNCT_CB_MISC_GETFIRMWAREVERSION) ;
       
  3242             ret = MyHandleResponseGetFirmwareVersion(dev_p, rqt, resp, (CyAsGetFirmwareVersionData*)node->data) ;
       
  3243             break ;
       
  3244         case CY_RQT_READ_MCU_REGISTER:
       
  3245             CyAsHalAssert(node->data != 0) ;
       
  3246             CyAsHalAssert(type == CY_FUNCT_CB_MISC_READMCUREGISTER) ;
       
  3247             ret = MyHandleResponseReadMCURegister(dev_p, rqt, resp, (uint8_t*)node->data) ;
       
  3248             break ;
       
  3249         case CY_RQT_GET_GPIO_STATE:
       
  3250             CyAsHalAssert(node->data != 0) ;
       
  3251             CyAsHalAssert(type == CY_FUNCT_CB_MISC_GETGPIOVALUE) ;
       
  3252             ret = MyHandleResponseGetGpioValue(dev_p, rqt, resp, (uint8_t*)node->data) ;
       
  3253             break ;
       
  3254         case CY_RQT_SET_SD_CLOCK_FREQ:
       
  3255             CyAsHalAssert(type == CY_FUNCT_CB_MISC_SETSDFREQ) ;
       
  3256             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3257             break ;
       
  3258         case CY_RQT_CONTROL_ANTIOCH_HEARTBEAT:
       
  3259             CyAsHalAssert(type == CY_FUNCT_CB_MISC_HEARTBEATCONTROL) ;
       
  3260             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3261             break ;
       
  3262         case CY_RQT_WRITE_MCU_REGISTER:
       
  3263             CyAsHalAssert(type == CY_FUNCT_CB_MISC_WRITEMCUREGISTER) ;
       
  3264             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3265             break ;
       
  3266         case CY_RQT_STORAGE_MEDIA_CHANGED:
       
  3267             CyAsHalAssert(type == CY_FUNCT_CB_MISC_STORAGECHANGED) ;
       
  3268             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3269             break ;
       
  3270         case CY_RQT_SET_GPIO_STATE:
       
  3271             CyAsHalAssert(type == CY_FUNCT_CB_MISC_SETGPIOVALUE) ;
       
  3272             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3273             break ;
       
  3274         case CY_RQT_SET_TRACE_LEVEL:
       
  3275             CyAsHalAssert(type == CY_FUNCT_CB_MISC_SETTRACELEVEL) ;
       
  3276             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3277             if (ret == CY_AS_ERROR_INVALID_RESPONSE)
       
  3278                 ret = CY_AS_ERROR_NOT_SUPPORTED ;
       
  3279             break ;
       
  3280         case CY_RQT_PREPARE_FOR_STANDBY:
       
  3281             CyAsHalAssert(type == CY_FUNCT_CB_MISC_ENTERSTANDBY) ;
       
  3282             ret = MyHandleResponseEnterStandby(dev_p, rqt, resp, (CyBool)node->data) ;
       
  3283             break ;
       
  3284         case CY_RQT_ENTER_SUSPEND_MODE:
       
  3285             CyAsHalAssert(type == CY_FUNCT_CB_MISC_ENTERSUSPEND) ;
       
  3286             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3287             if (ret == CY_AS_ERROR_SUCCESS)
       
  3288             {
       
  3289                 CyAsDeviceSetSuspendMode(dev_p) ;
       
  3290             }
       
  3291             break ;
       
  3292     case CY_RQT_RESERVE_LNA_BOOT_AREA:
       
  3293             CyAsHalAssert(type == CY_FUNCT_CB_MISC_RESERVELNABOOTAREA) ;
       
  3294             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3295             break ;
       
  3296     case CY_RQT_SDPOLARITY:
       
  3297             CyAsHalAssert(type == CY_FUNCT_CB_MISC_SETSDPOLARITY) ;
       
  3298             ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  3299             break ;
       
  3300 
       
  3301 
       
  3302     default:
       
  3303             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3304             CyAsHalAssert(CyFalse) ;
       
  3305             break ;
       
  3306         }
       
  3307         break ;
       
  3308 
       
  3309     case CY_RQT_RESOURCE_RQT_CONTEXT:
       
  3310         CyAsHalAssert(dev_p->func_cbs_res->count != 0) ;
       
  3311         CyAsHalAssert(dev_p->func_cbs_res->type == CYAS_FUNC_CB) ;
       
  3312         node = (CyAsFuncCBNode*)dev_p->func_cbs_res->head_p ;
       
  3313         type = CyAsFunctCBTypeGetType(node->dataType) ;
       
  3314 
       
  3315         switch(code)
       
  3316         {
       
  3317         case CY_RQT_ACQUIRE_RESOURCE:
       
  3318             /* The node->data field is actually an enum value which could be
       
  3319             0, thus no assert is done */
       
  3320             CyAsHalAssert(type == CY_FUNCT_CB_MISC_ACQUIRERESOURCE) ;
       
  3321             ret = MyHandleResponseAcquireResource(dev_p, rqt, resp, (CyAsResourceType*)node->data) ;
       
  3322             break ;
       
  3323         default:
       
  3324             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3325             CyAsHalAssert(CyFalse) ;
       
  3326             break ;
       
  3327         }
       
  3328         break ;
       
  3329 
       
  3330     default:
       
  3331         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3332         CyAsHalAssert(CyFalse) ;
       
  3333         break ;
       
  3334     }
       
  3335 
       
  3336     /*
       
  3337      * If the low level layer returns a direct error, use the corresponding error code.
       
  3338      * If not, use the error code based on the response from firmware.
       
  3339      */
       
  3340     if (stat == CY_AS_ERROR_SUCCESS)
       
  3341         stat = ret ;
       
  3342 
       
  3343     /* Call the user Callback */
       
  3344     node->cb_p((CyAsDeviceHandle)dev_p, stat, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ;
       
  3345     if(cntxt == CY_RQT_GENERAL_RQT_CONTEXT)
       
  3346         CyAsRemoveCBNode(dev_p->func_cbs_misc) ;
       
  3347     else
       
  3348         CyAsRemoveCBNode(dev_p->func_cbs_res) ;
       
  3349 
       
  3350 }
       
  3351 
       
  3352 
       
  3353 /* This includes the implementation of the deprecated functions for backward
       
  3354  * compatibility
       
  3355  */
       
  3356 #include "cyasmisc_dep_impl.h"
       
  3357 
       
  3358 /*[]*/
       
  3359