PRSDK-3513 Modified xs file to build.
[keystone-rtos/mcbsp-lld.git] / src / mcbsp_drv.c
1 /*
2  * mcbsp_drv.c
3  *
4  * This file contains Driver Layer Interface implementation for the McBSP Driver.
5  * McBSP Driver provides Driver Layer Interface to do operations on the McBSP
6  * peripheral like device initialization, channel creation, control commands for
7  * peripheral specific operations etc. It uses EDMA3 for data transfer.
8  *
9  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
10  *
11  *
12  *  Redistribution and use in source and binary forms, with or without
13  *  modification, are permitted provided that the following conditions
14  *  are met:
15  *
16  *    Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  *
19  *    Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the
22  *    distribution.
23  *
24  *    Neither the name of Texas Instruments Incorporated nor the names of
25  *    its contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40 */
42 /*============================================================================*/
43 /*                              INCLUDE FILES                                 */
44 /*============================================================================*/
46 /* MCBSP Types and OSAL definitions: These files can be override by customers
47  * to point to their copies. Because of this the files have not been explicitly 
48  * specified to include the driver path.*/
49 #include <mcbsp_types.h>
50 #include <mcbsp_osal.h>
52 /* MCBSP Driver Includes */
53 #include <ti/drv/mcbsp/mcbsp_drv.h>
54 #include <ti/drv/mcbsp/include/mcbsp_pvt.h>
57 /* ========================================================================== */
58 /*                       GLOBAL MODULE STATE                                  */
59 /* ========================================================================== */
61 /**
62  * \brief  Array of Mcbsp instance State objects array
63  */
64 #pragma DATA_SECTION (Mcbsp_Instances, ".mcbsp");
65 #pragma DATA_ALIGN   (Mcbsp_Instances, MCBSP_MAX_CACHE_ALIGN)
66 Mcbsp_Object Mcbsp_Instances[CSL_MCBSP_PER_CNT];
68 /**
69  * \brief  Mcbsp structure containing the information specific to an instance.
70  */
71 /* Shared Memory Variable to ensure synchronizing SRIO initialization
72  * with all the other cores. */
73 /* Created an array to pad the cache line with MCBSP_MAX_CACHE_ALIGN size */
74 #pragma DATA_SECTION (Mcbsp_deviceInstInfo, ".mcbsp");
75 #pragma DATA_ALIGN   (Mcbsp_deviceInstInfo, MCBSP_MAX_CACHE_ALIGN)
76 Mcbsp_HwInfo Mcbsp_deviceInstInfo[CSL_MCBSP_PER_CNT];
78 /**
79  *  \brief  Mute buffer per instance
80  *
81  *  \note   Buffer used when the mcbsp is placed in mute.
82  */
83 #pragma DATA_SECTION (Mcbsp_muteBuf, ".mcbsp");
84 #pragma DATA_ALIGN   (Mcbsp_muteBuf, MCBSP_MAX_CACHE_ALIGN)
85 Mcbsp_TempBuffer Mcbsp_muteBuf[CSL_MCBSP_PER_CNT];
87 #ifdef MCBSP_LOOPJOB_ENABLE
88 /**
89  * \brief  Destination loop buffer per instance
90  *
91  * \note   Buffer used during the loop job mode for the Transmit section
92  */
93 #pragma DATA_SECTION (Mcbsp_loopDstBuf, ".mcbsp");
94 #pragma DATA_ALIGN   (Mcbsp_loopDstBuf, MCBSP_MAX_CACHE_ALIGN)
95 Mcbsp_TempBuffer Mcbsp_loopDstBuf[CSL_MCBSP_PER_CNT];
97 /**
98  * \brief  Receive loop buffer per instance
99  *
100  * \note   Buffer used during the loop job mode for the Receive section
101  */
102 #pragma DATA_SECTION (Mcbsp_loopSrcBuf, ".mcbsp");
103 #pragma DATA_ALIGN   (Mcbsp_loopSrcBuf, MCBSP_MAX_CACHE_ALIGN)
104 Mcbsp_TempBuffer Mcbsp_loopSrcBuf[CSL_MCBSP_PER_CNT];
105 #endif /* MCBSP_LOOPJOB_ENABLE */
107 /*============================================================================*/
108 /*                         LOCAL FUNCTION PROTOTYPES                          */
109 /*============================================================================*/
110 int32_t mcbspSubmitReq(Mcbsp_Object_Unpadded *instHandle,
111                        Mcbsp_ChannelObj  *chanHandle,
112                        Mcbsp_IOBuf       *ioBuf);
113 void mcbspConfigureFifo(Mcbsp_HwInfo_Unpadded *hMcbsp,
114                         Mcbsp_ChannelObj    *chanHandle,
115                         Bool                 enableHwFifo);
117 #ifndef MCBSP_LOOPJOB_ENABLE
118 extern uint32_t Mcbsp_edmaChanNum;
119 #endif /* MCBSP_LOOPJOB_ENABLE */
122 /* ========================================================================== */
123 /*                    MODULE PUBLIC FUNCTIONS                                 */
124 /* ========================================================================== */
126 /**
127  *  @b Description
128  *  @n  
129  *      This is the MCBSP Driver Initialization API which needs to be 
130  *      invoked by the users to initialize the MCBSP peripheral. This call
131  *      is *mandatory* and should be called before calling any of the 
132  *      other driver API's. 
133  *
134  *      This should only be called *ONCE* for the device.
135  *
136  *  @retval
137  *      MCBSP_STATUS_COMPLETED     if successful 
138  *  @retval
139  *      MCBSP_ERR_BADARGS          if not successful
140  *      MCBSP_ERR_ALLOC
141  */
142 int32_t mcbspInit (void)
144     int32_t devId = 0;
145     void *criticalSectionInfo;
147     /* Begin Critical Section before accessing shared resources. */
148     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
150     /* Invalidate the Cache Contents */
151     Mcbsp_osalBeginMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
153     /* initialize the information for all the device instances                */
154     for (devId = 0; devId < CSL_MCBSP_PER_CNT; devId++)
155     {
156         /* initialise the instance object                                     */
157         memset((void *)&Mcbsp_Instances[devId], 0, sizeof(Mcbsp_Object));
158         Mcbsp_Instances[devId].obj.inUse = FALSE;
159     }
161     /* Writeback Global Object */
162     Mcbsp_osalEndMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
164     /* End Critical Section */
165     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
167     return MCBSP_STATUS_COMPLETED;
170 /**
171  * \brief   Allocates and configures the McBSP instance specified by devid.
172  *
173  *  Acquires the Handle of the McBSP and configure the McBSP by
174  *  default for the following things.
175  *      o   Data output for audio playback
176  *      o   Data input for audio recording
177  *      o   Configure the McBSP in DSP/TDM data format mode of the audio
178  *          codec.
179  *      o   Configure the McBSP to receive the Frame Sync and bit clock
180  *          externally for both receiver and transmitter.
181  *      o   McBSP can also be configured to generate Frame Sync and
182  *          bit clock internally by enabling sample rate generator and
183  *          frame sync generator blocks respectively depending on the
184  *          fields set in the device parameter structure which shall
185  *          be passed to mcbspBindDev() function as one of the parameter.
186  *
187  * \param   devp         [OUT]  pointer to hold allocated instance object ptr
188  * \param   devid        [IN]   instance number of the mcbsp
189  * \param   devParams    [IN]   user supplied data params.
190  *
191  * \return  MCBSP_STATUS_COMPLETED     if successful
192  *
193  *          MCBSP_ERR_BADARGS          if not successful
194  *          MCBSP_ERR_ALLOC
195  *
196  * \enter   devp        should be non NULL and valid pointer,
197  *          devId       should be < CSL_MCBSP_PER_CNT
198  *          devParams   should be non NULL and valid pointer,
199  *
200  * \leave   Not implemented
201  */
202 int32_t mcbspBindDev(void* *devp, int32_t devid, void* devParams)
204     Mcbsp_Object_Unpadded *instHandle = NULL;
205     Mcbsp_Params *params     = NULL;
206     uint32_t      ctrlMask   = 0x00;
207     uint32_t      count      = 0x00;
208     int32_t       status     = MCBSP_STATUS_COMPLETED;
209     void         *criticalSectionInfo;
211     /* Begin Critical Section before accessing shared resources. */
212     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
214     /* Invalidate the Cache Contents */
215     Mcbsp_osalBeginMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
216     Mcbsp_osalBeginMemAccess ((void *)Mcbsp_deviceInstInfo, sizeof(Mcbsp_deviceInstInfo));
218 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
219     if ((NULL == devp) || (NULL == devParams) || (devid >= CSL_MCBSP_PER_CNT))
220     {
221         status = MCBSP_ERR_BADARGS;
222     }
224     if (MCBSP_STATUS_COMPLETED == status)
225     {
226         if (TRUE == Mcbsp_Instances[devid].obj.inUse)
227         {
228             status = MCBSP_ERR_INUSE;
229         }
230         else
231         {
232 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
233             /* copy the pointer to the instance object                        */
234             instHandle = &(Mcbsp_Instances[devid].obj);
236             /* set the module state as in use                                 */
237             Mcbsp_Instances[devid].obj.inUse = TRUE;
239             params = (Mcbsp_Params *)devParams;
241 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
242             /* Only DMA mode of the operation is supported for Mcbsp mode     */
243             if ((Mcbsp_DevMode_McBSP == params->mode) &&
244                 (Mcbsp_OpMode_DMAINTERRUPT != params->opMode))
245             {
246                 status = MCBSP_ERR_BADMODE;
247             }
248             else
249             {
250                 if (NULL == params->srgSetup)
251                 {
252                     status = MCBSP_ERR_BADMODE;
253                 }
254             }
255         }
256     }
257 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
259     if (MCBSP_STATUS_COMPLETED == status)
260     {
261         /* update the instance of the device being created                    */
262         instHandle->instNum = devid;
264         /* update the user supplied params to the instance object             */
265         instHandle->mode = params->mode;
266         instHandle->opMode = params->opMode;
267         instHandle->enablecache = params->enablecache;
269         /* copy the SOC related information in to the instance object         */
270         instHandle->hwInfo = Mcbsp_deviceInstInfo[devid].obj;
272         /* stop the state machine of RX and TX                                */
273         instHandle->stopSmFsXmt = TRUE;
274         instHandle->stopSmFsRcv = TRUE;
276         instHandle->retryCount = Mcbsp_POLLED_RETRYCOUNT;
278         /* configure the default values for the transmit channel              */
279         instHandle->xmtObj.mode = (uint16_t)MCBSP_MODE_OUTPUT;
280         instHandle->xmtObj.devHandle = NULL;
281         instHandle->xmtObj.cbFxn   = NULL;
282         instHandle->xmtObj.cbArg   = NULL;
283         instHandle->xmtObj.edmaHandle = NULL;
284         instHandle->xmtObj.edmaEventQue = Mcbsp_TXEVENTQUE;
285         instHandle->xmtObj.edmaCallback = NULL;
286         instHandle->xmtObj.xferChan = 0x00;
287         instHandle->xmtObj.tcc = 0x00;
288         instHandle->xmtObj.tempIOBuf = NULL;
289         instHandle->xmtObj.submitCount = 0x00;
290         instHandle->xmtObj.dataFormat = Mcbsp_BufferFormat_1SLOT;
291         instHandle->xmtObj.bMuteON = FALSE;
292         instHandle->xmtObj.paused = FALSE;
293         instHandle->xmtObj.flush = FALSE;
294         instHandle->xmtObj.isTempIOBufValid = FALSE;
295         instHandle->xmtObj.enableHwFifo = TRUE;
296         instHandle->xmtObj.gblErrCbk = NULL;
297         instHandle->xmtObj.userDataBufferSize = 0x00;
298         instHandle->xmtObj.loopJobBuffer = NULL;
299         instHandle->xmtObj.loopJobLength = 0x00;
300         instHandle->xmtObj.nextLinkParamSetToBeUpdated = 0x00;
301         instHandle->xmtObj.loopjobUpdatedinParamset = FALSE;
302         instHandle->xmtObj.roundedWordWidth = 0x00;
304         instHandle->rcvObj.mode = (uint16_t)MCBSP_MODE_INPUT;
305         instHandle->rcvObj.devHandle = NULL;
306         instHandle->rcvObj.cbFxn   = NULL;
307         instHandle->rcvObj.cbArg   = NULL;
308         instHandle->rcvObj.edmaHandle = NULL;
309         instHandle->rcvObj.edmaEventQue = Mcbsp_RXEVENTQUE;
310         instHandle->rcvObj.edmaCallback = NULL;
311         instHandle->rcvObj.xferChan = 0x00;
312         instHandle->rcvObj.tcc = 0x00;
313         instHandle->rcvObj.tempIOBuf = NULL;
314         instHandle->rcvObj.submitCount = 0x00;
315         instHandle->rcvObj.dataFormat = Mcbsp_BufferFormat_1SLOT;
316         instHandle->rcvObj.bMuteON = FALSE;
317         instHandle->rcvObj.paused = FALSE;
318         instHandle->rcvObj.flush = FALSE;
319         instHandle->rcvObj.isTempIOBufValid = FALSE;
320         instHandle->rcvObj.enableHwFifo = TRUE;
321         instHandle->rcvObj.gblErrCbk = NULL;
322         instHandle->rcvObj.userDataBufferSize = 0x00;
323         instHandle->rcvObj.loopJobBuffer = NULL;
324         instHandle->rcvObj.loopJobLength = 0x00;
325         instHandle->rcvObj.nextLinkParamSetToBeUpdated = 0x00;
326         instHandle->rcvObj.loopjobUpdatedinParamset = FALSE;
327         instHandle->rcvObj.roundedWordWidth = 0x00;
329 #ifdef MCBSP_LOOPJOB_ENABLE
330         /* driver is compiled in loop Job mode                                */
331         instHandle->loopJobMode = TRUE;
332 #else
333         instHandle->loopJobMode = FALSE;
334 #endif
336         for (count = 0; count < Mcbsp_MAXLINKCNT; count++)
337         {
338             instHandle->xmtObj.pramTbl[count] = 0x00;
339             instHandle->rcvObj.pramTbl[count] = 0x00;
340             instHandle->xmtObj.pramTblAddr[count] = 0x00;
341             instHandle->rcvObj.pramTblAddr[count] = 0x00;
342         }
344         /* set the status of the channel to closed                            */
345         instHandle->xmtObj.chanState = Mcbsp_DriverState_CLOSED;
346         instHandle->rcvObj.chanState = Mcbsp_DriverState_CLOSED;
348         /* Pending and Floating queues for TX and RX channels */
349         instHandle->xmtObj.ptrQPendList  = params->txQPendingList;
350         instHandle->xmtObj.ptrQFloatList = params->txQFloatingList;
351         instHandle->rcvObj.ptrQPendList  = params->rxQPendingList;
352         instHandle->rcvObj.ptrQFloatList = params->rxQFloatingList;
354         if (MCBSP_STATUS_COMPLETED == status)
355         {
356             /* Reset the McBSP Transmitter, receiver and SRGR before          *
357              * configuration                                                  */
358             ctrlMask = ((Mcbsp_SpcrCtrl_TX_DISABLE | 
359                          Mcbsp_SpcrCtrl_RX_DISABLE) |
360                        (Mcbsp_SpcrCtrl_SRG_DISABLE | 
361                         Mcbsp_SpcrCtrl_FSYNC_DISABLE));
363             status = Mcbsp_localResetCtrl(instHandle,ctrlMask);
364             if (MCBSP_STATUS_COMPLETED != status)
365             {
366                 /* Writeback Global Object */
367                 Mcbsp_osalEndMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
368                 Mcbsp_osalEndMemAccess ((void *)Mcbsp_deviceInstInfo, sizeof(Mcbsp_deviceInstInfo));
370                 /* End Critical Section */
371                 Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
373                 return status;
374             }
376             /* copy the configuration for the sample rate generator and config*
377              * the emulation mode and DLB mode settings                       */
379             /* Configure the McBSP with user supplied parameters              */
380             instHandle->srgrConfig = *(params->srgSetup);
382             /* reset the Mcbsp                                                */
383             instHandle->hwInfo.regs->SPCR = 0x00u;
385             /* set the DLB mode settings                                      */
386             instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_DLB_MASK);
387             instHandle->hwInfo.regs->SPCR |=
388                 (params->dlbMode << CSL_MCBSP_SPCR_DLB_SHIFT);
390             /* set the clock stop mode settings                               */
391             instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_CLKSTP_MASK);
393             /* set the emulation state                                        */
394             instHandle->hwInfo.regs->SPCR &= (~(CSL_MCBSP_SPCR_SOFT_MASK |
395                                                 CSL_MCBSP_SPCR_FREE_MASK));
396             instHandle->hwInfo.regs->SPCR |=
397                 (params->emulationMode << CSL_MCBSP_SPCR_SOFT_SHIFT);
398         }
400         if (MCBSP_STATUS_COMPLETED != status)
401         {
402             *devp = NULL;
403         }
404         else
405         {
406             *devp = &(Mcbsp_Instances[devid]);
408             /* set the status of the driver to created                        */
409             instHandle->devState = Mcbsp_DriverState_CREATED;
410         }
411     }
413     /* Writeback Global Object */
414     Mcbsp_osalEndMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
415     Mcbsp_osalEndMemAccess ((void *)Mcbsp_deviceInstInfo, sizeof(Mcbsp_deviceInstInfo));
417     /* End Critical Section */
418     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
420     return status;
423 /**
424  *  \brief  Creates a communication channel in specified mode to communicate
425  *          data between the application and the McBSP device instance. This
426  *          function sets the required hardware configurations for the data
427  *          transactions. It returns configured channel handle to application
428  *          which will be used in all further transactions with the channel.
429  *
430  *          Pre-requisites:
431  *          1.  Valid chanParams structure
432  *              This takes much information pertaining to mcbsp channel
433  *              configuration such as how many slots are used for this
434  *              channel what are their communication parameters, clock settings etc.
435  *          2.  Valid device pointer
436  *
437  * \param   chanp        [IN]     Channel Handler
438  * \param   devp         [IN]     Device pointer
439  * \param   mode         [IN]     channel  mode -> input or output
440  * \param   chanParams   [IN]     channel parameters from user
441  * \param   cbFxn        [IN]     callback function pointer
442  * \param   cbArg        [IN]     callback function Arguments
443  *
444  * \return  MCBSP_STATUS_COMPLETED     if successful
445  *          MCBSP_ERR_BADIO        if not successful
446  *          MCBSP_ERR_ALLOC            "
447  *          MCBSP_ERR_BADARGS      if passed invalid chanParams structure
448  */
449 int32_t mcbspCreateChan(void*            *chanp,
450                        void*              devp,
451                        int32_t            mode,
452                        void*              chanParams,
453                        Mcbsp_CallbackFxn  cbFxn,
454                        void*              cbArg)
456     Mcbsp_Object *hInst = NULL;
457     Mcbsp_Object_Unpadded *instHandle = NULL;
458     Mcbsp_ChannelObj    *chanHandle = NULL;
459     Mcbsp_ChanParams    *chanparam  = NULL;
460     void*                criticalSectionInfo;
461     int32_t              status     = MCBSP_STATUS_COMPLETED;
463 /* Begin parameter checking                                                   */
464 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
465     if (((NULL == chanParams)
466         || (NULL == cbFxn)
467         || (NULL == cbArg)
468         || (NULL == devp))
469         || ((MCBSP_MODE_INPUT != mode) && (MCBSP_MODE_OUTPUT != mode)))
470     {
471         return MCBSP_ERR_BADARGS;
472     }
473     else
474     {
475 #endif
476         chanparam = (Mcbsp_ChanParams *)chanParams;
477 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
478         if (NULL == chanparam->edmaHandle)
479         {
480             return MCBSP_ERR_BADARGS;
481         }
482     }
483 #endif  /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
484 /* End parameter checking                                                     */
486     /* Begin Critical Section before accessing shared resources. */
487     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
489     /* Invalidate the Cache Contents */
490     Mcbsp_osalBeginMemAccess ((void *)devp, sizeof(Mcbsp_Object));
492     if (MCBSP_STATUS_COMPLETED == status)
493     {
494         hInst = (Mcbsp_Object *)devp;
495         instHandle = (Mcbsp_Object_Unpadded *)&(hInst->obj);
497         /* get the pointer to the required channel structure              */
498         if (MCBSP_MODE_INPUT == mode)
499         {
500             chanHandle = &instHandle->rcvObj;
501         }
502         else
503         {
504             chanHandle = &instHandle->xmtObj;
505         }
507         /* we will check if the current requested channel is availablehere*
508          * protect the channel status so that multiple threads requesting *
509          * same channel do not cause a corruption                         */
510         if (Mcbsp_DriverState_CLOSED == chanHandle->chanState)
511         {
512             chanHandle->chanState = Mcbsp_DriverState_OPENED;
513         }
514         else
515         {
516             /* Requested channel is already taken hence we will set status*
517              * as invalid                                                 */
518             status = MCBSP_ERR_BADMODE;
519         }
521         if (MCBSP_STATUS_COMPLETED == status)
522         {
523             chanHandle->mode = (uint16_t)mode;
524             chanHandle->devHandle = hInst;
526             /* Assign the respective callback function                        */
527             chanHandle->cbFxn = cbFxn;
528             chanHandle->cbArg = cbArg;
530             /* This is used in EDMA mode to populate paramsets in PINGPONG    */
531             chanHandle->nextLinkParamSetToBeUpdated = 0;
533             /* Initialize Mute parameter                                      */
534             chanHandle->bMuteON = FALSE;
536             chanHandle->isTempIOBufValid = FALSE;
538             /* Counter that counts outstanding requests of this channel       */
539             chanHandle->submitCount = 0;
541             /* Global error callback registered to channel                    */
542             chanHandle->gblErrCbk = chanparam->gblCbk;
544             /* copy the edma event queue details                              */
545             chanHandle->edmaEventQue = chanparam->edmaEventQue;
547             /* store the EDMA3 module handle                                  */
548             chanHandle->edmaHandle = chanparam->edmaHandle;
550             /* configure the FIFO                                             */
551             chanHandle->enableHwFifo = chanparam->enableHwFifo;
553             /* copy the user settings in to the channel object                */
554             chanHandle->chanConfig = *(chanparam->chanConfig);
555             chanHandle->clkSetup   = *(chanparam->clkSetup);
556             chanHandle->numEnabledChannels = chanparam->numEnabledChannels;
557             chanHandle->dataFormat = chanparam->dataFormat;
558         }
560         if (MCBSP_STATUS_COMPLETED == status)
561         {
562             /* configure the actual wordwidth to be used                      */
563             switch (chanparam->wordWidth)
564             {
565                 case Mcbsp_WordLength_8:
566                     chanHandle->roundedWordWidth = 1u;
567                     break;
568                 case Mcbsp_WordLength_12:
569                 case Mcbsp_WordLength_16:
570                     chanHandle->roundedWordWidth = 2u;
571                     break;
572                 case Mcbsp_WordLength_20:
573                 case Mcbsp_WordLength_24:
574                     chanHandle->roundedWordWidth = 3u;
575                     break;
576                 case Mcbsp_WordLength_32:
577                 default:
578                     chanHandle->roundedWordWidth = 4u;
579                     break;
580             }
582 #ifdef  MCBSP_LOOPJOB_ENABLE
583             /* Configure the loop job for the user specified buffer if given  */
584             if (NULL == chanparam->userLoopJobBuffer)
585             {
586                 if (MCBSP_MODE_INPUT == chanHandle->mode)
587                 {
588                     chanHandle->loopJobBuffer =
589                         Mcbsp_loopDstBuf[instHandle->instNum].scratchBuffer;
590                 }
591                 else
592                 {
593                     chanHandle->loopJobBuffer =
594                         Mcbsp_loopSrcBuf[instHandle->instNum].scratchBuffer;
595                 }
596                 chanHandle->loopJobLength = chanHandle->roundedWordWidth;
597             }
598             else
599             {
600                 /* Apps has preference on the loopjob buffer & lets use it    */
601                 chanHandle->loopJobBuffer = chanparam->userLoopJobBuffer;
602                 chanHandle->userLoopJobLength = chanparam->userLoopJobLength;
604                 /* user loopJob is being used                                 */
605                 chanHandle->userLoopJob = TRUE;
606                 if (chanHandle->roundedWordWidth >
607                         chanparam->userLoopJobLength)
608                 {
609                     /* not enough loopjob buffer has been provided  we        *
610                      * should have at least loopbuffer for 1 sync event       */
611                     status = MCBSP_ERR_BADARGS;
612                 }
613             }
614 #endif
615         }
617         if ((Mcbsp_DevMode_McBSP == instHandle->mode) && (MCBSP_STATUS_COMPLETED == status))
618         {
619             if (MCBSP_MODE_INPUT == chanHandle->mode)
620             {
621                 /* Assign the Channel ID and TCC                              */
622                 chanHandle->xferChan     = instHandle->hwInfo.edmaRxEventNum;
623                 chanHandle->tcc          = instHandle->hwInfo.edmaRxEventNum;
624                 chanHandle->edmaCallback =
625                     (EDMA3_RM_TccCallback)&Mcbsp_localEdmaCallback;
626             }
627             else
628             {
629                 /* Assign the Channel ID and TCC                              */
630                 chanHandle->xferChan     = instHandle->hwInfo.edmaTxEventNum;
631                 chanHandle->tcc          = instHandle->hwInfo.edmaTxEventNum;
632                 chanHandle->edmaCallback =
633                     (EDMA3_RM_TccCallback)&Mcbsp_localEdmaCallback;
634             }
636             if (MCBSP_STATUS_COMPLETED == status)
637             {
638                 mcbspConfigureFifo(&(instHandle->hwInfo),
639                     chanHandle,
640                     chanHandle->enableHwFifo);
641             }
643             if (MCBSP_MODE_INPUT == chanHandle->mode)
644             {
645                 /* configure the RX section                                   */
646                 status = Mcbsp_localConfigureRcvChannel(instHandle,chanparam);
647             }
648             else
649             {
650                 /* configure the TX section                                   */
651                 status = Mcbsp_localConfigureXmtChannel(instHandle,chanparam);
652             }
654             if (MCBSP_STATUS_COMPLETED == status)
655             {
656                 /* configure the sample rate generator                        */
657                 status = Mcbsp_localConfigureSrgr(instHandle,chanHandle);
658             }
659             
660             if (MCBSP_STATUS_COMPLETED == status)
661             {
662                 /* enable the internal sample rate generator if required      */
663                 if (((MCBSP_MODE_INPUT == chanHandle->mode) &&
664                     (TRUE == instHandle->rxSrgEnable)) ||
665                     ((MCBSP_MODE_OUTPUT == chanHandle->mode) &&
666                     (TRUE == instHandle->txSrgEnable)))
667                 {
668                     /* enable the sample rate generator                       */
669                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_SRG_ENABLE);
670                     instHandle->srgEnabled = TRUE;
672                     /* wait for the 2CLKG clock cycles                        */
673                     Mcbsp_osalWaitNBitClocks(2u);
674                 }
675             
676                 /* clear the XSYNCERR (to be done only if TX is used)         */
677                 if (MCBSP_MODE_OUTPUT == chanHandle->mode)
678                 {
679                     /* Enable the TX section                                  */
680                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
682                     /* wait for 2 CLKR or CLX cycles                          */
683                     Mcbsp_osalWaitNBitClocks(2u);
685                     /* Disable the TX section to clear any XYNCERR            */
686                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_DISABLE);
687                 }
689                 /* complete the EDMA setup for the driver                     */
690                 status =  Mcbsp_localSetupEdmaDuringOpen(chanHandle);
691             }
693 #ifdef MCBSP_LOOPJOB_ENABLE
694             if (MCBSP_STATUS_COMPLETED == status)
695             {
696                                         /* configure the FIFO for the specific channel                        */
697                 if (TRUE == chanHandle->enableHwFifo)
698                 {
699                     /* Disable and enable the FIFO so that the events are             *
700                      * generated to the Mcbsp for the first time                      */
701                     mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,FALSE);
702                     mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,TRUE);
703                 }
705                 /* enable the EDMA transfer for the channel so that it is     *
706                  * ready to transfer the data as soon as the state machine is *
707                  * enabled                                                    */
708                 EDMA3_DRV_enableTransfer(
709                     chanHandle->edmaHandle,
710                     chanHandle->xferChan,
711                     EDMA3_DRV_TRIG_MODE_EVENT);
713                 /* Start the McBSP hardware                                   */
714                 if (MCBSP_MODE_INPUT == chanHandle->mode)
715                 {
716                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_ENABLE);
717                 }
718                 else
719                 {
720                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
721                 }
723                 if (MCBSP_MODE_INPUT == chanHandle->mode)
724                 {
725                     if (TRUE == instHandle->rxFsgEnable)
726                     {
727                         /* enable the sample rate generator                   */
728                         Mcbsp_localResetCtrl(
729                             instHandle,
730                             Mcbsp_SpcrCtrl_FSYNC_ENABLE);
731                     }
732                 }
733                 else
734                 {
735                     if (TRUE == instHandle->txFsgEnable)
736                     {
737                         /* enable the sample rate generator                   */
738                         Mcbsp_localResetCtrl(
739                             instHandle,
740                             Mcbsp_SpcrCtrl_FSYNC_ENABLE);
741                     }
742                 }
744                 /* State machine stop status                                  */
745                 if (MCBSP_MODE_INPUT == chanHandle->mode)
746                 {
747                     instHandle->stopSmFsRcv = FALSE;
748                 }
749                 else
750                 {
751                     instHandle->stopSmFsXmt = FALSE;
752                 }
753             }
754 #endif
755         }
756     }
758     if (MCBSP_STATUS_COMPLETED != status )
759     {
760         if (NULL != chanHandle)
761         {
762             /* set the status of the channel to closed                        */
763             chanHandle->mode = (uint16_t)Mcbsp_DriverState_CLOSED;
764         }
766         /* channel opening for transaction has failed                         */
767         chanHandle = NULL;
768     }
769     else
770     {
771         *chanp = chanHandle;
772     }
774     /* Writeback Global Object */
775     Mcbsp_osalEndMemAccess ((void *)devp, sizeof(Mcbsp_Object));
777     /* End Critical Section */
778     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
780     return status;
783 /**
784  * \brief   frees a channel and all it's associated resources.
785  *
786  *          Frees the EDMA resources including EDMA master channel and link
787  *          PaRAM entries held by the channel.it also unregisters all the
788  *          interrupt handlers.
789  *
790  * \param   chanp  [IN]       Handle to the channel
791  *
792  * \return  MCBSP_STATUS_COMPLETED     if successful
793  *          MCBSP_STATUS_ABORTED       if not successful
794  *
795  * \enter   chanp       should be non NULL and valid pointer,
796  *
797  * \leave   Not implemented
798  */
799 int32_t mcbspDeleteChan(void* chanp)
801     Mcbsp_Object_Unpadded *instHandle = NULL;
802     Mcbsp_ChannelObj *chanHandle = NULL;
803     Uint8    linkCnt = 0;
804     uint32_t timeOut = 0x00;
805     int32_t  status  = MCBSP_STATUS_COMPLETED;
806     void *criticalSectionInfo;
808     /* Begin Critical Section before accessing shared resources. */
809     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
811 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
812     if (NULL == chanp)
813     {
814         status = MCBSP_ERR_BADARGS;
815     }
816     else
817     {
818 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
819         chanHandle = (Mcbsp_ChannelObj *)chanp;
821         /* Invalidate the Cache Contents */
822         Mcbsp_osalBeginMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
824 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
825         if (Mcbsp_DriverState_OPENED != chanHandle->chanState)
826         {
827             status = MCBSP_ERR_BADMODE;
828         }
829         else
830         {
831             if (NULL == chanHandle->devHandle)
832             {
833                 status = MCBSP_ERR_BADARGS;
834             }
835             else
836             {
837 #endif
838                 instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
840 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
841                 if (NULL == instHandle)
842                 {
843                     status = MCBSP_ERR_BADARGS;
844                 }
845             }
846         }
847     }
848 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
850     if (MCBSP_STATUS_COMPLETED == status)
851     {
852         /* reset the channel              .                               */
853         Mcbsp_localAbortReset(chanHandle);
855         /* Disable the current transfer to make sure that there is no     *
856          * running EDMA transfer taking place                             */
857         status = EDMA3_DRV_disableTransfer(
858                      chanHandle->edmaHandle,
859                      chanHandle->xferChan,
860                      EDMA3_DRV_TRIG_MODE_EVENT);
862         /* Disable current EDMA transfer                                  */
863         if (MCBSP_STATUS_COMPLETED == status)
864         {
865             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
866             {
867                 timeOut = instHandle->retryCount;
869                 /* Poll for TXEMPTY                                       */
870                 while ((CSL_MCBSP_SPCR_XEMPTY_MASK ==
871                     (CSL_MCBSP_SPCR_XEMPTY_MASK & instHandle->hwInfo.regs->SPCR))
872                     && (0 != timeOut))
873                 {
874                     timeOut--;
875                 }
876             }
878             /* Reset McBSP before freeing the edma channels               */
879             if (MCBSP_MODE_INPUT == chanHandle->mode)
880             {
881                 Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_DISABLE);
882             }
883             else
884             {
885                 Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_DISABLE);
886             }
888             /* Free Edma channels                                         */
889             status = EDMA3_DRV_freeChannel(
890                          chanHandle->edmaHandle,
891                          chanHandle->xferChan);
892 #ifndef MCBSP_LOOPJOB_ENABLE
894             /* free the already allocated dummy PaRAM entries         */
895             EDMA3_DRV_freeChannel(chanHandle->edmaHandle,
896                           Mcbsp_edmaChanNum);
897 #endif
898                          
899             if (MCBSP_STATUS_COMPLETED ==  status)
900             {
901                 /* free the EDMA PaRAM entries used for Ping pong buffer  */
902                 for (linkCnt = 0; linkCnt < Mcbsp_MAXLINKCNT; linkCnt++)
903                 {
904                     status = EDMA3_DRV_freeChannel(
905                                  chanHandle->edmaHandle,
906                                  chanHandle->pramTbl[linkCnt]);
907                     if (MCBSP_STATUS_COMPLETED != status)
908                     {
909                         break;
910                     }
911                 }
912             }
914             if (MCBSP_STATUS_COMPLETED == status)
915             {
916                 /* Set the state of the channel as closed                 */
917                 chanHandle->chanState = Mcbsp_DriverState_CLOSED;
919                 /* Set the Muted state to FALSE                           */
920                 chanHandle->bMuteON   = FALSE;
922                 /* Set the Paused state to FALSE                          */
923                 chanHandle->paused    = FALSE;
924             }
925         }
927         /* Writeback Global Object */
928         Mcbsp_osalEndMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
929     }
931     /* End Critical Section */
932     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
934     return (status);
937 /**
938  * \brief   Closes the McBSP device instance from use.
939  *          This API is called by the application when it no longer requires the
940  *          device instance. Note that all the channels have to be closed for
941  *          the device instance to be deleted sucessfully.
942  *
943  * \param   devp    [IN]  Handle to the device created.
944  *
945  * \return  MCBSP_STATUS_COMPLETED     if successful
946  *          MCBSP_STATUS_ABORTED       if not successful
947  *
948  * \enter   devp       should be non NULL and valid pointer,
949  *
950  * \leave   Not implemented
951  */
952 int32_t mcbspUnBindDev(void* devp)
954     Mcbsp_Object *hInst = NULL;
955     Mcbsp_Object_Unpadded *instHandle = NULL;
956     int32_t status = MCBSP_STATUS_COMPLETED;
957     void* criticalSectionInfo;
959     /* Begin Critical Section before accessing shared resources. */
960     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
962 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
963     if (NULL == devp)
964     {
965         status = MCBSP_ERR_BADARGS;
966     }
967     else
968     {
969 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
971         hInst = (Mcbsp_Object *)devp;
973         /* Invalidate the Cache Contents */
974         Mcbsp_osalBeginMemAccess ((void *)hInst, sizeof(Mcbsp_Object));
976         instHandle = (Mcbsp_Object_Unpadded *)&(hInst->obj);
978 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
979         if ((CSL_MCBSP_PER_CNT <= instHandle->instNum)                  ||
980             (Mcbsp_DriverState_CLOSED != instHandle->xmtObj.chanState)  ||
981             (Mcbsp_DriverState_CLOSED != instHandle->rcvObj.chanState))
982         {
983             status = MCBSP_ERR_BADARGS;
984         }
985     }
986 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
988     if (MCBSP_STATUS_COMPLETED == status)
989     {
990         /* reset the Mcbsp                                                */
991         instHandle->hwInfo.regs->SPCR = 0x00u;
993         /* Mark driver state as deleted and module as not in use              */
994         instHandle->devState = Mcbsp_DriverState_DELETED;
995         instHandle->inUse = FALSE;
997         /* update the user params to the instance object                      */
998         instHandle->instNum = -1;
1000         /* Intialize the mcbsp driver to default values                       */
1001         memset(instHandle, 0, sizeof(Mcbsp_Object_Unpadded));
1003         /* Writeback Global Object */
1004         Mcbsp_osalEndMemAccess ((void *)hInst, sizeof(Mcbsp_Object));
1005     }
1007     /* End Critical Section */
1008     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
1010     return status;
1013 /**
1014  * \brief   Submit a I/O buffer to a channel for processing
1015  *
1016  *  The application calls this function to cause the driver
1017  *  to process the Mcbsp_IOBuf for read/write/flush/abort operations.
1018  *
1019  * \param   chanp         [IN]    Pointer to channel
1020  * \param   ioBuf         [IN]    Pointer to buffer to be submitted
1021  *
1022  * \return  MCBSP_STATUS_COMPLETED, if buffer is fully processed
1023  *          MCBSP_STATUS_ABORTED,   if buffer is aborted
1024  *          MCBSP_STATUS_PENDING,   if buffer is not fully processed
1025  *          MCBSP_ERR_BADIO     in case of an error in processing
1026  *
1027  */
1028 int32_t mcbspSubmitChan(void* chanp, Mcbsp_IOBuf *const ioBuf)
1030     Mcbsp_Object_Unpadded *instHandle = NULL;
1031     Mcbsp_ChannelObj      *chanHandle = NULL;
1032     int32_t                status     = MCBSP_STATUS_COMPLETED;
1034 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1035     if ((NULL == chanp) || ( NULL == ioBuf))
1036     {
1037         status = MCBSP_ERR_BADARGS;
1038     }
1039     else
1040     {
1041 #endif
1042         chanHandle = (Mcbsp_ChannelObj *)chanp;
1044 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1046         if ((NULL == chanHandle) || (NULL == chanHandle->devHandle))
1047         {
1048             status = MCBSP_ERR_BADARGS;
1049         }
1050         else
1051         {
1052 #endif
1053             instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1054 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1055             if (NULL == instHandle)
1056             {
1057                 status = MCBSP_ERR_BADARGS;
1058             }
1059             else
1060             {
1061                 if (NULL == ioBuf->addr)
1062                 {
1063                     if ((Mcbsp_IOBuf_Cmd_READ == ioBuf->cmd) ||
1064                         (Mcbsp_IOBuf_Cmd_WRITE == ioBuf->cmd))
1065                     {
1066                         status = MCBSP_ERR_BADARGS;
1067                     }
1068                 }
1069             }
1070         }
1071     }
1072 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
1074     if (MCBSP_STATUS_COMPLETED == status)
1075     {
1076         /* process the command sent by the application                        */
1077         switch (ioBuf->cmd)
1078         {
1079             case Mcbsp_IOBuf_Cmd_READ:
1080             case Mcbsp_IOBuf_Cmd_WRITE:
1081                 if (TRUE != chanHandle->flush)
1082                 {
1083                     status = mcbspSubmitReq(instHandle,chanHandle,ioBuf);
1084                 }
1085                 else
1086                 {
1087                     status = MCBSP_ERR_BADIO;
1088                 }
1089                 break;
1090             case Mcbsp_IOBuf_Cmd_FLUSH:
1091                 /* Flush command has been issued need to abort the receive    *
1092                  * channel buffers and complete the TX buffers normally       */
1093                 chanHandle->flush = TRUE;
1094                 Mcbsp_localAbortReset(chanHandle);
1095                 chanHandle->flush = FALSE;
1096                 break;
1097             case Mcbsp_IOBuf_Cmd_ABORT:
1098                 Mcbsp_localAbortReset(chanHandle);
1099                 break;
1100             default:
1101                 status = MCBSP_ERR_BADIO;
1102                 break;
1103         }
1104     }
1106     return status;
1109 /**
1110  * \brief   Implements the IOCTLS for McBSP driver.
1111  *
1112  *          ControlChan() implements recieved IOCTL commands from the
1113  *          application and executes them accordingly.
1114  *
1115  * \param   chanp  [IN]    Pointer to channel
1116  * \param   cmd    [IN]    specific IOCTL command
1117  * \param   arg    [IN]    arguments required for specific commands
1118  *
1119  * \return  MCBSP_STATUS_COMPLETED, if command is executed correctly
1120  *          MCBSP_STATUS_ABORTED,   if command returns error during execution
1121  *          MCBSP_ERR_NOTIMPL,  if command is not supported
1122  *          MCBSP_ERR_BADARGS   if args are not correct
1123  */
1124 int32_t mcbspControlChan(void* chanp, Mcbsp_IOCTL cmd, void* arg)
1126     Mcbsp_ChannelObj *chanHandle = NULL;
1127     int32_t status = MCBSP_STATUS_COMPLETED;
1129 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1130     if (NULL == chanp)
1131     {
1132         status = MCBSP_ERR_BADARGS;
1133     }
1134     else
1135     {
1136 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
1138         chanHandle = (Mcbsp_ChannelObj *)chanp;
1140         /* Invalidate the Cache Contents */
1141         Mcbsp_osalBeginMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
1143 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1144         if (NULL == chanHandle->devHandle)
1145         {
1146             status = MCBSP_ERR_BADARGS;
1147         }
1148     }
1149 #endif
1150         
1151     if (MCBSP_STATUS_COMPLETED == status)
1152     {
1153         /* call the function to process the IOCTL command                 */
1154         status =  Mcbsp_localSubmitIoctl(
1155                         chanHandle,
1156                         cmd,
1157                         arg,
1158                         NULL);
1159     }
1161     /* Writeback Global Object */
1162     Mcbsp_osalEndMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
1164     return (status);
1167 /**
1168  * \brief   McBSP Tx ISR function
1169  *
1170  *          This Function is the interrupt service routine for the Mcbsp TX
1171  *          event.
1172  *
1173  * \param   hChan  [IN]  Handle to the channel
1174  *
1175  * \return  None
1176  */
1177 void mcbspGblXmtIsr(void *hChan)
1179     Mcbsp_Object_Unpadded *instHandle = NULL;
1180     Mcbsp_ChannelObj *chanHandle = (Mcbsp_ChannelObj *)hChan;
1182     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1184     /* Only DMA mode of operation is supported by the Mcbsp driver hence we   *
1185      * will only check if there is an sync error and notify the application   */
1186     if (CSL_MCBSP_SPCR_XSYNCERR_MASK ==
1187         (CSL_MCBSP_SPCR_XSYNCERR_MASK & instHandle->hwInfo.regs->SPCR))
1188     {
1189         /* call the application registered global callback function           */
1190         if (NULL != chanHandle->gblErrCbk)
1191         {
1192             (*chanHandle->gblErrCbk)((uint32_t)chanHandle,
1193                 instHandle->hwInfo.regs->SPCR,
1194                 NULL);
1195         }
1196     }
1198     return;
1201 /**
1202  * \brief   McBSP Rx ISR function
1203  *
1204  *          This Function is the interrupt service routine for the Mcbsp RX
1205  *          event.
1206  *
1207  * \param   hChan  [IN]  Handle to the channel
1208  *
1209  * \return  None
1210  */
1211 void mcbspGblRcvIsr(void *hChan)
1213     Mcbsp_Object_Unpadded *instHandle = NULL;
1214     Mcbsp_ChannelObj *chanHandle = (Mcbsp_ChannelObj *)hChan;
1216     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1218     /* Only DMA mode of operation is supported by the Mcbsp driver hence we   *
1219      * will only check if there is an sync error and notify the application   */
1220     if (CSL_MCBSP_SPCR_RSYNCERR_MASK ==
1221         (CSL_MCBSP_SPCR_RSYNCERR_MASK & instHandle->hwInfo.regs->SPCR))
1222     {
1223         /* call the application registered global callback function           */
1224         if (NULL != chanHandle->gblErrCbk)
1225         {
1226             (*chanHandle->gblErrCbk)((uint32_t)chanHandle,
1227                 instHandle->hwInfo.regs->SPCR,
1228                 NULL);
1229         }
1230     }
1232     return;
1235 /*============================================================================*/
1236 /*                          LOCAL FUNCTION DEFINTIONS                         */
1237 /*============================================================================*/
1239 /**
1240  *  \brief   Submit a I/O buffer to a channel for processing
1241  *
1242  *   This function is called with the Mcbsp_IOBuf_Cmd_READ or Mcbsp_IOBuf_Cmd_WRITE  
1243  *   command to process the IOP. The function handles the MCBSP mode. In case
1244  *   that the driver is currently idle it sets up buffer for transfer. In case
1245  *   that the driver is currently processing a buffer then it will queue up the
1246  *   current buffer and exit.
1247  *
1248  * \param   instHandle  [IN]  pointer to the instance object
1249  * \param   chanHandle  [IN] handle to the channel
1250  * \param   ioBuf       [IN] pointer to Mcbsp I/O buffer.
1251  *
1252  * \return  MCBSP_STATUS_PENDING in case the buffer is sucesfully processed
1253  *          MCBSP_ERR_BADIO  in case of any error.
1254  */
1255 int32_t mcbspSubmitReq(Mcbsp_Object_Unpadded *instHandle,
1256                        Mcbsp_ChannelObj *chanHandle,
1257                        Mcbsp_IOBuf      *ioBuf)
1259     void*           criticalSectionInfo;
1260     int32_t         status = MCBSP_STATUS_COMPLETED;
1262     if ((NULL == chanHandle) || (NULL == ioBuf) || (NULL == instHandle))
1263     {
1264         return MCBSP_ERR_BADIO;
1265     }
1266     if((0 == ioBuf->size) || (ioBuf->size > Mcbsp_MAX_IOBUF_SIZE))
1267     {
1268         return MCBSP_ERR_BADIO;
1269     }
1271     /* clean the buffers if the cache operation mode is enabled               */
1272     if (TRUE == instHandle->enablecache)
1273     {
1274         if (MCBSP_MODE_INPUT == chanHandle->mode)
1275         {
1276             /* Invalidate the cache */
1277             Mcbsp_osalBeginMemAccess(ioBuf->addr, ioBuf->size);
1278         }
1279         else
1280         {
1281             /* Writeback the cache */
1282             Mcbsp_osalEndMemAccess(ioBuf->addr, ioBuf->size);
1283         }
1284     }
1286     /*==========================MCBSP MODE ===================================*/
1287     if (Mcbsp_DevMode_McBSP == instHandle->mode)
1288     {
1289         /* We are entering the crictical section because the current active   *
1290          * IOP is being check and it can become NULL at any point. Hence we   *
1291          * will protect this code from the interrupt handler.                 */
1292         criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
1294 #ifdef MCBSP_LOOPJOB_ENABLE
1295         if ((Mcbsp_MAXLINKCNT <= chanHandle->submitCount) ||
1296 #else
1297         /* We now have 3 buffers loaded in the EDMA                           */
1298         if (((Mcbsp_MAXLINKCNT + 1) <= chanHandle->submitCount) ||
1299 #endif
1300             (TRUE == chanHandle->paused))
1301         {
1302             /* There are enough buffers programmed in the EDMA or if the MCBSP*
1303              * is issued a pause command,hence queue buffer in to the pending *
1304              * queue                                                          */
1305             chanHandle->submitCount++;
1307             Mcbsp_osalQueuePut(chanHandle->ptrQPendList,(void*)ioBuf);
1309             /* critical section ends                                          */
1310             Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1311         }
1312         else
1313         {
1314             /* Either one of the paramset or Both the paramsets are free      */
1316             /* increment the submit count                                     */
1317             chanHandle->submitCount++;
1319             Mcbsp_osalQueuePut(chanHandle->ptrQFloatList, (void*)ioBuf);
1321             Mcbsp_localLoadPktToEdma(chanHandle,ioBuf);
1323             /* critical section ends                                          */
1324             Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1326         } /* Pending queue empty or not*/
1327     }
1328     if (MCBSP_STATUS_COMPLETED == status)
1329     {
1330         status = MCBSP_STATUS_PENDING;
1331     }
1332     return (status);
1335 /**
1336  * \brief   McBSP SPCR configuration function
1337  *
1338  *  This Function is used to set/reset specific bit of SPCR as specified in
1339  *  the given mask.
1340  *
1341  * \param   instHandle   [IN]  pointer to the mcbsp instance object.
1342  * \param   selectMask   [IN]  the SPCR control mask
1343  *
1344  * \return  MCBSP_STATUS_COMPLETED     if successful
1345  *
1346  *          MCBSP_ERR_BADARGS          if not successful
1347  */
1348 int32_t Mcbsp_localResetCtrl(Mcbsp_Object_Unpadded *instHandle, uint32_t selectMask)
1350     if ((NULL == instHandle) || (NULL == instHandle->hwInfo.regs))
1351     {
1352         return MCBSP_ERR_BADARGS;
1353     }
1355     /* Configuring SPCR for Frame sync generator enable/disable               */
1356     if (0u != (selectMask & Mcbsp_SpcrCtrl_FSYNC_DISABLE))
1357     {
1358         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_FRST_MASK );
1359     }
1361     if (0 != (selectMask & Mcbsp_SpcrCtrl_RX_DISABLE))
1362     {
1363         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_RRST_MASK );
1364     }
1366     /* start the sample rate generator                                        */
1367     if (0u != (selectMask & Mcbsp_SpcrCtrl_SRG_ENABLE))
1368     {
1369         instHandle->hwInfo.regs->SPCR |=  CSL_MCBSP_SPCR_GRST_MASK;
1370     }
1372     /* Configuring SPCR for Transmit enable/disable                           */
1373     if (0 != (selectMask & Mcbsp_SpcrCtrl_TX_DISABLE))
1374     {
1375         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_XRST_MASK);
1376     }
1378     /* Configuring SPCR for transmit section enable                           */
1379     if (0 != (selectMask & Mcbsp_SpcrCtrl_TX_ENABLE))
1380     {
1381         instHandle->hwInfo.regs->SPCR |= CSL_MCBSP_SPCR_XRST_MASK;
1382     }
1384     /* Configuring SPCR for Receive section enable                            */
1385     if (0 != (selectMask & Mcbsp_SpcrCtrl_RX_ENABLE))
1386     {
1387         instHandle->hwInfo.regs->SPCR |= CSL_MCBSP_SPCR_RRST_MASK ;
1388     }
1390     /* Set the FRST bit to 1 to start the internal frame sync generator       */
1391     if (0u != (selectMask & Mcbsp_SpcrCtrl_FSYNC_ENABLE))
1392     {
1393         instHandle->hwInfo.regs->SPCR |=  CSL_MCBSP_SPCR_FRST_MASK;
1394     }
1396     /* Configuring SPCR for sample rate generator enable/disable              */
1397     if (0u != (selectMask & Mcbsp_SpcrCtrl_SRG_DISABLE))
1398     {
1399         instHandle->hwInfo.regs->SPCR &=  (~CSL_MCBSP_SPCR_GRST_MASK);
1400     }
1402     return MCBSP_STATUS_COMPLETED;
1405 /**
1406  *  \brief   This function completes the current pending request and then
1407  *           invokes the application registered callback.
1408  *
1409  *  \param   chanHandle   [IN]  Handle to the channel
1410  *
1411  *  \return  None
1412  *
1413  *  \enter   chanHandle  is a valid non null pointer
1414  *
1415  *  \leave   Not implemented
1416  */
1417 void Mcbsp_localCompleteCurrentIo(Mcbsp_ChannelObj *chanHandle)
1419     Mcbsp_IOBuf   *ioBuf = NULL;
1421     if (TRUE == chanHandle->isTempIOBufValid)
1422     {
1423         ioBuf = chanHandle->tempIOBuf;
1425         chanHandle->tempIOBuf = NULL;
1426         chanHandle->isTempIOBufValid = FALSE;
1427         /* call the completion callback function registered with us           *
1428          * during channel creation                                            */
1429         if ((NULL != chanHandle->cbFxn) && (NULL != chanHandle->cbArg))
1430         {
1431             /*  Application callback                                          */
1432             (*chanHandle->cbFxn)((void*)chanHandle->cbArg,ioBuf);
1433         }
1434     }
1436     chanHandle->currentError = MCBSP_STATUS_COMPLETED;
1437     chanHandle->userDataBufferSize = 0;
1440 /**
1441  * \brief     This function configures the transmit section of the mcbsp
1442  *            sync properties.
1443  *
1444  * \param     instHandle  [IN] pointer to the instance object.
1445  * \param     params      [IN] User supplied channel parameters
1446  *
1447  * \return    MCBSP_ERR_BADARGS  if configuration fails.
1448  *            MCBSP_STATUS_COMPLETED if configuration is sucessful.
1449  */
1450 int32_t Mcbsp_localConfigureXmtChannel(Mcbsp_Object_Unpadded *instHandle,
1451                                      Mcbsp_ChanParams *params)
1453     uint32_t  tempVal = 0x00;
1454     int32_t   status  = MCBSP_STATUS_COMPLETED;
1456     if ((NULL == instHandle) || (NULL == params))
1457     {
1458         return MCBSP_ERR_BADARGS;
1459     }
1461     /* configure the transmit section                                         */
1462     /* configure the transmit interrupt setting                               */
1463     instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_XINTM_MASK);
1464     instHandle->hwInfo.regs->SPCR |=
1465         (params->chanConfig->intMode << CSL_MCBSP_SPCR_XINTM_SHIFT);
1467         /* configure the DX enabler */
1468         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_DXENA_MASK);
1469         instHandle->hwInfo.regs->SPCR |=
1470         (params->chanConfig->dxState << CSL_MCBSP_SPCR_DXENA_SHIFT);
1472     /* configure the transmit control register settings                       */
1473     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XPHASE_MASK);
1474     instHandle->hwInfo.regs->XCR |=
1475         (params->chanConfig->phaseNum << CSL_MCBSP_XCR_XPHASE_SHIFT);
1477     /* configure the frame length for single and dual phase frames            */
1478     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XFRLEN1_MASK);
1479     instHandle->hwInfo.regs->XCR |=
1480         ((params->chanConfig->frmLen1 - 1u) << CSL_MCBSP_XCR_XFRLEN1_SHIFT);
1482     /* configure the word length of the single and dual phase frames          */
1483     switch (params->chanConfig->wrdLen1)
1484     {
1485         case Mcbsp_WordLength_8:
1486             tempVal = 0u;
1487             break;
1488         case Mcbsp_WordLength_12:
1489             tempVal = 1u;
1490             break;
1491         case Mcbsp_WordLength_16:
1492             tempVal = 2u;
1493             break;
1494         case Mcbsp_WordLength_20:
1495             tempVal = 3u;
1496             break;
1497         case Mcbsp_WordLength_24:
1498             tempVal = 4u;
1499             break;
1500         case Mcbsp_WordLength_32:
1501             tempVal = 5u;
1502             break;
1503         default:
1504             /* wordlength is not supported by the driver                      */
1505             status = MCBSP_ERR_BADARGS;
1506             break;
1507     }
1509     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XWDLEN1_MASK);
1510     instHandle->hwInfo.regs->XCR |=
1511         (tempVal << CSL_MCBSP_XCR_XWDLEN1_SHIFT);
1513     if (Mcbsp_Phase_DUAL == params->chanConfig->phaseNum)
1514     {
1516         instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XFRLEN2_MASK);
1517         instHandle->hwInfo.regs->XCR |=
1518             ((params->chanConfig->frmLen2 -1u) << CSL_MCBSP_XCR_XFRLEN2_SHIFT);
1520         /* configure the word length of the single and dual phase frames      */
1521         switch (params->chanConfig->wrdLen2)
1522         {
1523             case Mcbsp_WordLength_8:
1524                 tempVal = 0u;
1525                 break;
1526             case Mcbsp_WordLength_12:
1527                 tempVal = 1u;
1528                 break;
1529             case Mcbsp_WordLength_16:
1530                 tempVal = 2u;
1531                 break;
1532             case Mcbsp_WordLength_20:
1533                 tempVal = 3u;
1534                 break;
1535             case Mcbsp_WordLength_24:
1536                 tempVal = 4u;
1537                 break;
1538             case Mcbsp_WordLength_32:
1539                 tempVal = 5u;
1540                 break;
1541             default:
1542                 /* wordlength is not supported by the driver                  */
1543                 status = MCBSP_ERR_BADARGS;
1544                 break;
1545         }
1547         instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XWDLEN2_MASK);
1548         instHandle->hwInfo.regs->XCR |=
1549             (tempVal << CSL_MCBSP_XCR_XWDLEN2_SHIFT);
1550     }
1551     /* set the companding selection                                           */
1552     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XCOMPAND_MASK);
1553     instHandle->hwInfo.regs->XCR |=
1554         (params->chanConfig->compandSel << CSL_MCBSP_XCR_XCOMPAND_SHIFT);
1556     /* set the bit reverse settings                                           */
1557     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XWDREVRS_MASK);
1558     instHandle->hwInfo.regs->XCR |=
1559         (params->chanConfig->bitReversal << CSL_MCBSP_XCR_XWDREVRS_SHIFT);
1561     /* frame ignore settings                                                  */
1562     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XFIG_MASK);
1563     instHandle->hwInfo.regs->XCR |=
1564         (params->chanConfig->frmSyncIgn << CSL_MCBSP_XCR_XFIG_SHIFT);
1566     /* configure the data delay                                               */
1567     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XDATDLY_MASK);
1568     instHandle->hwInfo.regs->XCR |=
1569         (params->chanConfig->dataDelay << CSL_MCBSP_XCR_XDATDLY_SHIFT);
1571     /* configure the multi channel control register settings                  */
1572     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XMCM_MASK);
1573     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->multiChanMode
1574                                           << CSL_MCBSP_MCR_XMCM_SHIFT);
1576     /* select the partition mode and the channel selection controls           */
1577     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XPABLK_MASK);
1578     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelA
1579                                           << CSL_MCBSP_MCR_XPABLK_SHIFT);
1581     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XPBBLK_MASK);
1582     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelB
1583                                           << CSL_MCBSP_MCR_XPBBLK_SHIFT);
1585     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XMCME_MASK);
1586     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionMode
1587                                           << CSL_MCBSP_MCR_XMCME_SHIFT);
1589     /* Configure the channels to be enabled                                   */
1590     instHandle->hwInfo.regs->XCERE0 = params->chanEnableMask[0];
1591     instHandle->hwInfo.regs->XCERE1 = params->chanEnableMask[1];
1592     instHandle->hwInfo.regs->XCERE2 = params->chanEnableMask[2];
1593     instHandle->hwInfo.regs->XCERE3 = params->chanEnableMask[3];
1596     /* configure the clock polarity                                           */
1597     if (Mcbsp_ClkPol_RISING_EDGE == params->clkSetup->clkPolarity)
1598     {
1599         /* clock data sampled on rising edge                                  */
1600         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKXP_MASK);
1601     }
1602     else
1603     {
1604         /* clock data sampled on falling edge                                 */
1605         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKXP_MASK);
1606     }
1608     /* configure the frame sync polarity                                      */
1609     if (Mcbsp_FsPol_ACTIVE_HIGH == params->clkSetup->frmSyncPolarity)
1610     {
1611         /* frame sync polarity is active high                                 */
1612         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSXP_MASK);
1613     }
1614     else
1615     {
1616         /* frame sync polarity is active low                                  */
1617         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSXP_MASK);
1618     }
1620     /* check if the frame sync generator is to be enabled for this TX section */
1621     if (Mcbsp_FsClkMode_EXTERNAL == params->clkSetup->frmSyncMode)
1622     {
1623         /* External frame sync to be used                                     */
1624         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSXM_MASK);
1626         /* frame sync generator needs to be disabled                          */
1627         instHandle->txFsgEnable = FALSE;
1628     }
1629     else
1630     {
1631         /* internal frame sync to be used                                     */
1632         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSXM_MASK);
1633         
1634         /* The FRST and GRST has to be cleared to configure the FSGM bit. 
1635          * By clearing the FRST and GRST bit, the sample rate generator and the 
1636          * frame sync generator will be kept in the reset mode. 
1637          * Ref IR SDOCM00077966
1638          */
1639         tempVal = instHandle->hwInfo.regs->SPCR;
1640         instHandle->hwInfo.regs->SPCR &= ~(CSL_MCBSP_SPCR_FRST_MASK | 
1641                                                                                                  CSL_MCBSP_SPCR_GRST_MASK );
1643         /* could be internal or configured for DXR to XSR copy                */
1644         if (Mcbsp_FsClkMode_INTERNAL == params->clkSetup->frmSyncMode)
1645         {
1646             /* set the FSGM bit in the SRGR register                          */
1647             instHandle->hwInfo.regs->SRGR |= (CSL_MCBSP_SRGR_FSGM_MASK);
1649             /* frame sync generator needs to be enabled                       */
1650             instHandle->txFsgEnable = TRUE;
1651         }
1652         else
1653         {   /* DXR to XSR copy generates frame sync                           */
1654             /* reset the FSGM bit in the SRGR register                        */
1655             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_FSGM_MASK);
1657             /* frame sync generator needs to be disabled                      */
1658             instHandle->txFsgEnable = FALSE;
1659         }
1660         /* The SPCR register values are reverted back once the FSGM bit is set
1661          */
1662         instHandle->hwInfo.regs->SPCR = tempVal;
1663     }
1665     /* configure the clock mode (external or internal)                        */
1666     if (Mcbsp_TxRxClkMode_EXTERNAL == params->clkSetup->clkMode)
1667     {
1668         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKXM_MASK);
1670         if (TRUE == instHandle->txFsgEnable)
1671         {
1672             /* frame sync generator is using the internal clock hence need to *
1673              * enable the sample rate generator                               */
1674             instHandle->txSrgEnable = TRUE;
1675         }
1676         else
1677         {
1678             /* dont require to enable the sample rate generator               */
1679             instHandle->txSrgEnable = FALSE;
1680         }
1681     }
1682     else
1683     {
1684         /* external mode clock enabled                                        */
1685         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKXM_MASK);
1687         /* sample rate generator is enabled                                   */
1688         instHandle->txSrgEnable = TRUE;
1689     }
1691     return (status);
1695 /**
1696  * \brief     This function configures the receives section of the mcbsp.
1697  *
1698  * \param     instHandle  [IN] pointer to the instance object.
1699  * \param     params      [IN] User supplied channel parameters
1700  *
1701  * \return    MCBSP_ERR_BADARGS  if configuration fails.
1702  *            MCBSP_STATUS_COMPLETED if confioguration is sucessful.
1703  */
1704 int32_t Mcbsp_localConfigureRcvChannel(Mcbsp_Object_Unpadded *instHandle,
1705                                      Mcbsp_ChanParams *params)
1707     uint32_t  tempVal = 0x00;
1708     int32_t   status  = MCBSP_STATUS_COMPLETED;
1710     if ((NULL == instHandle) || (NULL == params))
1711     {
1712         return MCBSP_ERR_BADARGS;
1713     }
1715     /* configure the receive section                                          */
1716     /* configure the receive interrupt setting                                */
1717     instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_RINTM_MASK);
1718     instHandle->hwInfo.regs->SPCR |=
1719         (params->chanConfig->intMode << CSL_MCBSP_SPCR_RINTM_SHIFT);
1721     /* configure the Receive sign-extension and justification                 */
1722     instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_RJUST_MASK);
1723     instHandle->hwInfo.regs->SPCR |=
1724         (params->chanConfig->rjust << CSL_MCBSP_SPCR_RJUST_SHIFT);
1726     /* configure the receive control register settings                        */
1727     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RPHASE_MASK);
1728     instHandle->hwInfo.regs->RCR |=
1729         (params->chanConfig->phaseNum << CSL_MCBSP_RCR_RPHASE_SHIFT);
1731     /* configure the frame length for single and dual phase frames            */
1732     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RFRLEN1_MASK);
1733     instHandle->hwInfo.regs->RCR |=
1734         ((params->chanConfig->frmLen1 - 1u) << CSL_MCBSP_RCR_RFRLEN1_SHIFT);
1736     /* configure the word length of the single and dual phase frames          */
1737     switch (params->chanConfig->wrdLen1)
1738     {
1739         case Mcbsp_WordLength_8:
1740             tempVal = 0u;
1741             break;
1742         case Mcbsp_WordLength_12:
1743             tempVal = 1u;
1744             break;
1745         case Mcbsp_WordLength_16:
1746             tempVal = 2u;
1747             break;
1748         case Mcbsp_WordLength_20:
1749             tempVal = 3u;
1750             break;
1751         case Mcbsp_WordLength_24:
1752             tempVal = 4u;
1753             break;
1754         case Mcbsp_WordLength_32:
1755             tempVal = 5u;
1756             break;
1757         default:
1758             /* wordlength is not supported by the driver                      */
1759             status = MCBSP_ERR_BADARGS;
1760             break;
1761     }
1764     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RWDLEN1_MASK);
1765     instHandle->hwInfo.regs->RCR |=
1766         (tempVal << CSL_MCBSP_RCR_RWDLEN1_SHIFT);
1768     if (Mcbsp_Phase_DUAL == params->chanConfig->phaseNum)
1769     {
1770         instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RFRLEN2_MASK);
1771         instHandle->hwInfo.regs->RCR |=
1772         ((params->chanConfig->frmLen2 - 1u) << CSL_MCBSP_RCR_RFRLEN2_SHIFT);
1773     
1774         /* configure the word length of the single and dual phase frames      */
1775         switch (params->chanConfig->wrdLen2)
1776         {
1777             case Mcbsp_WordLength_8:
1778                 tempVal = 0u;
1779                 break;
1780             case Mcbsp_WordLength_12:
1781                 tempVal = 1u;
1782                 break;
1783             case Mcbsp_WordLength_16:
1784                 tempVal = 2u;
1785                 break;
1786             case Mcbsp_WordLength_20:
1787                 tempVal = 3u;
1788                 break;
1789             case Mcbsp_WordLength_24:
1790                 tempVal = 4u;
1791                 break;
1792             case Mcbsp_WordLength_32:
1793                 tempVal = 5u;
1794                 break;
1795             default:
1796                 /* wordlength is not supported by the driver                      */
1797                 status = MCBSP_ERR_BADARGS;
1798                 break;
1799         }
1801         instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RWDLEN2_MASK);
1802         instHandle->hwInfo.regs->RCR |=
1803             (tempVal << CSL_MCBSP_RCR_RWDLEN2_SHIFT);
1804     }
1805     /* set the companding selection                                           */
1806     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RCOMPAND_MASK);
1807     instHandle->hwInfo.regs->RCR |=
1808         (params->chanConfig->compandSel << CSL_MCBSP_RCR_RCOMPAND_SHIFT);
1810     /* set the bit reverse settings                                           */
1811     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RWDREVRS_MASK);
1812     instHandle->hwInfo.regs->RCR |=
1813         (params->chanConfig->bitReversal << CSL_MCBSP_RCR_RWDREVRS_SHIFT);
1815     /* frame ignore settings                                                  */
1816     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RFIG_MASK);
1817     instHandle->hwInfo.regs->RCR |=
1818         (params->chanConfig->frmSyncIgn << CSL_MCBSP_RCR_RFIG_SHIFT);
1820     /* configure the data delay                                               */
1821     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RDATDLY_MASK);
1822     instHandle->hwInfo.regs->RCR |=
1823         (params->chanConfig->dataDelay << CSL_MCBSP_RCR_RDATDLY_SHIFT);
1825     /* Configure the channels to be enabled                                   */
1826     instHandle->hwInfo.regs->RCERE0 = params->chanEnableMask[0];
1827     instHandle->hwInfo.regs->RCERE1 = params->chanEnableMask[1];
1828     instHandle->hwInfo.regs->RCERE2 = params->chanEnableMask[2];
1829     instHandle->hwInfo.regs->RCERE3 = params->chanEnableMask[3];
1831     /* configure the MCR register                                             */
1832     switch (params->multiChanCtrl->multiChanMode)
1833     {
1834         case Mcbsp_McmMode_ALL_CHAN_ENABLED_UNMASKED:
1835         case Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED:
1836             break;
1837         default:
1838             status = MCBSP_ERR_BADARGS;
1839             break;
1840     }
1842     if (MCBSP_STATUS_COMPLETED == status)
1843     {
1844         instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RMCM_MASK);
1845         instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->multiChanMode
1846                                           << CSL_MCBSP_MCR_RMCM_SHIFT);
1847     }
1849     /* select the partition mode and the channel selection controls           */
1850     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RPABLK_MASK);
1851     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelA
1852                                           << CSL_MCBSP_MCR_RPABLK_SHIFT);
1854     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RPBBLK_MASK);
1855     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelB
1856                                           << CSL_MCBSP_MCR_RPBBLK_SHIFT);
1858     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RMCME_MASK);
1859     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionMode
1860                                           << CSL_MCBSP_MCR_RMCME_SHIFT);
1862     /* configure the clock polarity                                           */
1863     if (Mcbsp_ClkPol_RISING_EDGE == params->clkSetup->clkPolarity)
1864     {
1865         /* clock data sampled on rising edge                                  */
1866         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKRP_MASK);
1867     }
1868     else
1869     {
1870         /* clock data sampled on falling edge                                 */
1871         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKRP_MASK);
1872     }
1874     /* configure the frame sync polarity                                      */
1875     if (Mcbsp_FsPol_ACTIVE_HIGH == params->clkSetup->frmSyncPolarity)
1876     {
1877         /* frame sync polarity is active high                                 */
1878         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSRP_MASK);
1879     }
1880     else
1881     {
1882         /* frame sync polarity is active low                                  */
1883         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSRP_MASK);
1884     }
1887     /* check if the frame sync generator is to be enabled for this section    */
1888     if (Mcbsp_FsClkMode_INTERNAL == params->clkSetup->frmSyncMode)
1889     {
1890         /* set the frame sync generation mode                                 */
1891         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSRM_MASK);
1893         /* frame sync generator needs to be enabled                           */
1894         instHandle->rxFsgEnable = TRUE;
1895     }
1896     else
1897     {
1898         /* reset the frame sync generation mode                               */
1899         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSRM_MASK);
1901         /* frame sync generator needs to be disabled                          */
1902         instHandle->rxFsgEnable = FALSE;
1903     }
1905     /* configure the clock mode (external or internal)                        */
1906     if (Mcbsp_TxRxClkMode_EXTERNAL == params->clkSetup->clkMode)
1907     {
1908         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKRM_MASK);
1910         if (TRUE == instHandle->rxFsgEnable)
1911         {
1912             /* frame sync generator is using the internal clock hence need to *
1913              * enable the sample rate generator                               */
1914             instHandle->rxSrgEnable = TRUE;
1915         }
1916         else
1917         {
1918             /* dont require to enable the sample rate generator               */
1919             instHandle->rxSrgEnable = FALSE;
1920         }
1921     }
1922     else
1923     {
1924         /* external mode clock                                                */
1925         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKRM_MASK);
1927         /* sample rate generator is enabled                                   */
1928         instHandle->rxSrgEnable = TRUE;
1929     }
1930     return (status);
1933 /**
1934  * \brief     This function configures the sample rate generator and frame
1935  *            sync properties.
1936  *
1937  * \param     instHandle  [IN] pointer to the instance object.
1938  * \param     chanHandle  [IN] Handle to the channel.
1939  *
1940  * \return    MCBSP_ERR_BADARGS  if calculation fails.
1941  *            MCBSP_STATUS_COMPLETED if calculation is sucessful.
1942  */
1943 int32_t Mcbsp_localConfigureSrgr(Mcbsp_Object_Unpadded *instHandle,
1944                                Mcbsp_ChannelObj *chanHandle)
1946     Bool             srgrConfig  = FALSE;
1947     uint32_t         clkgDiv     = 0x00;
1948     uint32_t         noOfBits    = 0x00;
1949     uint32_t         framePeriod = 0x00;
1950     Bool             sclkme      = 0x00;
1951     Bool             clksm       = 0x00;
1952     int32_t          status      = MCBSP_STATUS_COMPLETED;
1953     void*            criticalSectionInfo;
1955     if ((NULL == instHandle) || (NULL == chanHandle))
1956     {
1957         return MCBSP_ERR_BADARGS;
1958     }
1960     /* check if the SRGR is not configured already                            */
1961     /* critical section starts                                                */
1962     criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
1964     if (FALSE == instHandle->srgConfigured)
1965     {
1966         /* set the status that SRGR is configured                             */
1967         instHandle->srgConfigured = TRUE;
1969         /* critical section ends                                              */
1970         Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1972         /* check if this channel requires the SRGR to be enabled              */
1973         if (MCBSP_MODE_INPUT == chanHandle->mode)
1974         {
1975             if (TRUE == instHandle->rxSrgEnable)
1976             {
1977                 /* Need to configure the SRGR                                 */
1978                 srgrConfig = TRUE;
1979             }
1980             else
1981             {
1982                         instHandle->srgConfigured = FALSE;   
1983             }
1984         }
1985         else
1986         {
1987             if (TRUE == instHandle->txSrgEnable)
1988             {
1989                 /* Need to configure the SRGR                                 */
1990                 srgrConfig = TRUE;
1991             }
1992             else
1993             {
1994                         instHandle->srgConfigured = FALSE;   
1995             }            
1996         }
1997     }
1998     else
1999     {
2000         /* critical section ends                                          */
2001         Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
2002     }
2004     if (TRUE == srgrConfig)
2005     {
2006         /* set the input clock selection for Sample rate generator            */
2007         switch (instHandle->srgrConfig.srgInputClkMode)
2008         {
2009             /* Input clock is CLKS                                            */
2010             case Mcbsp_SrgClk_CLKS:
2011                 sclkme = 0x00;
2012                 clksm = 0x00;
2014                 /* set the CLKS polarity (only if CLKS is used)               */
2015                 instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_CLKSP_MASK);
2016                 instHandle->hwInfo.regs->SRGR |=
2017                     (instHandle->srgrConfig.clksPolarity
2018                         << CSL_MCBSP_SRGR_CLKSP_SHIFT);
2020                 /* set the GSYNC option                                       */
2021                 instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_GSYNC_MASK);
2022                 instHandle->hwInfo.regs->SRGR |=
2023                     (instHandle->srgrConfig.gSync
2024                         << CSL_MCBSP_SRGR_GSYNC_SHIFT);
2025                 break;
2026             /* Input clock for SRG is from CPU clock                          */
2027             case Mcbsp_SrgClk_CLKCPU:
2028                 sclkme = 0x00;
2029                 clksm = 0x01u;
2030                 break;
2031             /* Input clock is from receive pin                                */
2032             case Mcbsp_SrgClk_CLKR:
2033                 sclkme = 0x01u;
2034                 clksm = 0x00;
2035                 break;
2036             /* Input clock is from transmit pin                               */
2037             case Mcbsp_SrgClk_CLKX:
2038                 sclkme = 0x01u;
2039                 clksm = 0x01u;
2040                 break;
2041             default:
2042                 status = MCBSP_ERR_BADARGS;
2043                 break;
2044         }
2046         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_SCLKME_MASK);
2047         instHandle->hwInfo.regs->PCR |= (sclkme << CSL_MCBSP_PCR_SCLKME_SHIFT);
2049         instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_CLKSM_MASK);
2050         instHandle->hwInfo.regs->SRGR |= (clksm << CSL_MCBSP_SRGR_CLKSM_SHIFT);
2052         /* calculate and set the CLKG div values                              */
2053         if (Mcbsp_Phase_DUAL == chanHandle->chanConfig.phaseNum)
2054         {
2055             noOfBits = ((chanHandle->chanConfig.wrdLen1
2056                             * chanHandle->chanConfig.frmLen1)
2057                         + (chanHandle->chanConfig.wrdLen2
2058                             * chanHandle->chanConfig.frmLen2));
2059         }
2060         else
2061         {
2062             noOfBits  = (chanHandle->chanConfig.wrdLen1
2063                             * chanHandle->chanConfig.frmLen1);
2064         }
2066         clkgDiv = ((instHandle->srgrConfig.srgrInputFreq/
2067                     (chanHandle->clkSetup.samplingRate
2068                     * noOfBits)) - 1u);
2070         framePeriod = (noOfBits - 1u);
2072         if ((0xFF < clkgDiv) || (0xFFF < framePeriod) ||
2073             (MCBSP_STATUS_COMPLETED != status))
2074         {
2075             /* The CLKGDIV or frame period value has exceeded the limit       */
2076             status = MCBSP_ERR_BADARGS;
2077         }
2078         else
2079         {
2080             /* set the value of the CLKGDIV                                   */
2081             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_CLKGDV_MASK);
2082             instHandle->hwInfo.regs->SRGR |= clkgDiv;
2084             /* set the value of the frame period                              */
2085             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_FPER_MASK);
2086             instHandle->hwInfo.regs->SRGR |=
2087                 (framePeriod << CSL_MCBSP_SRGR_FPER_SHIFT);
2089             /* set the frame width                                            */
2090             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_FWID_MASK);
2091             instHandle->hwInfo.regs->SRGR |=
2092                 (instHandle->srgrConfig.srgFrmPulseWidth <<
2093                     CSL_MCBSP_SRGR_FWID_SHIFT);
2094         }
2095     }
2097     return (status);
2100 /**
2101  * \brief   Abort the queued up requests.
2102  *
2103  *          This commands aborts all the pending IO requests and returns them
2104  *          to the application. The current state of the IO request will be set
2105  *          to ABORTED.
2106  *
2107  * \param   chanHandle   [IN]   Handle to the channel whose requests are to be
2108  *                              aborted
2109  *
2110  * \return  None
2111  */
2112 void Mcbsp_localAbortReset(Mcbsp_ChannelObj *chanHandle)
2114     Mcbsp_Object_Unpadded *instHandle   = NULL;
2115     Mcbsp_IOBuf      *ioBuf        = NULL;
2116     void*             criticalSectionInfo;
2117     uint32_t          timeoutCount = 0x00;
2119     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
2121     /* initialize the retry count value                                       */
2122     timeoutCount = instHandle->retryCount;
2124     /* critical section starts                                        */
2125     criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
2127     if (Mcbsp_DevMode_McBSP == instHandle->mode)
2128     {
2129         /* Disable the EDMA transfer for the current transfer channel         */
2130         EDMA3_DRV_disableTransfer(
2131             chanHandle->edmaHandle,
2132             chanHandle->xferChan,
2133             EDMA3_DRV_TRIG_MODE_EVENT);
2135         if (MCBSP_MODE_OUTPUT == chanHandle->mode)
2136         {
2137             /* Wait for the TX to be empty                                    */
2138             while ((CSL_MCBSP_SPCR_XEMPTY_MASK ==
2139                 (CSL_MCBSP_SPCR_XEMPTY_MASK & instHandle->hwInfo.regs->SPCR)) &&
2140                 (0 != timeoutCount))
2141             {
2142                 timeoutCount--;
2143             }
2144         }
2146         /* Stop the McBSP instance                                            */
2147         if (MCBSP_MODE_INPUT == chanHandle->mode)
2148         {
2149             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_DISABLE);
2150         }
2151         else
2152         {
2153             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_DISABLE);
2154         }
2156         /* Empty the floating queue. Aborted request is currently enqueued    *
2157          * in the floating queue. Dequeue the floating request in EDMA        *
2158          * param table and return the actual transfer element count           */
2159         while (TRUE !=  Mcbsp_osalQueueEmpty(chanHandle->ptrQFloatList))
2160         {
2161             ioBuf = Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
2163             if (NULL != ioBuf)
2164             {
2165                 /* if FLUSH cmd called for INPUT channel then status is equal *
2166                  * to FLUSHED otherwise status is equal to ABORTED            */
2167                 if ((TRUE == chanHandle->flush) &&
2168                     (MCBSP_MODE_INPUT == chanHandle->mode))
2169                 {
2170                     ioBuf->status = MCBSP_STATUS_FLUSHED;
2171                 }
2172                 else
2173                 {
2174                     ioBuf->status = MCBSP_STATUS_ABORTED;
2175                 }
2177                 if ((NULL !=  chanHandle->cbFxn) && (NULL != chanHandle->cbArg))
2178                 {
2179                     /*  Application callback                                  */
2180                     (*chanHandle->cbFxn)((void*)chanHandle->cbArg,ioBuf);
2181                 }
2182                 /* Decrement the submit count                                 */
2183                 chanHandle->submitCount--;
2184             }
2185         }
2187         /* Empty the pending queue                                            */
2188         while (TRUE != Mcbsp_osalQueueEmpty(chanHandle->ptrQPendList))
2189         {
2190             ioBuf = Mcbsp_osalQueueGet(chanHandle->ptrQPendList);
2192             if (NULL != ioBuf)
2193             {
2194                 /* if FLUSH cmd called for INPUT channel then status is equal *
2195                  * to MCBSP_STATUS_FLUSHED otherwise status is equal to MCBSP_STATUS_ABORTED    */
2196                 if ((TRUE == chanHandle->flush) &&
2197                     (MCBSP_MODE_INPUT == chanHandle->mode))
2198                 {
2199                     ioBuf->status = MCBSP_STATUS_FLUSHED;
2200                 }
2201                 else
2202                 {
2203                     ioBuf->status = MCBSP_STATUS_ABORTED;
2204                 }
2206                 if ((NULL != chanHandle->cbFxn) && (NULL != chanHandle->cbArg))
2207                 {
2208                     /*  Application callback                                  */
2209                     (*chanHandle->cbFxn)((void*)chanHandle->cbArg,ioBuf);
2210                 }
2211                 
2212                 /* Decrement the submit count                                 */
2213                 chanHandle->submitCount--;
2214             }
2215         }
2217         /* As EDMA is disabled it might have thrown an error and set error bit*
2218          * Clear the error bit to enable the transfer again                   */
2219         EDMA3_DRV_clearErrorBits(chanHandle->edmaHandle,chanHandle->xferChan);
2221         /* Configure the EDMA channel and EDMA param tables with              *
2222          * intialization configuration as they are configured at the          *
2223          * create time.                                                       */
2224         Mcbsp_localEdmaChanPaRAMsetup(chanHandle);
2226 #ifdef MCBSP_LOOPJOB_ENABLE
2228                 /* configure the FIFO for the specific channel                        */
2229         if (TRUE == chanHandle->enableHwFifo)
2230         {
2231             /* Disable and enable the FIFO so that the events are             *
2232              * generated to the Mcbsp for the first time                      */
2233             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,FALSE);
2234             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,TRUE);
2235         }
2237         /* Enable the EDMA transfer to start the Loop job running             */
2238         EDMA3_DRV_enableTransfer(
2239             chanHandle->edmaHandle,
2240             chanHandle->xferChan,
2241             EDMA3_DRV_TRIG_MODE_EVENT);
2243         chanHandle->loopjobUpdatedinParamset = TRUE;
2244         chanHandle->nextLinkParamSetToBeUpdated = 0;
2245         
2246         /* start the Mcbsp channel                                             */
2247         if (MCBSP_MODE_INPUT == chanHandle->mode)
2248         {
2249             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_ENABLE);
2250         }
2251         else
2252         {
2253                         Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
2254                 }
2255 #endif
2256     }
2257     /* critical section ends                                          */
2258     Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
2260 /**
2261  *
2262  * \brief   This function configures the Hardware FIFO
2263  *
2264  * \param   hMcbsp       [IN] pointer to the Mcbsp Hardware information struct
2265  * \param   chanHandle   [IN] handle to the channel
2266  * \param   enableHwFifo [IN] option to Enable or disbale the FIFO
2267  *
2268  * \return  None
2269  *
2270  * \enter   hMcbsp      is a valid non null pointer
2271  *          chanHandle  is a valid non null pointer
2272  *
2273  * \leave   Not implemented
2274  *
2275  */
2276 void mcbspConfigureFifo(Mcbsp_HwInfo_Unpadded *hMcbsp,
2277                         Mcbsp_ChannelObj    *chanHandle,
2278                         Bool                 enableHwFifo)
2280     /* check if the HW FIFO usage is requested by the user for this channel   */
2281     if (TRUE == enableHwFifo)
2282     {
2283         if (MCBSP_MODE_INPUT == chanHandle->mode)
2284         {
2285             /* configure the receive channel                                  */
2286             /* Step 1 : configure the "WNUMDMA" and "WNUMEVT" bits before     *
2287              * enabling the FIFO                                              */
2288             hMcbsp->fifoRegs->RFIFOCTL =
2289                 (1 << CSL_BFIFO_RFIFOCTL_RNUMEVT_SHIFT);
2291             hMcbsp->fifoRegs->RFIFOCTL |=
2292                 (CSL_BFIFO_RFIFOCTL_RNUMDMA_1WORDS
2293                     << CSL_BFIFO_RFIFOCTL_RNUMDMA_SHIFT);
2295             /* enable the FIFO now by setting the "WENA" bit                  */
2296             hMcbsp->fifoRegs->RFIFOCTL |=
2297                 (CSL_BFIFO_RFIFOCTL_RENA_ENABLED
2298                     << CSL_BFIFO_RFIFOCTL_RENA_SHIFT);
2299         }
2300         else
2301         {
2302             /* configure the transmit channel                                 */
2303             /* Step 1 : configure the "WNUMDMA" and "WNUMEVT" bits before     *
2304              * enabling the FIFO                                              */
2305             hMcbsp->fifoRegs->WFIFOCTL =
2306                 (1 << CSL_BFIFO_WFIFOCTL_WNUMEVT_SHIFT);
2308             hMcbsp->fifoRegs->WFIFOCTL |=
2309                 (CSL_BFIFO_WFIFOCTL_WNUMDMA_1WORDS
2310                     << CSL_BFIFO_WFIFOCTL_WNUMDMA_SHIFT);
2312             /* enable the FIFO now by setting the "WENA" bit                  */
2313             hMcbsp->fifoRegs->WFIFOCTL |=
2314                 (CSL_BFIFO_WFIFOCTL_WENA_ENABLED
2315                     << CSL_BFIFO_WFIFOCTL_WENA_SHIFT);
2316         }
2317     }
2318     else
2319     {
2320         /* FIFO needs to be disabled                                          */
2321         if (MCBSP_MODE_INPUT == chanHandle->mode)
2322         {
2323             /* disable the FIFO now by resetting the "WENA" bit               */
2324             hMcbsp->fifoRegs->RFIFOCTL =
2325                 (CSL_BFIFO_RFIFOCTL_RENA_DISABLED
2326                     << CSL_BFIFO_RFIFOCTL_RENA_SHIFT);
2327         }
2328         else
2329         {
2330             /* disable the FIFO now by resetting the "WENA" bit               */
2331             hMcbsp->fifoRegs->WFIFOCTL =
2332                 (CSL_BFIFO_WFIFOCTL_WENA_DISABLED
2333                     << CSL_BFIFO_WFIFOCTL_WENA_SHIFT);
2334         }
2335     }
2338 /**
2339  * \brief   This is going to complete the current request and abort
2340  *          all other reqest.
2341  *
2342  * \param   chanHandle   [IN]   Channel handle
2343  *
2344  * \return  None
2345  *
2346  * \enter   chanHandle  is a valid non null pointer
2347  *
2348  * \leave   Not implemented
2349  */
2350 void Mcbsp_localCancelAndAbortAllIo(Mcbsp_ChannelObj *chanHandle)
2352     chanHandle->submitCount--;
2353     chanHandle->tempIOBuf->status = MCBSP_STATUS_ABORTED;
2355     Mcbsp_localCompleteCurrentIo(chanHandle);
2357     Mcbsp_localAbortReset(chanHandle);
2360 #ifndef MCBSP_LOOPJOB_ENABLE
2361 /**
2362  *  \brief  This function waits for the FIFO to be emptied(if enabled) and the
2363  *          TX empty bit to be set so that the TX section could be disabled when
2364  *          there is no data present.
2365  *
2366  *  \param  arg0   [IN]  Handle to the TX channel
2367  *  \param  arg1   [IN]  unused
2368  *
2369  *  \return None
2370  *
2371  *  \enter  arg0 is a valid non null pointer
2372  *
2373  *  \leave  Not implemented
2374  */
2375 void Mcbsp_TxFifo(int32_t arg0, int32_t arg1)
2377     Mcbsp_ChannelObj  *chanHandle = NULL;
2378     Mcbsp_Object *hInst = NULL;
2379     Mcbsp_Object_Unpadded *instHandle = NULL;
2380     uint32_t           timeOut    = 0x00;
2381     void*              criticalSectionInfo;
2383     chanHandle = (Mcbsp_ChannelObj *)arg0;
2384     hInst = (Mcbsp_Object *)arg1;
2385     instHandle = (Mcbsp_Object_Unpadded *)&(hInst->obj);
2387     /* critical section starts                                                */
2388     criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
2390     /* update the timeout value from the instance handle                      */
2391     timeOut = instHandle->retryCount;
2393     /* we have come here means that the Mcbsp has got an callback but it      *
2394      * did have any more buffer to load Hence here we will wait for the       *
2395      * FIFO to become empty (if FIFO is enabled) else wait for the TX to      *
2396      * become empty.then we will disable the TX section                       */
2397     if (TRUE == chanHandle->enableHwFifo)
2398     {
2399         while ((0 != (instHandle->hwInfo.fifoRegs->WFIFOSTS &
2400                        CSL_BFIFO_WFIFOSTS_WLVL_MASK))
2401                 && (0 != timeOut))
2402         {
2403             /* reduce the timeout count and check if the FIFO is empty    */
2404             timeOut--;
2405         }
2406     }
2408     /* reinitialize the retry count                                       */
2409     timeOut = instHandle->retryCount;
2411     while ((CSL_MCBSP_SPCR_XEMPTY_MASK ==
2412             (instHandle->hwInfo.regs->SPCR & CSL_MCBSP_SPCR_XEMPTY_MASK))
2413            && (0 != timeOut))
2414     {
2415         /* reduce the retry count and check if the TX has completed           *
2416          * transmitting all the bytes                                         */
2417         timeOut--;
2418     }
2420     /* we need to stop the frame sycn generator now.But also need to check    *
2421      * if  1.The frame sycn generator is actually started By TX.              *
2422      *     2.The RX is  not feeding of the sample rate generator              */
2423     if ((TRUE == instHandle->txFsgEnable) &&
2424         ((TRUE != instHandle->rxFsgEnable)
2425             || (TRUE == instHandle->stopSmFsRcv)))
2426     {
2427         /* Now we can disable the frame sync generator                        */
2428         Mcbsp_localResetCtrl(
2429             (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj),
2430             Mcbsp_SpcrCtrl_FSYNC_DISABLE);
2431         instHandle->fsgEnabled = FALSE;
2432     }
2434     /* Stop the TX section                                                    */
2435     Mcbsp_localResetCtrl(
2436         (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj),
2437         Mcbsp_SpcrCtrl_TX_DISABLE);
2439     /* Transmit state machine is stopped                                      */
2440     instHandle->stopSmFsXmt = TRUE;
2442     /* clear the error bits in the EDMA(as this is the last buffer)           */
2443     EDMA3_DRV_clearErrorBits(
2444         chanHandle->edmaHandle,
2445         chanHandle->xferChan);
2447     /* complete the IOP now and call the callback to the stream               */
2448     chanHandle->tempIOBuf = Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
2450     /* Decrement the submit count for the IO buffers                          */
2451     chanHandle->submitCount--;
2453     chanHandle->isTempIOBufValid = TRUE;
2454     chanHandle->tempIOBuf->status = chanHandle->currentError;
2455     Mcbsp_localCompleteCurrentIo(chanHandle);
2457     /* critical section ends                                                  */
2458     Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
2462 #endif /* #ifndef MCBSP_LOOPJOB_ENABLE */
2465 /**
2466  * \brief  This function toggles the index of the edma params
2467  *
2468  * \param  index [IN]  pointer to current index
2469  *
2470  * \return None
2471  *
2472  * \enter  index is a valid non null pointer
2473  *
2474  * \leave  Not implemented
2475  */
2476 void Mcbsp_localGetNextIndex(uint32_t *index)
2478     *index = (((*index) + 1u) & 0x01u);
2481 /**
2482  *  \brief  This function loads the buffers to the actual EDMA paramset.
2483  *
2484  *  \param  chanHandle [IN]  Handle to channel.
2485  *  \param  ioBuf      [IN]  pointer to the ioBuf
2486  *
2487  *  \return None
2488  *
2489  *  \enter  Not implemented
2490  *
2491  *  \leave  Not implemented
2492  */
2493 void Mcbsp_localLoadPktToEdma(Mcbsp_ChannelObj *chanHandle,Mcbsp_IOBuf *ioBuf)
2495 #ifndef MCBSP_LOOPJOB_ENABLE
2496     Mcbsp_Object_Unpadded *instHandle  = NULL;
2497 #endif
2498     int32_t             status      = MCBSP_STATUS_COMPLETED;
2500 #ifndef MCBSP_LOOPJOB_ENABLE
2501     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
2502 #endif
2504     chanHandle->currentDataSize = (uint16_t)ioBuf->size;
2505     chanHandle->userDataBufferSize = (uint32_t)ioBuf->size;
2506     
2507 #ifdef MCBSP_LOOPJOB_ENABLE
2508     if (Mcbsp_MAXLINKCNT == chanHandle->submitCount)
2509     {
2510 #else
2511     /* The second and the third buffer will go the link paramsets             */
2512     if (Mcbsp_MAXLINKCNT <= chanHandle->submitCount)
2513     {
2514 #endif
2515         /* Though we have to post to param set directly from here,            *
2516          * there will be differene between first such buffer and              *
2517          * second buffer. As we have control here we are second buffer        *
2518          * and first buffer has not yet returned (or corresponding            *
2519          * edma callback has not been called.For second buffer, we            *
2520          * will be updating the second param set, which is currently          *
2521          * hosting loopjob parameter. Hence increment the index to            *
2522          * point second paramset and since we are moving out loopjob          *
2523          * from both param sets, the loopjobUpdatedinParamset is reset        */
2524         chanHandle->loopjobUpdatedinParamset = FALSE;
2525         Mcbsp_localGetNextIndex(
2526             &chanHandle->nextLinkParamSetToBeUpdated);
2527     }
2528     
2529     /* Now update the data buffer to the link params. The paramset to         *
2530      * be updated is decidec by the "nextLinkParamSetToBeUpdated"             */
2531     if (MCBSP_STATUS_COMPLETED != Mcbsp_localUpdtDtPktToLnkPrms(chanHandle,ioBuf))
2532     {
2533         status = MCBSP_ERR_BADIO;
2534     }
2535     
2536     if ((1u == chanHandle->submitCount) && (MCBSP_STATUS_COMPLETED == status))
2537     {
2538 #ifdef MCBSP_LOOPJOB_ENABLE
2539         /* if at all this is the very first buffer, then one param set        *
2540          * has loop job loaded , self linked and active with the main         *
2541          * xfer channel param. other param set is ready loaded (just          *
2542          * now)and has link param set as the one having loopjob (this         *
2543          * is to ensure that if at all we are not getting any more            *
2544          * buffers loopjob be will taken over). Now we have to link           *
2545          * the floating / newly loaded param set to xfer channel.             */
2546         if (MCBSP_STATUS_COMPLETED != EDMA3_DRV_linkChannel(
2547                                  chanHandle->edmaHandle,
2548                                  chanHandle->xferChan,
2549                                  chanHandle->pramTbl[chanHandle->nextLinkParamSetToBeUpdated]))
2550         {
2551             status = MCBSP_ERR_BADIO;
2552         }
2553 #else
2554         /* configure the FIFO for the specific channel                        */
2555         if (TRUE == chanHandle->enableHwFifo)
2556         {
2557             /* Disable and enable the FIFO so that the events are             *
2558              * generated to the Mcbsp for the first time                      */
2559             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,FALSE);
2560             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,TRUE);
2561         }
2563         /* enable the EDMA transfer for the channel so that it is             *
2564          * ready to transfer the data as soon as the state machine is         *
2565          * enabled                                                            */
2566         EDMA3_DRV_enableTransfer(
2567             chanHandle->edmaHandle,
2568             chanHandle->xferChan,
2569             EDMA3_DRV_TRIG_MODE_EVENT);
2571         /* Start the McBSP hardware                                           */
2572         if (MCBSP_MODE_INPUT == chanHandle->mode)
2573         {
2574             instHandle->stopSmFsRcv = FALSE;
2575             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_ENABLE);
2576         }
2577         else
2578         {
2579             instHandle->stopSmFsXmt = FALSE;
2580             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
2581         }
2583         if (((MCBSP_MODE_INPUT == chanHandle->mode) && 
2584             (TRUE == instHandle->rxFsgEnable)) ||
2585             ((MCBSP_MODE_OUTPUT == chanHandle->mode) &&
2586              (TRUE == instHandle->txFsgEnable)))
2587         {
2588             /* enable the sample rate generator                               */
2589             Mcbsp_localResetCtrl(
2590                 instHandle,
2591                 Mcbsp_SpcrCtrl_FSYNC_ENABLE);
2592         }
2593 #endif /* MCBSP_LOOPJOB_ENABLE */
2594     }
2597 /**
2598  * \brief   Function to modify the sample rate generator configuration
2599  *
2600  * \param   chanHandle  [IN]  Handle to the channel
2601  * \param   arg         [IN]  pointer to the srg config setup
2602  *
2603  * \return  None
2604  */
2605 int32_t Mcbsp_localModifySampleRate(Mcbsp_ChannelObj *chanHandle,void* arg)
2607     Mcbsp_Object_Unpadded *instHandle = NULL;
2608     Mcbsp_ClkSetup  *clkConfig  = NULL;
2609     int32_t            status     = MCBSP_STATUS_COMPLETED;
2611     if ((NULL == arg) || (NULL == chanHandle))
2612     {
2613         return MCBSP_ERR_BADARGS;
2614     }
2616     instHandle = &(chanHandle->devHandle->obj);
2617     if (NULL == instHandle)
2618     {
2619         return MCBSP_ERR_BADARGS;
2620     }
2622     clkConfig = (Mcbsp_ClkSetup *)arg;
2624     /* check if the Frame sync clock is generated by the module               */
2625     if (TRUE == instHandle->srgConfigured)
2626     {
2627         /* Configure the McBSP with user supplied parameters                  */
2628         chanHandle->clkSetup = *(clkConfig);
2629         instHandle->srgConfigured = FALSE;
2631         /* stop the sample rate generator                             */
2632         if (TRUE == instHandle->srgEnabled)
2633         {
2634             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_SRG_DISABLE);
2635         
2636             status = Mcbsp_localConfigureSrgr(instHandle,chanHandle);
2637         
2638             if (MCBSP_STATUS_COMPLETED == status)
2639             {
2640                 /* enable the sample rate generator                   */
2641                 Mcbsp_localResetCtrl(
2642                     instHandle,
2643                     Mcbsp_SpcrCtrl_SRG_ENABLE);
2644         
2645                 /* wait for the 2CLKG clock cycles                    */
2646                 Mcbsp_osalWaitNBitClocks(2u);
2647             }
2648         
2649             /* clear the XSYNCERR (to be done only if TX is used)     */
2650             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
2651             {
2652                 /* Enable the TX section                              */
2653                 Mcbsp_localResetCtrl(
2654                     instHandle,
2655                     Mcbsp_SpcrCtrl_TX_ENABLE);
2656         
2657                 /* wait for 2 CLKR or CLX cycles                      */
2658                 Mcbsp_osalWaitNBitClocks(2u);
2659         
2660                 /* Disable the TX section to clear any XYNCERR        */
2661                 Mcbsp_localResetCtrl(
2662                     instHandle,
2663                     Mcbsp_SpcrCtrl_TX_DISABLE);
2664             }
2665         }
2666     }
2667     else
2668     {
2669         status = MCBSP_ERR_BADMODE;
2670         
2671         if (MCBSP_MODE_INPUT == chanHandle->mode)
2672         {
2673             if (TRUE != instHandle->rxSrgEnable)
2674             {
2675                     /* Since this mode does not use the sample rate generator, so
2676                      * there is no point in changing the sample rate. So return 
2677                      * with success*/
2678                                 status  = MCBSP_STATUS_COMPLETED;
2679             }
2680         }
2681         else
2682         {
2683             if (TRUE != instHandle->txSrgEnable)
2684             {
2685                     /* Since this mode does not use the sample rate generator, so
2686                      * there is no point in changing the sample rate. So return 
2687                      * with success*/
2688                     status      = MCBSP_STATUS_COMPLETED;
2689             }
2690         }
2691     }
2692     return (status);
2695 /* ========================================================================== */
2696 /*                             END OF FILE                                    */
2697 /* ========================================================================== */