df911b0fc93292769e62a33fd86e1f39602d76c4
[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>
56 #
59 /* ========================================================================== */
60 /*                       GLOBAL MODULE STATE                                  */
61 /* ========================================================================== */
63 /**
64  * \brief  Array of Mcbsp instance State objects array
65  */
66 #pragma DATA_SECTION (Mcbsp_Instances, ".mcbsp");
67 #pragma DATA_ALIGN   (Mcbsp_Instances, MCBSP_MAX_CACHE_ALIGN)
68 Mcbsp_Object Mcbsp_Instances[CSL_MCBSP_PER_CNT];
70 /**
71  * \brief  Mcbsp structure containing the information specific to an instance.
72  */
73 /* Shared Memory Variable to ensure synchronizing SRIO initialization
74  * with all the other cores. */
75 /* Created an array to pad the cache line with MCBSP_MAX_CACHE_ALIGN size */
76 #pragma DATA_SECTION (Mcbsp_deviceInstInfo, ".mcbsp");
77 #pragma DATA_ALIGN   (Mcbsp_deviceInstInfo, MCBSP_MAX_CACHE_ALIGN)
78 Mcbsp_HwInfo Mcbsp_deviceInstInfo[CSL_MCBSP_PER_CNT];
80 /**
81  *  \brief  Mute buffer per instance
82  *
83  *  \note   Buffer used when the mcbsp is placed in mute.
84  */
85 #pragma DATA_SECTION (Mcbsp_muteBuf, ".mcbsp");
86 #pragma DATA_ALIGN   (Mcbsp_muteBuf, MCBSP_MAX_CACHE_ALIGN)
87 Mcbsp_TempBuffer Mcbsp_muteBuf[CSL_MCBSP_PER_CNT];
89 #ifdef MCBSP_LOOPJOB_ENABLE
90 /**
91  * \brief  Destination loop buffer per instance
92  *
93  * \note   Buffer used during the loop job mode for the Transmit section
94  */
95 #pragma DATA_SECTION (Mcbsp_loopDstBuf, ".mcbsp");
96 #pragma DATA_ALIGN   (Mcbsp_loopDstBuf, MCBSP_MAX_CACHE_ALIGN)
97 Mcbsp_TempBuffer Mcbsp_loopDstBuf[CSL_MCBSP_PER_CNT];
99 /**
100  * \brief  Receive loop buffer per instance
101  *
102  * \note   Buffer used during the loop job mode for the Receive section
103  */
104 #pragma DATA_SECTION (Mcbsp_loopSrcBuf, ".mcbsp");
105 #pragma DATA_ALIGN   (Mcbsp_loopSrcBuf, MCBSP_MAX_CACHE_ALIGN)
106 Mcbsp_TempBuffer Mcbsp_loopSrcBuf[CSL_MCBSP_PER_CNT];
107 #endif /* MCBSP_LOOPJOB_ENABLE */
109 /*============================================================================*/
110 /*                         LOCAL FUNCTION PROTOTYPES                          */
111 /*============================================================================*/
112 int32_t mcbspSubmitReq(Mcbsp_Object_Unpadded *instHandle,
113                        Mcbsp_ChannelObj  *chanHandle,
114                        Mcbsp_IOBuf       *ioBuf);
115 void mcbspConfigureFifo(Mcbsp_HwInfo_Unpadded *hMcbsp,
116                         Mcbsp_ChannelObj    *chanHandle,
117                         Bool                 enableHwFifo);
119 #ifndef MCBSP_LOOPJOB_ENABLE
120 extern uint32_t Mcbsp_edmaChanNum;
121 #endif /* MCBSP_LOOPJOB_ENABLE */
124 /* ========================================================================== */
125 /*                    MODULE PUBLIC FUNCTIONS                                 */
126 /* ========================================================================== */
128 /**
129  *  @b Description
130  *  @n  
131  *      This is the MCBSP Driver Initialization API which needs to be 
132  *      invoked by the users to initialize the MCBSP peripheral. This call
133  *      is *mandatory* and should be called before calling any of the 
134  *      other driver API's. 
135  *
136  *      This should only be called *ONCE* for the device.
137  *
138  *  @retval
139  *      MCBSP_STATUS_COMPLETED     if successful 
140  *  @retval
141  *      MCBSP_ERR_BADARGS          if not successful
142  *      MCBSP_ERR_ALLOC
143  */
144 int32_t mcbspInit (void)
146     int32_t devId = 0;
147     void *criticalSectionInfo;
149     /* Begin Critical Section before accessing shared resources. */
150     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
152     /* Invalidate the Cache Contents */
153     Mcbsp_osalBeginMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
155     /* initialize the information for all the device instances                */
156     for (devId = 0; devId < CSL_MCBSP_PER_CNT; devId++)
157     {
158         /* initialise the instance object                                     */
159         memset((void *)&Mcbsp_Instances[devId], 0, sizeof(Mcbsp_Object));
160         Mcbsp_Instances[devId].obj.inUse = FALSE;
161     }
163     /* Writeback Global Object */
164     Mcbsp_osalEndMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
166     /* End Critical Section */
167     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
169     return MCBSP_STATUS_COMPLETED;
172 /**
173  * \brief   Allocates and configures the McBSP instance specified by devid.
174  *
175  *  Acquires the Handle of the McBSP and configure the McBSP by
176  *  default for the following things.
177  *      o   Data output for audio playback
178  *      o   Data input for audio recording
179  *      o   Configure the McBSP in DSP/TDM data format mode of the audio
180  *          codec.
181  *      o   Configure the McBSP to receive the Frame Sync and bit clock
182  *          externally for both receiver and transmitter.
183  *      o   McBSP can also be configured to generate Frame Sync and
184  *          bit clock internally by enabling sample rate generator and
185  *          frame sync generator blocks respectively depending on the
186  *          fields set in the device parameter structure which shall
187  *          be passed to mcbspBindDev() function as one of the parameter.
188  *
189  * \param   devp         [OUT]  pointer to hold allocated instance object ptr
190  * \param   devid        [IN]   instance number of the mcbsp
191  * \param   devParams    [IN]   user supplied data params.
192  *
193  * \return  MCBSP_STATUS_COMPLETED     if successful
194  *
195  *          MCBSP_ERR_BADARGS          if not successful
196  *          MCBSP_ERR_ALLOC
197  *
198  * \enter   devp        should be non NULL and valid pointer,
199  *          devId       should be < CSL_MCBSP_PER_CNT
200  *          devParams   should be non NULL and valid pointer,
201  *
202  * \leave   Not implemented
203  */
204 int32_t mcbspBindDev(void* *devp, int32_t devid, void* devParams)
206     Mcbsp_Object_Unpadded *instHandle = NULL;
207     Mcbsp_Params *params     = NULL;
208     uint32_t      ctrlMask   = 0x00;
209     uint32_t      count      = 0x00;
210     int32_t       status     = MCBSP_STATUS_COMPLETED;
211     void         *criticalSectionInfo;
213     /* Begin Critical Section before accessing shared resources. */
214     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
216     /* Invalidate the Cache Contents */
217     Mcbsp_osalBeginMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
218     Mcbsp_osalBeginMemAccess ((void *)Mcbsp_deviceInstInfo, sizeof(Mcbsp_deviceInstInfo));
220 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
221     if ((NULL == devp) || (NULL == devParams) || (devid >= CSL_MCBSP_PER_CNT))
222     {
223         status = MCBSP_ERR_BADARGS;
224     }
226     if (MCBSP_STATUS_COMPLETED == status)
227     {
228         if (TRUE == Mcbsp_Instances[devid].obj.inUse)
229         {
230             status = MCBSP_ERR_INUSE;
231         }
232         else
233         {
234 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
235             /* copy the pointer to the instance object                        */
236             instHandle = &(Mcbsp_Instances[devid].obj);
238             /* set the module state as in use                                 */
239             Mcbsp_Instances[devid].obj.inUse = TRUE;
241             params = (Mcbsp_Params *)devParams;
243 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
244             /* Only DMA mode of the operation is supported for Mcbsp mode     */
245             if ((Mcbsp_DevMode_McBSP == params->mode) &&
246                 (Mcbsp_OpMode_DMAINTERRUPT != params->opMode))
247             {
248                 status = MCBSP_ERR_BADMODE;
249             }
250             else
251             {
252                 if (NULL == params->srgSetup)
253                 {
254                     status = MCBSP_ERR_BADMODE;
255                 }
256             }
257         }
258     }
259 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
261     if (MCBSP_STATUS_COMPLETED == status)
262     {
263         /* update the instance of the device being created                    */
264         instHandle->instNum = devid;
266         /* update the user supplied params to the instance object             */
267         instHandle->mode = params->mode;
268         instHandle->opMode = params->opMode;
269         instHandle->enablecache = params->enablecache;
271         /* copy the SOC related information in to the instance object         */
272         instHandle->hwInfo = Mcbsp_deviceInstInfo[devid].obj;
274         /* stop the state machine of RX and TX                                */
275         instHandle->stopSmFsXmt = TRUE;
276         instHandle->stopSmFsRcv = TRUE;
278         instHandle->retryCount = Mcbsp_POLLED_RETRYCOUNT;
280         /* configure the default values for the transmit channel              */
281         instHandle->xmtObj.mode = (uint16_t)MCBSP_MODE_OUTPUT;
282         instHandle->xmtObj.devHandle = NULL;
283         instHandle->xmtObj.cbFxn   = NULL;
284         instHandle->xmtObj.cbArg   = NULL;
285         instHandle->xmtObj.edmaHandle = NULL;
286         instHandle->xmtObj.edmaEventQue = Mcbsp_TXEVENTQUE;
287         instHandle->xmtObj.edmaCallback = NULL;
288         instHandle->xmtObj.xferChan = 0x00;
289         instHandle->xmtObj.tcc = 0x00;
290         instHandle->xmtObj.tempIOBuf = NULL;
291         instHandle->xmtObj.submitCount = 0x00;
292         instHandle->xmtObj.dataFormat = Mcbsp_BufferFormat_1SLOT;
293         instHandle->xmtObj.bMuteON = FALSE;
294         instHandle->xmtObj.paused = FALSE;
295         instHandle->xmtObj.flush = FALSE;
296         instHandle->xmtObj.isTempIOBufValid = FALSE;
297         instHandle->xmtObj.enableHwFifo = TRUE;
298         instHandle->xmtObj.gblErrCbk = NULL;
299         instHandle->xmtObj.userDataBufferSize = 0x00;
300         instHandle->xmtObj.loopJobBuffer = NULL;
301         instHandle->xmtObj.loopJobLength = 0x00;
302         instHandle->xmtObj.nextLinkParamSetToBeUpdated = 0x00;
303         instHandle->xmtObj.loopjobUpdatedinParamset = FALSE;
304         instHandle->xmtObj.roundedWordWidth = 0x00;
306         instHandle->rcvObj.mode = (uint16_t)MCBSP_MODE_INPUT;
307         instHandle->rcvObj.devHandle = NULL;
308         instHandle->rcvObj.cbFxn   = NULL;
309         instHandle->rcvObj.cbArg   = NULL;
310         instHandle->rcvObj.edmaHandle = NULL;
311         instHandle->rcvObj.edmaEventQue = Mcbsp_RXEVENTQUE;
312         instHandle->rcvObj.edmaCallback = NULL;
313         instHandle->rcvObj.xferChan = 0x00;
314         instHandle->rcvObj.tcc = 0x00;
315         instHandle->rcvObj.tempIOBuf = NULL;
316         instHandle->rcvObj.submitCount = 0x00;
317         instHandle->rcvObj.dataFormat = Mcbsp_BufferFormat_1SLOT;
318         instHandle->rcvObj.bMuteON = FALSE;
319         instHandle->rcvObj.paused = FALSE;
320         instHandle->rcvObj.flush = FALSE;
321         instHandle->rcvObj.isTempIOBufValid = FALSE;
322         instHandle->rcvObj.enableHwFifo = TRUE;
323         instHandle->rcvObj.gblErrCbk = NULL;
324         instHandle->rcvObj.userDataBufferSize = 0x00;
325         instHandle->rcvObj.loopJobBuffer = NULL;
326         instHandle->rcvObj.loopJobLength = 0x00;
327         instHandle->rcvObj.nextLinkParamSetToBeUpdated = 0x00;
328         instHandle->rcvObj.loopjobUpdatedinParamset = FALSE;
329         instHandle->rcvObj.roundedWordWidth = 0x00;
331 #ifdef MCBSP_LOOPJOB_ENABLE
332         /* driver is compiled in loop Job mode                                */
333         instHandle->loopJobMode = TRUE;
334 #else
335         instHandle->loopJobMode = FALSE;
336 #endif
338         for (count = 0; count < Mcbsp_MAXLINKCNT; count++)
339         {
340             instHandle->xmtObj.pramTbl[count] = 0x00;
341             instHandle->rcvObj.pramTbl[count] = 0x00;
342             instHandle->xmtObj.pramTblAddr[count] = 0x00;
343             instHandle->rcvObj.pramTblAddr[count] = 0x00;
344         }
346         /* set the status of the channel to closed                            */
347         instHandle->xmtObj.chanState = Mcbsp_DriverState_CLOSED;
348         instHandle->rcvObj.chanState = Mcbsp_DriverState_CLOSED;
350         /* Pending and Floating queues for TX and RX channels */
351         instHandle->xmtObj.ptrQPendList  = params->txQPendingList;
352         instHandle->xmtObj.ptrQFloatList = params->txQFloatingList;
353         instHandle->rcvObj.ptrQPendList  = params->rxQPendingList;
354         instHandle->rcvObj.ptrQFloatList = params->rxQFloatingList;
356         if (MCBSP_STATUS_COMPLETED == status)
357         {
358             /* Reset the McBSP Transmitter, receiver and SRGR before          *
359              * configuration                                                  */
360             ctrlMask = ((Mcbsp_SpcrCtrl_TX_DISABLE | 
361                          Mcbsp_SpcrCtrl_RX_DISABLE) |
362                        (Mcbsp_SpcrCtrl_SRG_DISABLE | 
363                         Mcbsp_SpcrCtrl_FSYNC_DISABLE));
365             status = Mcbsp_localResetCtrl(instHandle,ctrlMask);
366             if (MCBSP_STATUS_COMPLETED != status)
367             {
368                 /* Writeback Global Object */
369                 Mcbsp_osalEndMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
370                 Mcbsp_osalEndMemAccess ((void *)Mcbsp_deviceInstInfo, sizeof(Mcbsp_deviceInstInfo));
372                 /* End Critical Section */
373                 Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
375                 return status;
376             }
378             /* copy the configuration for the sample rate generator and config*
379              * the emulation mode and DLB mode settings                       */
381             /* Configure the McBSP with user supplied parameters              */
382             instHandle->srgrConfig = *(params->srgSetup);
384             /* reset the Mcbsp                                                */
385             instHandle->hwInfo.regs->SPCR = 0x00u;
387             /* set the DLB mode settings                                      */
388             instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_DLB_MASK);
389             instHandle->hwInfo.regs->SPCR |=
390                 (params->dlbMode << CSL_MCBSP_SPCR_DLB_SHIFT);
392             /* set the clock stop mode settings                               */
393             instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_CLKSTP_MASK);
395             /* set the emulation state                                        */
396             instHandle->hwInfo.regs->SPCR &= (~(CSL_MCBSP_SPCR_SOFT_MASK |
397                                                 CSL_MCBSP_SPCR_FREE_MASK));
398             instHandle->hwInfo.regs->SPCR |=
399                 (params->emulationMode << CSL_MCBSP_SPCR_SOFT_SHIFT);
400         }
402         if (MCBSP_STATUS_COMPLETED != status)
403         {
404             *devp = NULL;
405         }
406         else
407         {
408             *devp = &(Mcbsp_Instances[devid]);
410             /* set the status of the driver to created                        */
411             instHandle->devState = Mcbsp_DriverState_CREATED;
412         }
413     }
415     /* Writeback Global Object */
416     Mcbsp_osalEndMemAccess ((void *)Mcbsp_Instances, sizeof(Mcbsp_Instances));
417     Mcbsp_osalEndMemAccess ((void *)Mcbsp_deviceInstInfo, sizeof(Mcbsp_deviceInstInfo));
419     /* End Critical Section */
420     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
422     return status;
425 /**
426  *  \brief  Creates a communication channel in specified mode to communicate
427  *          data between the application and the McBSP device instance. This
428  *          function sets the required hardware configurations for the data
429  *          transactions. It returns configured channel handle to application
430  *          which will be used in all further transactions with the channel.
431  *
432  *          Pre-requisites:
433  *          1.  Valid chanParams structure
434  *              This takes much information pertaining to mcbsp channel
435  *              configuration such as how many slots are used for this
436  *              channel what are their communication parameters, clock settings etc.
437  *          2.  Valid device pointer
438  *
439  * \param   chanp        [IN]     Channel Handler
440  * \param   devp         [IN]     Device pointer
441  * \param   mode         [IN]     channel  mode -> input or output
442  * \param   chanParams   [IN]     channel parameters from user
443  * \param   cbFxn        [IN]     callback function pointer
444  * \param   cbArg        [IN]     callback function Arguments
445  *
446  * \return  MCBSP_STATUS_COMPLETED     if successful
447  *          MCBSP_ERR_BADIO        if not successful
448  *          MCBSP_ERR_ALLOC            "
449  *          MCBSP_ERR_BADARGS      if passed invalid chanParams structure
450  */
451 int32_t mcbspCreateChan(void*            *chanp,
452                        void*              devp,
453                        int32_t            mode,
454                        void*              chanParams,
455                        Mcbsp_CallbackFxn  cbFxn,
456                        void*              cbArg)
458     Mcbsp_Object *hInst = NULL;
459     Mcbsp_Object_Unpadded *instHandle = NULL;
460     Mcbsp_ChannelObj    *chanHandle = NULL;
461     Mcbsp_ChanParams    *chanparam  = NULL;
462     void*                criticalSectionInfo;
463     int32_t              status     = MCBSP_STATUS_COMPLETED;
465 /* Begin parameter checking                                                   */
466 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
467     if (((NULL == chanParams)
468         || (NULL == cbFxn)
469         || (NULL == cbArg)
470         || (NULL == devp))
471         || ((MCBSP_MODE_INPUT != mode) && (MCBSP_MODE_OUTPUT != mode)))
472     {
473         return MCBSP_ERR_BADARGS;
474     }
475     else
476     {
477 #endif
478         chanparam = (Mcbsp_ChanParams *)chanParams;
479 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
480         if (NULL == chanparam->edmaHandle)
481         {
482             return MCBSP_ERR_BADARGS;
483         }
484     }
485 #endif  /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
486 /* End parameter checking                                                     */
488     /* Begin Critical Section before accessing shared resources. */
489     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
491     /* Invalidate the Cache Contents */
492     Mcbsp_osalBeginMemAccess ((void *)devp, sizeof(Mcbsp_Object));
494     if (MCBSP_STATUS_COMPLETED == status)
495     {
496         hInst = (Mcbsp_Object *)devp;
497         instHandle = (Mcbsp_Object_Unpadded *)&(hInst->obj);
499         /* get the pointer to the required channel structure              */
500         if (MCBSP_MODE_INPUT == mode)
501         {
502             chanHandle = &instHandle->rcvObj;
503         }
504         else
505         {
506             chanHandle = &instHandle->xmtObj;
507         }
509         /* we will check if the current requested channel is availablehere*
510          * protect the channel status so that multiple threads requesting *
511          * same channel do not cause a corruption                         */
512         if (Mcbsp_DriverState_CLOSED == chanHandle->chanState)
513         {
514             chanHandle->chanState = Mcbsp_DriverState_OPENED;
515         }
516         else
517         {
518             /* Requested channel is already taken hence we will set status*
519              * as invalid                                                 */
520             status = MCBSP_ERR_BADMODE;
521         }
523         if (MCBSP_STATUS_COMPLETED == status)
524         {
525             chanHandle->mode = (uint16_t)mode;
526             chanHandle->devHandle = hInst;
528             /* Assign the respective callback function                        */
529             chanHandle->cbFxn = cbFxn;
530             chanHandle->cbArg = cbArg;
532             /* This is used in EDMA mode to populate paramsets in PINGPONG    */
533             chanHandle->nextLinkParamSetToBeUpdated = 0;
535             /* Initialize Mute parameter                                      */
536             chanHandle->bMuteON = FALSE;
538             chanHandle->isTempIOBufValid = FALSE;
540             /* Counter that counts outstanding requests of this channel       */
541             chanHandle->submitCount = 0;
543             /* Global error callback registered to channel                    */
544             chanHandle->gblErrCbk = chanparam->gblCbk;
546             /* copy the edma event queue details                              */
547             chanHandle->edmaEventQue = chanparam->edmaEventQue;
549             /* store the EDMA3 module handle                                  */
550             chanHandle->edmaHandle = chanparam->edmaHandle;
552             /* configure the FIFO                                             */
553             chanHandle->enableHwFifo = chanparam->enableHwFifo;
555             /* copy the user settings in to the channel object                */
556             chanHandle->chanConfig = *(chanparam->chanConfig);
557             chanHandle->clkSetup   = *(chanparam->clkSetup);
558             chanHandle->numEnabledChannels = chanparam->numEnabledChannels;
559             chanHandle->dataFormat = chanparam->dataFormat;
560         }
562         if (MCBSP_STATUS_COMPLETED == status)
563         {
564             /* configure the actual wordwidth to be used                      */
565             switch (chanparam->wordWidth)
566             {
567                 case Mcbsp_WordLength_8:
568                     chanHandle->roundedWordWidth = 1u;
569                     break;
570                 case Mcbsp_WordLength_12:
571                 case Mcbsp_WordLength_16:
572                     chanHandle->roundedWordWidth = 2u;
573                     break;
574                 case Mcbsp_WordLength_20:
575                 case Mcbsp_WordLength_24:
576                     chanHandle->roundedWordWidth = 3u;
577                     break;
578                 case Mcbsp_WordLength_32:
579                 default:
580                     chanHandle->roundedWordWidth = 4u;
581                     break;
582             }
584 #ifdef  MCBSP_LOOPJOB_ENABLE
585             /* Configure the loop job for the user specified buffer if given  */
586             if (NULL == chanparam->userLoopJobBuffer)
587             {
588                 if (MCBSP_MODE_INPUT == chanHandle->mode)
589                 {
590                     chanHandle->loopJobBuffer =
591                         Mcbsp_loopDstBuf[instHandle->instNum].scratchBuffer;
592                 }
593                 else
594                 {
595                     chanHandle->loopJobBuffer =
596                         Mcbsp_loopSrcBuf[instHandle->instNum].scratchBuffer;
597                 }
598                 chanHandle->loopJobLength = chanHandle->roundedWordWidth;
599             }
600             else
601             {
602                 /* Apps has preference on the loopjob buffer & lets use it    */
603                 chanHandle->loopJobBuffer = chanparam->userLoopJobBuffer;
604                 chanHandle->userLoopJobLength = chanparam->userLoopJobLength;
606                 /* user loopJob is being used                                 */
607                 chanHandle->userLoopJob = TRUE;
608                 if (chanHandle->roundedWordWidth >
609                         chanparam->userLoopJobLength)
610                 {
611                     /* not enough loopjob buffer has been provided  we        *
612                      * should have at least loopbuffer for 1 sync event       */
613                     status = MCBSP_ERR_BADARGS;
614                 }
615             }
616 #endif
617         }
619         if ((Mcbsp_DevMode_McBSP == instHandle->mode) && (MCBSP_STATUS_COMPLETED == status))
620         {
621             if (MCBSP_MODE_INPUT == chanHandle->mode)
622             {
623                 /* Assign the Channel ID and TCC                              */
624                 chanHandle->xferChan     = instHandle->hwInfo.edmaRxEventNum;
625                 chanHandle->tcc          = instHandle->hwInfo.edmaRxEventNum;
626                 chanHandle->edmaCallback =
627                     (EDMA3_RM_TccCallback)&Mcbsp_localEdmaCallback;
628             }
629             else
630             {
631                 /* Assign the Channel ID and TCC                              */
632                 chanHandle->xferChan     = instHandle->hwInfo.edmaTxEventNum;
633                 chanHandle->tcc          = instHandle->hwInfo.edmaTxEventNum;
634                 chanHandle->edmaCallback =
635                     (EDMA3_RM_TccCallback)&Mcbsp_localEdmaCallback;
636             }
638             if (MCBSP_STATUS_COMPLETED == status)
639             {
640                 mcbspConfigureFifo(&(instHandle->hwInfo),
641                     chanHandle,
642                     chanHandle->enableHwFifo);
643             }
645             if (MCBSP_MODE_INPUT == chanHandle->mode)
646             {
647                 /* configure the RX section                                   */
648                 status = Mcbsp_localConfigureRcvChannel(instHandle,chanparam);
649             }
650             else
651             {
652                 /* configure the TX section                                   */
653                 status = Mcbsp_localConfigureXmtChannel(instHandle,chanparam);
654             }
656             if (MCBSP_STATUS_COMPLETED == status)
657             {
658                 /* configure the sample rate generator                        */
659                 status = Mcbsp_localConfigureSrgr(instHandle,chanHandle);
660             }
661             
662             if (MCBSP_STATUS_COMPLETED == status)
663             {
664                 /* enable the internal sample rate generator if required      */
665                 if (((MCBSP_MODE_INPUT == chanHandle->mode) &&
666                     (TRUE == instHandle->rxSrgEnable)) ||
667                     ((MCBSP_MODE_OUTPUT == chanHandle->mode) &&
668                     (TRUE == instHandle->txSrgEnable)))
669                 {
670                     /* enable the sample rate generator                       */
671                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_SRG_ENABLE);
672                     instHandle->srgEnabled = TRUE;
674                     /* wait for the 2CLKG clock cycles                        */
675                     Mcbsp_osalWaitNBitClocks(2u);
676                 }
677             
678                 /* clear the XSYNCERR (to be done only if TX is used)         */
679                 if (MCBSP_MODE_OUTPUT == chanHandle->mode)
680                 {
681                     /* Enable the TX section                                  */
682                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
684                     /* wait for 2 CLKR or CLX cycles                          */
685                     Mcbsp_osalWaitNBitClocks(2u);
687                     /* Disable the TX section to clear any XYNCERR            */
688                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_DISABLE);
689                 }
691                 /* complete the EDMA setup for the driver                     */
692                 status =  Mcbsp_localSetupEdmaDuringOpen(chanHandle);
693             }
695 #ifdef MCBSP_LOOPJOB_ENABLE
696             if (MCBSP_STATUS_COMPLETED == status)
697             {
698                                         /* configure the FIFO for the specific channel                        */
699                 if (TRUE == chanHandle->enableHwFifo)
700                 {
701                     /* Disable and enable the FIFO so that the events are             *
702                      * generated to the Mcbsp for the first time                      */
703                     mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,FALSE);
704                     mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,TRUE);
705                 }
707                 /* enable the EDMA transfer for the channel so that it is     *
708                  * ready to transfer the data as soon as the state machine is *
709                  * enabled                                                    */
710                 EDMA3_DRV_enableTransfer(
711                     chanHandle->edmaHandle,
712                     chanHandle->xferChan,
713                     EDMA3_DRV_TRIG_MODE_EVENT);
715                 /* Start the McBSP hardware                                   */
716                 if (MCBSP_MODE_INPUT == chanHandle->mode)
717                 {
718                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_ENABLE);
719                 }
720                 else
721                 {
722                     Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
723                 }
725                 if (MCBSP_MODE_INPUT == chanHandle->mode)
726                 {
727                     if (TRUE == instHandle->rxFsgEnable)
728                     {
729                         /* enable the sample rate generator                   */
730                         Mcbsp_localResetCtrl(
731                             instHandle,
732                             Mcbsp_SpcrCtrl_FSYNC_ENABLE);
733                     }
734                 }
735                 else
736                 {
737                     if (TRUE == instHandle->txFsgEnable)
738                     {
739                         /* enable the sample rate generator                   */
740                         Mcbsp_localResetCtrl(
741                             instHandle,
742                             Mcbsp_SpcrCtrl_FSYNC_ENABLE);
743                     }
744                 }
746                 /* State machine stop status                                  */
747                 if (MCBSP_MODE_INPUT == chanHandle->mode)
748                 {
749                     instHandle->stopSmFsRcv = FALSE;
750                 }
751                 else
752                 {
753                     instHandle->stopSmFsXmt = FALSE;
754                 }
755             }
756 #endif
757         }
758     }
760     if (MCBSP_STATUS_COMPLETED != status )
761     {
762         if (NULL != chanHandle)
763         {
764             /* set the status of the channel to closed                        */
765             chanHandle->mode = (uint16_t)Mcbsp_DriverState_CLOSED;
766         }
768         /* channel opening for transaction has failed                         */
769         chanHandle = NULL;
770     }
771     else
772     {
773         *chanp = chanHandle;
774     }
776     /* Writeback Global Object */
777     Mcbsp_osalEndMemAccess ((void *)devp, sizeof(Mcbsp_Object));
779     /* End Critical Section */
780     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
782     return status;
785 /**
786  * \brief   frees a channel and all it's associated resources.
787  *
788  *          Frees the EDMA resources including EDMA master channel and link
789  *          PaRAM entries held by the channel.it also unregisters all the
790  *          interrupt handlers.
791  *
792  * \param   chanp  [IN]       Handle to the channel
793  *
794  * \return  MCBSP_STATUS_COMPLETED     if successful
795  *          MCBSP_STATUS_ABORTED       if not successful
796  *
797  * \enter   chanp       should be non NULL and valid pointer,
798  *
799  * \leave   Not implemented
800  */
801 int32_t mcbspDeleteChan(void* chanp)
803     Mcbsp_Object_Unpadded *instHandle = NULL;
804     Mcbsp_ChannelObj *chanHandle = NULL;
805     Uint8    linkCnt = 0;
806     uint32_t timeOut = 0x00;
807     int32_t  status  = MCBSP_STATUS_COMPLETED;
808     void *criticalSectionInfo;
810     /* Begin Critical Section before accessing shared resources. */
811     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
813 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
814     if (NULL == chanp)
815     {
816         status = MCBSP_ERR_BADARGS;
817     }
818     else
819     {
820 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
821         chanHandle = (Mcbsp_ChannelObj *)chanp;
823         /* Invalidate the Cache Contents */
824         Mcbsp_osalBeginMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
826 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
827         if (Mcbsp_DriverState_OPENED != chanHandle->chanState)
828         {
829             status = MCBSP_ERR_BADMODE;
830         }
831         else
832         {
833             if (NULL == chanHandle->devHandle)
834             {
835                 status = MCBSP_ERR_BADARGS;
836             }
837             else
838             {
839 #endif
840                 instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
842 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
843                 if (NULL == instHandle)
844                 {
845                     status = MCBSP_ERR_BADARGS;
846                 }
847             }
848         }
849     }
850 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
852     if (MCBSP_STATUS_COMPLETED == status)
853     {
854         /* reset the channel              .                               */
855         Mcbsp_localAbortReset(chanHandle);
857         /* Disable the current transfer to make sure that there is no     *
858          * running EDMA transfer taking place                             */
859         status = EDMA3_DRV_disableTransfer(
860                      chanHandle->edmaHandle,
861                      chanHandle->xferChan,
862                      EDMA3_DRV_TRIG_MODE_EVENT);
864         /* Disable current EDMA transfer                                  */
865         if (MCBSP_STATUS_COMPLETED == status)
866         {
867             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
868             {
869                 timeOut = instHandle->retryCount;
871                 /* Poll for TXEMPTY                                       */
872                 while ((CSL_MCBSP_SPCR_XEMPTY_MASK ==
873                     (CSL_MCBSP_SPCR_XEMPTY_MASK & instHandle->hwInfo.regs->SPCR))
874                     && (0 != timeOut))
875                 {
876                     timeOut--;
877                 }
878             }
880             /* Reset McBSP before freeing the edma channels               */
881             if (MCBSP_MODE_INPUT == chanHandle->mode)
882             {
883                 Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_DISABLE);
884             }
885             else
886             {
887                 Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_DISABLE);
888             }
890             /* Free Edma channels                                         */
891             status = EDMA3_DRV_freeChannel(
892                          chanHandle->edmaHandle,
893                          chanHandle->xferChan);
894 #ifndef MCBSP_LOOPJOB_ENABLE
896             /* free the already allocated dummy PaRAM entries         */
897             EDMA3_DRV_freeChannel(chanHandle->edmaHandle,
898                           Mcbsp_edmaChanNum);
899 #endif
900                          
901             if (MCBSP_STATUS_COMPLETED ==  status)
902             {
903                 /* free the EDMA PaRAM entries used for Ping pong buffer  */
904                 for (linkCnt = 0; linkCnt < Mcbsp_MAXLINKCNT; linkCnt++)
905                 {
906                     status = EDMA3_DRV_freeChannel(
907                                  chanHandle->edmaHandle,
908                                  chanHandle->pramTbl[linkCnt]);
909                     if (MCBSP_STATUS_COMPLETED != status)
910                     {
911                         break;
912                     }
913                 }
914             }
916             if (MCBSP_STATUS_COMPLETED == status)
917             {
918                 /* Set the state of the channel as closed                 */
919                 chanHandle->chanState = Mcbsp_DriverState_CLOSED;
921                 /* Set the Muted state to FALSE                           */
922                 chanHandle->bMuteON   = FALSE;
924                 /* Set the Paused state to FALSE                          */
925                 chanHandle->paused    = FALSE;
926             }
927         }
929         /* Writeback Global Object */
930         Mcbsp_osalEndMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
931     }
933     /* End Critical Section */
934     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
936     return (status);
939 /**
940  * \brief   Closes the McBSP device instance from use.
941  *          This API is called by the application when it no longer requires the
942  *          device instance. Note that all the channels have to be closed for
943  *          the device instance to be deleted sucessfully.
944  *
945  * \param   devp    [IN]  Handle to the device created.
946  *
947  * \return  MCBSP_STATUS_COMPLETED     if successful
948  *          MCBSP_STATUS_ABORTED       if not successful
949  *
950  * \enter   devp       should be non NULL and valid pointer,
951  *
952  * \leave   Not implemented
953  */
954 int32_t mcbspUnBindDev(void* devp)
956     Mcbsp_Object *hInst = NULL;
957     Mcbsp_Object_Unpadded *instHandle = NULL;
958     int32_t status = MCBSP_STATUS_COMPLETED;
959     void* criticalSectionInfo;
961     /* Begin Critical Section before accessing shared resources. */
962     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection ();
964 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
965     if (NULL == devp)
966     {
967         status = MCBSP_ERR_BADARGS;
968     }
969     else
970     {
971 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
973         hInst = (Mcbsp_Object *)devp;
975         /* Invalidate the Cache Contents */
976         Mcbsp_osalBeginMemAccess ((void *)hInst, sizeof(Mcbsp_Object));
978         instHandle = (Mcbsp_Object_Unpadded *)&(hInst->obj);
980 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
981         if ((CSL_MCBSP_PER_CNT <= instHandle->instNum)                  ||
982             (Mcbsp_DriverState_CLOSED != instHandle->xmtObj.chanState)  ||
983             (Mcbsp_DriverState_CLOSED != instHandle->rcvObj.chanState))
984         {
985             status = MCBSP_ERR_BADARGS;
986         }
987     }
988 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
990     if (MCBSP_STATUS_COMPLETED == status)
991     {
992         /* reset the Mcbsp                                                */
993         instHandle->hwInfo.regs->SPCR = 0x00u;
995         /* Mark driver state as deleted and module as not in use              */
996         instHandle->devState = Mcbsp_DriverState_DELETED;
997         instHandle->inUse = FALSE;
999         /* update the user params to the instance object                      */
1000         instHandle->instNum = -1;
1002         /* Intialize the mcbsp driver to default values                       */
1003         memset(instHandle, 0, sizeof(Mcbsp_Object_Unpadded));
1005         /* Writeback Global Object */
1006         Mcbsp_osalEndMemAccess ((void *)hInst, sizeof(Mcbsp_Object));
1007     }
1009     /* End Critical Section */
1010     Mcbsp_osalExitMultipleCoreCriticalSection (criticalSectionInfo);
1012     return status;
1015 /**
1016  * \brief   Submit a I/O buffer to a channel for processing
1017  *
1018  *  The application calls this function to cause the driver
1019  *  to process the Mcbsp_IOBuf for read/write/flush/abort operations.
1020  *
1021  * \param   chanp         [IN]    Pointer to channel
1022  * \param   ioBuf         [IN]    Pointer to buffer to be submitted
1023  *
1024  * \return  MCBSP_STATUS_COMPLETED, if buffer is fully processed
1025  *          MCBSP_STATUS_ABORTED,   if buffer is aborted
1026  *          MCBSP_STATUS_PENDING,   if buffer is not fully processed
1027  *          MCBSP_ERR_BADIO     in case of an error in processing
1028  *
1029  */
1030 int32_t mcbspSubmitChan(void* chanp, Mcbsp_IOBuf *const ioBuf)
1032     Mcbsp_Object_Unpadded *instHandle = NULL;
1033     Mcbsp_ChannelObj      *chanHandle = NULL;
1034     int32_t                status     = MCBSP_STATUS_COMPLETED;
1036 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1037     if ((NULL == chanp) || ( NULL == ioBuf))
1038     {
1039         status = MCBSP_ERR_BADARGS;
1040     }
1041     else
1042     {
1043 #endif
1044         chanHandle = (Mcbsp_ChannelObj *)chanp;
1046 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1048         if ((NULL == chanHandle) || (NULL == chanHandle->devHandle))
1049         {
1050             status = MCBSP_ERR_BADARGS;
1051         }
1052         else
1053         {
1054 #endif
1055             instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1056 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1057             if (NULL == instHandle)
1058             {
1059                 status = MCBSP_ERR_BADARGS;
1060             }
1061             else
1062             {
1063                 if (NULL == ioBuf->addr)
1064                 {
1065                     if ((Mcbsp_IOBuf_Cmd_READ == ioBuf->cmd) ||
1066                         (Mcbsp_IOBuf_Cmd_WRITE == ioBuf->cmd))
1067                     {
1068                         status = MCBSP_ERR_BADARGS;
1069                     }
1070                 }
1071             }
1072         }
1073     }
1074 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
1076     if (MCBSP_STATUS_COMPLETED == status)
1077     {
1078         /* process the command sent by the application                        */
1079         switch (ioBuf->cmd)
1080         {
1081             case Mcbsp_IOBuf_Cmd_READ:
1082             case Mcbsp_IOBuf_Cmd_WRITE:
1083                 if (TRUE != chanHandle->flush)
1084                 {
1085                     status = mcbspSubmitReq(instHandle,chanHandle,ioBuf);
1086                 }
1087                 else
1088                 {
1089                     status = MCBSP_ERR_BADIO;
1090                 }
1091                 break;
1092             case Mcbsp_IOBuf_Cmd_FLUSH:
1093                 /* Flush command has been issued need to abort the receive    *
1094                  * channel buffers and complete the TX buffers normally       */
1095                 chanHandle->flush = TRUE;
1096                 Mcbsp_localAbortReset(chanHandle);
1097                 chanHandle->flush = FALSE;
1098                 break;
1099             case Mcbsp_IOBuf_Cmd_ABORT:
1100                 Mcbsp_localAbortReset(chanHandle);
1101                 break;
1102             default:
1103                 status = MCBSP_ERR_BADIO;
1104                 break;
1105         }
1106     }
1108     return status;
1111 /**
1112  * \brief   Implements the IOCTLS for McBSP driver.
1113  *
1114  *          ControlChan() implements recieved IOCTL commands from the
1115  *          application and executes them accordingly.
1116  *
1117  * \param   chanp  [IN]    Pointer to channel
1118  * \param   cmd    [IN]    specific IOCTL command
1119  * \param   arg    [IN]    arguments required for specific commands
1120  *
1121  * \return  MCBSP_STATUS_COMPLETED, if command is executed correctly
1122  *          MCBSP_STATUS_ABORTED,   if command returns error during execution
1123  *          MCBSP_ERR_NOTIMPL,  if command is not supported
1124  *          MCBSP_ERR_BADARGS   if args are not correct
1125  */
1126 int32_t mcbspControlChan(void* chanp, Mcbsp_IOCTL cmd, void* arg)
1128     Mcbsp_ChannelObj *chanHandle = NULL;
1129     int32_t status = MCBSP_STATUS_COMPLETED;
1131 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1132     if (NULL == chanp)
1133     {
1134         status = MCBSP_ERR_BADARGS;
1135     }
1136     else
1137     {
1138 #endif /* MCBSP_DISABLE_INPUT_PARAM_CHECK */
1140         chanHandle = (Mcbsp_ChannelObj *)chanp;
1142         /* Invalidate the Cache Contents */
1143         Mcbsp_osalBeginMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
1145 #ifndef MCBSP_DISABLE_INPUT_PARAM_CHECK
1146         if (NULL == chanHandle->devHandle)
1147         {
1148             status = MCBSP_ERR_BADARGS;
1149         }
1150     }
1151 #endif
1152         
1153     if (MCBSP_STATUS_COMPLETED == status)
1154     {
1155         /* call the function to process the IOCTL command                 */
1156         status =  Mcbsp_localSubmitIoctl(
1157                         chanHandle,
1158                         cmd,
1159                         arg,
1160                         NULL);
1161     }
1163     /* Writeback Global Object */
1164     Mcbsp_osalEndMemAccess ((void *)chanHandle->devHandle, sizeof(Mcbsp_Object));
1166     return (status);
1169 /**
1170  * \brief   McBSP Tx ISR function
1171  *
1172  *          This Function is the interrupt service routine for the Mcbsp TX
1173  *          event.
1174  *
1175  * \param   hChan  [IN]  Handle to the channel
1176  *
1177  * \return  None
1178  */
1179 void mcbspGblXmtIsr(void *hChan)
1181     Mcbsp_Object_Unpadded *instHandle = NULL;
1182     Mcbsp_ChannelObj *chanHandle = (Mcbsp_ChannelObj *)hChan;
1184     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1186     /* Only DMA mode of operation is supported by the Mcbsp driver hence we   *
1187      * will only check if there is an sync error and notify the application   */
1188     if (CSL_MCBSP_SPCR_XSYNCERR_MASK ==
1189         (CSL_MCBSP_SPCR_XSYNCERR_MASK & instHandle->hwInfo.regs->SPCR))
1190     {
1191         /* call the application registered global callback function           */
1192         if (NULL != chanHandle->gblErrCbk)
1193         {
1194             (*chanHandle->gblErrCbk)((uint32_t)chanHandle,
1195                 instHandle->hwInfo.regs->SPCR,
1196                 NULL);
1197         }
1198     }
1200     return;
1203 /**
1204  * \brief   McBSP Rx ISR function
1205  *
1206  *          This Function is the interrupt service routine for the Mcbsp RX
1207  *          event.
1208  *
1209  * \param   hChan  [IN]  Handle to the channel
1210  *
1211  * \return  None
1212  */
1213 void mcbspGblRcvIsr(void *hChan)
1215     Mcbsp_Object_Unpadded *instHandle = NULL;
1216     Mcbsp_ChannelObj *chanHandle = (Mcbsp_ChannelObj *)hChan;
1218     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1220     /* Only DMA mode of operation is supported by the Mcbsp driver hence we   *
1221      * will only check if there is an sync error and notify the application   */
1222     if (CSL_MCBSP_SPCR_RSYNCERR_MASK ==
1223         (CSL_MCBSP_SPCR_RSYNCERR_MASK & instHandle->hwInfo.regs->SPCR))
1224     {
1225         /* call the application registered global callback function           */
1226         if (NULL != chanHandle->gblErrCbk)
1227         {
1228             (*chanHandle->gblErrCbk)((uint32_t)chanHandle,
1229                 instHandle->hwInfo.regs->SPCR,
1230                 NULL);
1231         }
1232     }
1234     return;
1237 /*============================================================================*/
1238 /*                          LOCAL FUNCTION DEFINTIONS                         */
1239 /*============================================================================*/
1241 /**
1242  *  \brief   Submit a I/O buffer to a channel for processing
1243  *
1244  *   This function is called with the Mcbsp_IOBuf_Cmd_READ or Mcbsp_IOBuf_Cmd_WRITE  
1245  *   command to process the IOP. The function handles the MCBSP mode. In case
1246  *   that the driver is currently idle it sets up buffer for transfer. In case
1247  *   that the driver is currently processing a buffer then it will queue up the
1248  *   current buffer and exit.
1249  *
1250  * \param   instHandle  [IN]  pointer to the instance object
1251  * \param   chanHandle  [IN] handle to the channel
1252  * \param   ioBuf       [IN] pointer to Mcbsp I/O buffer.
1253  *
1254  * \return  MCBSP_STATUS_PENDING in case the buffer is sucesfully processed
1255  *          MCBSP_ERR_BADIO  in case of any error.
1256  */
1257 int32_t mcbspSubmitReq(Mcbsp_Object_Unpadded *instHandle,
1258                        Mcbsp_ChannelObj *chanHandle,
1259                        Mcbsp_IOBuf      *ioBuf)
1261     void*           criticalSectionInfo;
1262     int32_t         status = MCBSP_STATUS_COMPLETED;
1264     if ((NULL == chanHandle) || (NULL == ioBuf) || (NULL == instHandle))
1265     {
1266         return MCBSP_ERR_BADIO;
1267     }
1268     if((0 == ioBuf->size) || (ioBuf->size > Mcbsp_MAX_IOBUF_SIZE))
1269     {
1270         return MCBSP_ERR_BADIO;
1271     }
1273     /* clean the buffers if the cache operation mode is enabled               */
1274     if (TRUE == instHandle->enablecache)
1275     {
1276         if (MCBSP_MODE_INPUT == chanHandle->mode)
1277         {
1278             /* Invalidate the cache */
1279             Mcbsp_osalBeginMemAccess(ioBuf->addr, ioBuf->size);
1280         }
1281         else
1282         {
1283             /* Writeback the cache */
1284             Mcbsp_osalEndMemAccess(ioBuf->addr, ioBuf->size);
1285         }
1286     }
1288     /*==========================MCBSP MODE ===================================*/
1289     if (Mcbsp_DevMode_McBSP == instHandle->mode)
1290     {
1291         /* We are entering the crictical section because the current active   *
1292          * IOP is being check and it can become NULL at any point. Hence we   *
1293          * will protect this code from the interrupt handler.                 */
1294         criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
1296 #ifdef MCBSP_LOOPJOB_ENABLE
1297         if ((Mcbsp_MAXLINKCNT <= chanHandle->submitCount) ||
1298 #else
1299         /* We now have 3 buffers loaded in the EDMA                           */
1300         if (((Mcbsp_MAXLINKCNT + 1) <= chanHandle->submitCount) ||
1301 #endif
1302             (TRUE == chanHandle->paused))
1303         {
1304             /* There are enough buffers programmed in the EDMA or if the MCBSP*
1305              * is issued a pause command,hence queue buffer in to the pending *
1306              * queue                                                          */
1307             chanHandle->submitCount++;
1309             Mcbsp_osalQueuePut(chanHandle->ptrQPendList,(void*)ioBuf);
1311             /* critical section ends                                          */
1312             Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1313         }
1314         else
1315         {
1316             /* Either one of the paramset or Both the paramsets are free      */
1318             /* increment the submit count                                     */
1319             chanHandle->submitCount++;
1321             Mcbsp_osalQueuePut(chanHandle->ptrQFloatList, (void*)ioBuf);
1323             Mcbsp_localLoadPktToEdma(chanHandle,ioBuf);
1325             /* critical section ends                                          */
1326             Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1328         } /* Pending queue empty or not*/
1329     }
1330     if (MCBSP_STATUS_COMPLETED == status)
1331     {
1332         status = MCBSP_STATUS_PENDING;
1333     }
1334     return (status);
1337 /**
1338  * \brief   McBSP SPCR configuration function
1339  *
1340  *  This Function is used to set/reset specific bit of SPCR as specified in
1341  *  the given mask.
1342  *
1343  * \param   instHandle   [IN]  pointer to the mcbsp instance object.
1344  * \param   selectMask   [IN]  the SPCR control mask
1345  *
1346  * \return  MCBSP_STATUS_COMPLETED     if successful
1347  *
1348  *          MCBSP_ERR_BADARGS          if not successful
1349  */
1350 int32_t Mcbsp_localResetCtrl(Mcbsp_Object_Unpadded *instHandle, uint32_t selectMask)
1352     if ((NULL == instHandle) || (NULL == instHandle->hwInfo.regs))
1353     {
1354         return MCBSP_ERR_BADARGS;
1355     }
1357     /* Configuring SPCR for Frame sync generator enable/disable               */
1358     if (0u != (selectMask & Mcbsp_SpcrCtrl_FSYNC_DISABLE))
1359     {
1360         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_FRST_MASK );
1361     }
1363     if (0 != (selectMask & Mcbsp_SpcrCtrl_RX_DISABLE))
1364     {
1365         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_RRST_MASK );
1366     }
1368     /* start the sample rate generator                                        */
1369     if (0u != (selectMask & Mcbsp_SpcrCtrl_SRG_ENABLE))
1370     {
1371         instHandle->hwInfo.regs->SPCR |=  CSL_MCBSP_SPCR_GRST_MASK;
1372     }
1374     /* Configuring SPCR for Transmit enable/disable                           */
1375     if (0 != (selectMask & Mcbsp_SpcrCtrl_TX_DISABLE))
1376     {
1377         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_XRST_MASK);
1378     }
1380     /* Configuring SPCR for transmit section enable                           */
1381     if (0 != (selectMask & Mcbsp_SpcrCtrl_TX_ENABLE))
1382     {
1383         instHandle->hwInfo.regs->SPCR |= CSL_MCBSP_SPCR_XRST_MASK;
1384     }
1386     /* Configuring SPCR for Receive section enable                            */
1387     if (0 != (selectMask & Mcbsp_SpcrCtrl_RX_ENABLE))
1388     {
1389         instHandle->hwInfo.regs->SPCR |= CSL_MCBSP_SPCR_RRST_MASK ;
1390     }
1392     /* Set the FRST bit to 1 to start the internal frame sync generator       */
1393     if (0u != (selectMask & Mcbsp_SpcrCtrl_FSYNC_ENABLE))
1394     {
1395         instHandle->hwInfo.regs->SPCR |=  CSL_MCBSP_SPCR_FRST_MASK;
1396     }
1398     /* Configuring SPCR for sample rate generator enable/disable              */
1399     if (0u != (selectMask & Mcbsp_SpcrCtrl_SRG_DISABLE))
1400     {
1401         instHandle->hwInfo.regs->SPCR &=  (~CSL_MCBSP_SPCR_GRST_MASK);
1402     }
1404     return MCBSP_STATUS_COMPLETED;
1407 /**
1408  *  \brief   This function completes the current pending request and then
1409  *           invokes the application registered callback.
1410  *
1411  *  \param   chanHandle   [IN]  Handle to the channel
1412  *
1413  *  \return  None
1414  *
1415  *  \enter   chanHandle  is a valid non null pointer
1416  *
1417  *  \leave   Not implemented
1418  */
1419 void Mcbsp_localCompleteCurrentIo(Mcbsp_ChannelObj *chanHandle)
1421     Mcbsp_IOBuf   *ioBuf = NULL;
1423     if (TRUE == chanHandle->isTempIOBufValid)
1424     {
1425         ioBuf = chanHandle->tempIOBuf;
1427         chanHandle->tempIOBuf = NULL;
1428         chanHandle->isTempIOBufValid = FALSE;
1429         /* call the completion callback function registered with us           *
1430          * during channel creation                                            */
1431         if ((NULL != chanHandle->cbFxn) && (NULL != chanHandle->cbArg))
1432         {
1433             /*  Application callback                                          */
1434             (*chanHandle->cbFxn)((void*)chanHandle->cbArg,ioBuf);
1435         }
1436     }
1438     chanHandle->currentError = MCBSP_STATUS_COMPLETED;
1439     chanHandle->userDataBufferSize = 0;
1442 /**
1443  * \brief     This function configures the transmit section of the mcbsp
1444  *            sync properties.
1445  *
1446  * \param     instHandle  [IN] pointer to the instance object.
1447  * \param     params      [IN] User supplied channel parameters
1448  *
1449  * \return    MCBSP_ERR_BADARGS  if configuration fails.
1450  *            MCBSP_STATUS_COMPLETED if configuration is sucessful.
1451  */
1452 int32_t Mcbsp_localConfigureXmtChannel(Mcbsp_Object_Unpadded *instHandle,
1453                                      Mcbsp_ChanParams *params)
1455     uint32_t  tempVal = 0x00;
1456     int32_t   status  = MCBSP_STATUS_COMPLETED;
1458     if ((NULL == instHandle) || (NULL == params))
1459     {
1460         return MCBSP_ERR_BADARGS;
1461     }
1463     /* configure the transmit section                                         */
1464     /* configure the transmit interrupt setting                               */
1465     instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_XINTM_MASK);
1466     instHandle->hwInfo.regs->SPCR |=
1467         (params->chanConfig->intMode << CSL_MCBSP_SPCR_XINTM_SHIFT);
1469         /* configure the DX enabler */
1470         instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_DXENA_MASK);
1471         instHandle->hwInfo.regs->SPCR |=
1472         (params->chanConfig->dxState << CSL_MCBSP_SPCR_DXENA_SHIFT);
1474     /* configure the transmit control register settings                       */
1475     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XPHASE_MASK);
1476     instHandle->hwInfo.regs->XCR |=
1477         (params->chanConfig->phaseNum << CSL_MCBSP_XCR_XPHASE_SHIFT);
1479     /* configure the frame length for single and dual phase frames            */
1480     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XFRLEN1_MASK);
1481     instHandle->hwInfo.regs->XCR |=
1482         ((params->chanConfig->frmLen1 - 1u) << CSL_MCBSP_XCR_XFRLEN1_SHIFT);
1484     /* configure the word length of the single and dual phase frames          */
1485     switch (params->chanConfig->wrdLen1)
1486     {
1487         case Mcbsp_WordLength_8:
1488             tempVal = 0u;
1489             break;
1490         case Mcbsp_WordLength_12:
1491             tempVal = 1u;
1492             break;
1493         case Mcbsp_WordLength_16:
1494             tempVal = 2u;
1495             break;
1496         case Mcbsp_WordLength_20:
1497             tempVal = 3u;
1498             break;
1499         case Mcbsp_WordLength_24:
1500             tempVal = 4u;
1501             break;
1502         case Mcbsp_WordLength_32:
1503             tempVal = 5u;
1504             break;
1505         default:
1506             /* wordlength is not supported by the driver                      */
1507             status = MCBSP_ERR_BADARGS;
1508             break;
1509     }
1511     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XWDLEN1_MASK);
1512     instHandle->hwInfo.regs->XCR |=
1513         (tempVal << CSL_MCBSP_XCR_XWDLEN1_SHIFT);
1515     if (Mcbsp_Phase_DUAL == params->chanConfig->phaseNum)
1516     {
1518         instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XFRLEN2_MASK);
1519         instHandle->hwInfo.regs->XCR |=
1520             ((params->chanConfig->frmLen2 -1u) << CSL_MCBSP_XCR_XFRLEN2_SHIFT);
1522         /* configure the word length of the single and dual phase frames      */
1523         switch (params->chanConfig->wrdLen2)
1524         {
1525             case Mcbsp_WordLength_8:
1526                 tempVal = 0u;
1527                 break;
1528             case Mcbsp_WordLength_12:
1529                 tempVal = 1u;
1530                 break;
1531             case Mcbsp_WordLength_16:
1532                 tempVal = 2u;
1533                 break;
1534             case Mcbsp_WordLength_20:
1535                 tempVal = 3u;
1536                 break;
1537             case Mcbsp_WordLength_24:
1538                 tempVal = 4u;
1539                 break;
1540             case Mcbsp_WordLength_32:
1541                 tempVal = 5u;
1542                 break;
1543             default:
1544                 /* wordlength is not supported by the driver                  */
1545                 status = MCBSP_ERR_BADARGS;
1546                 break;
1547         }
1549         instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XWDLEN2_MASK);
1550         instHandle->hwInfo.regs->XCR |=
1551             (tempVal << CSL_MCBSP_XCR_XWDLEN2_SHIFT);
1552     }
1553     /* set the companding selection                                           */
1554     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XCOMPAND_MASK);
1555     instHandle->hwInfo.regs->XCR |=
1556         (params->chanConfig->compandSel << CSL_MCBSP_XCR_XCOMPAND_SHIFT);
1558     /* set the bit reverse settings                                           */
1559     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XWDREVRS_MASK);
1560     instHandle->hwInfo.regs->XCR |=
1561         (params->chanConfig->bitReversal << CSL_MCBSP_XCR_XWDREVRS_SHIFT);
1563     /* frame ignore settings                                                  */
1564     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XFIG_MASK);
1565     instHandle->hwInfo.regs->XCR |=
1566         (params->chanConfig->frmSyncIgn << CSL_MCBSP_XCR_XFIG_SHIFT);
1568     /* configure the data delay                                               */
1569     instHandle->hwInfo.regs->XCR &= (~CSL_MCBSP_XCR_XDATDLY_MASK);
1570     instHandle->hwInfo.regs->XCR |=
1571         (params->chanConfig->dataDelay << CSL_MCBSP_XCR_XDATDLY_SHIFT);
1573     /* configure the multi channel control register settings                  */
1574     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XMCM_MASK);
1575     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->multiChanMode
1576                                           << CSL_MCBSP_MCR_XMCM_SHIFT);
1578     /* select the partition mode and the channel selection controls           */
1579     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XPABLK_MASK);
1580     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelA
1581                                           << CSL_MCBSP_MCR_XPABLK_SHIFT);
1583     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XPBBLK_MASK);
1584     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelB
1585                                           << CSL_MCBSP_MCR_XPBBLK_SHIFT);
1587     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_XMCME_MASK);
1588     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionMode
1589                                           << CSL_MCBSP_MCR_XMCME_SHIFT);
1591     /* Configure the channels to be enabled                                   */
1592     instHandle->hwInfo.regs->XCERE0 = params->chanEnableMask[0];
1593     instHandle->hwInfo.regs->XCERE1 = params->chanEnableMask[1];
1594     instHandle->hwInfo.regs->XCERE2 = params->chanEnableMask[2];
1595     instHandle->hwInfo.regs->XCERE3 = params->chanEnableMask[3];
1598     /* configure the clock polarity                                           */
1599     if (Mcbsp_ClkPol_RISING_EDGE == params->clkSetup->clkPolarity)
1600     {
1601         /* clock data sampled on rising edge                                  */
1602         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKXP_MASK);
1603     }
1604     else
1605     {
1606         /* clock data sampled on falling edge                                 */
1607         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKXP_MASK);
1608     }
1610     /* configure the frame sync polarity                                      */
1611     if (Mcbsp_FsPol_ACTIVE_HIGH == params->clkSetup->frmSyncPolarity)
1612     {
1613         /* frame sync polarity is active high                                 */
1614         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSXP_MASK);
1615     }
1616     else
1617     {
1618         /* frame sync polarity is active low                                  */
1619         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSXP_MASK);
1620     }
1622     /* check if the frame sync generator is to be enabled for this TX section */
1623     if (Mcbsp_FsClkMode_EXTERNAL == params->clkSetup->frmSyncMode)
1624     {
1625         /* External frame sync to be used                                     */
1626         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSXM_MASK);
1628         /* frame sync generator needs to be disabled                          */
1629         instHandle->txFsgEnable = FALSE;
1630     }
1631     else
1632     {
1633         /* internal frame sync to be used                                     */
1634         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSXM_MASK);
1635         
1636         /* The FRST and GRST has to be cleared to configure the FSGM bit. 
1637          * By clearing the FRST and GRST bit, the sample rate generator and the 
1638          * frame sync generator will be kept in the reset mode. 
1639          * Ref IR SDOCM00077966
1640          */
1641         tempVal = instHandle->hwInfo.regs->SPCR;
1642         instHandle->hwInfo.regs->SPCR &= ~(CSL_MCBSP_SPCR_FRST_MASK | 
1643                                                                                                  CSL_MCBSP_SPCR_GRST_MASK );
1645         /* could be internal or configured for DXR to XSR copy                */
1646         if (Mcbsp_FsClkMode_INTERNAL == params->clkSetup->frmSyncMode)
1647         {
1648             /* set the FSGM bit in the SRGR register                          */
1649             instHandle->hwInfo.regs->SRGR |= (CSL_MCBSP_SRGR_FSGM_MASK);
1651             /* frame sync generator needs to be enabled                       */
1652             instHandle->txFsgEnable = TRUE;
1653         }
1654         else
1655         {   /* DXR to XSR copy generates frame sync                           */
1656             /* reset the FSGM bit in the SRGR register                        */
1657             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_FSGM_MASK);
1659             /* frame sync generator needs to be disabled                      */
1660             instHandle->txFsgEnable = FALSE;
1661         }
1662         /* The SPCR register values are reverted back once the FSGM bit is set
1663          */
1664         instHandle->hwInfo.regs->SPCR = tempVal;
1665     }
1667     /* configure the clock mode (external or internal)                        */
1668     if (Mcbsp_TxRxClkMode_EXTERNAL == params->clkSetup->clkMode)
1669     {
1670         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKXM_MASK);
1672         if (TRUE == instHandle->txFsgEnable)
1673         {
1674             /* frame sync generator is using the internal clock hence need to *
1675              * enable the sample rate generator                               */
1676             instHandle->txSrgEnable = TRUE;
1677         }
1678         else
1679         {
1680             /* dont require to enable the sample rate generator               */
1681             instHandle->txSrgEnable = FALSE;
1682         }
1683     }
1684     else
1685     {
1686         /* external mode clock enabled                                        */
1687         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKXM_MASK);
1689         /* sample rate generator is enabled                                   */
1690         instHandle->txSrgEnable = TRUE;
1691     }
1693     return (status);
1697 /**
1698  * \brief     This function configures the receives section of the mcbsp.
1699  *
1700  * \param     instHandle  [IN] pointer to the instance object.
1701  * \param     params      [IN] User supplied channel parameters
1702  *
1703  * \return    MCBSP_ERR_BADARGS  if configuration fails.
1704  *            MCBSP_STATUS_COMPLETED if confioguration is sucessful.
1705  */
1706 int32_t Mcbsp_localConfigureRcvChannel(Mcbsp_Object_Unpadded *instHandle,
1707                                      Mcbsp_ChanParams *params)
1709     uint32_t  tempVal = 0x00;
1710     int32_t   status  = MCBSP_STATUS_COMPLETED;
1712     if ((NULL == instHandle) || (NULL == params))
1713     {
1714         return MCBSP_ERR_BADARGS;
1715     }
1717     /* configure the receive section                                          */
1718     /* configure the receive interrupt setting                                */
1719     instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_RINTM_MASK);
1720     instHandle->hwInfo.regs->SPCR |=
1721         (params->chanConfig->intMode << CSL_MCBSP_SPCR_RINTM_SHIFT);
1723     /* configure the Receive sign-extension and justification                 */
1724     instHandle->hwInfo.regs->SPCR &= (~CSL_MCBSP_SPCR_RJUST_MASK);
1725     instHandle->hwInfo.regs->SPCR |=
1726         (params->chanConfig->rjust << CSL_MCBSP_SPCR_RJUST_SHIFT);
1728     /* configure the receive control register settings                        */
1729     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RPHASE_MASK);
1730     instHandle->hwInfo.regs->RCR |=
1731         (params->chanConfig->phaseNum << CSL_MCBSP_RCR_RPHASE_SHIFT);
1733     /* configure the frame length for single and dual phase frames            */
1734     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RFRLEN1_MASK);
1735     instHandle->hwInfo.regs->RCR |=
1736         ((params->chanConfig->frmLen1 - 1u) << CSL_MCBSP_RCR_RFRLEN1_SHIFT);
1738     /* configure the word length of the single and dual phase frames          */
1739     switch (params->chanConfig->wrdLen1)
1740     {
1741         case Mcbsp_WordLength_8:
1742             tempVal = 0u;
1743             break;
1744         case Mcbsp_WordLength_12:
1745             tempVal = 1u;
1746             break;
1747         case Mcbsp_WordLength_16:
1748             tempVal = 2u;
1749             break;
1750         case Mcbsp_WordLength_20:
1751             tempVal = 3u;
1752             break;
1753         case Mcbsp_WordLength_24:
1754             tempVal = 4u;
1755             break;
1756         case Mcbsp_WordLength_32:
1757             tempVal = 5u;
1758             break;
1759         default:
1760             /* wordlength is not supported by the driver                      */
1761             status = MCBSP_ERR_BADARGS;
1762             break;
1763     }
1766     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RWDLEN1_MASK);
1767     instHandle->hwInfo.regs->RCR |=
1768         (tempVal << CSL_MCBSP_RCR_RWDLEN1_SHIFT);
1770     if (Mcbsp_Phase_DUAL == params->chanConfig->phaseNum)
1771     {
1772         instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RFRLEN2_MASK);
1773         instHandle->hwInfo.regs->RCR |=
1774         ((params->chanConfig->frmLen2 - 1u) << CSL_MCBSP_RCR_RFRLEN2_SHIFT);
1775     
1776         /* configure the word length of the single and dual phase frames      */
1777         switch (params->chanConfig->wrdLen2)
1778         {
1779             case Mcbsp_WordLength_8:
1780                 tempVal = 0u;
1781                 break;
1782             case Mcbsp_WordLength_12:
1783                 tempVal = 1u;
1784                 break;
1785             case Mcbsp_WordLength_16:
1786                 tempVal = 2u;
1787                 break;
1788             case Mcbsp_WordLength_20:
1789                 tempVal = 3u;
1790                 break;
1791             case Mcbsp_WordLength_24:
1792                 tempVal = 4u;
1793                 break;
1794             case Mcbsp_WordLength_32:
1795                 tempVal = 5u;
1796                 break;
1797             default:
1798                 /* wordlength is not supported by the driver                      */
1799                 status = MCBSP_ERR_BADARGS;
1800                 break;
1801         }
1803         instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RWDLEN2_MASK);
1804         instHandle->hwInfo.regs->RCR |=
1805             (tempVal << CSL_MCBSP_RCR_RWDLEN2_SHIFT);
1806     }
1807     /* set the companding selection                                           */
1808     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RCOMPAND_MASK);
1809     instHandle->hwInfo.regs->RCR |=
1810         (params->chanConfig->compandSel << CSL_MCBSP_RCR_RCOMPAND_SHIFT);
1812     /* set the bit reverse settings                                           */
1813     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RWDREVRS_MASK);
1814     instHandle->hwInfo.regs->RCR |=
1815         (params->chanConfig->bitReversal << CSL_MCBSP_RCR_RWDREVRS_SHIFT);
1817     /* frame ignore settings                                                  */
1818     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RFIG_MASK);
1819     instHandle->hwInfo.regs->RCR |=
1820         (params->chanConfig->frmSyncIgn << CSL_MCBSP_RCR_RFIG_SHIFT);
1822     /* configure the data delay                                               */
1823     instHandle->hwInfo.regs->RCR &= (~CSL_MCBSP_RCR_RDATDLY_MASK);
1824     instHandle->hwInfo.regs->RCR |=
1825         (params->chanConfig->dataDelay << CSL_MCBSP_RCR_RDATDLY_SHIFT);
1827     /* Configure the channels to be enabled                                   */
1828     instHandle->hwInfo.regs->RCERE0 = params->chanEnableMask[0];
1829     instHandle->hwInfo.regs->RCERE1 = params->chanEnableMask[1];
1830     instHandle->hwInfo.regs->RCERE2 = params->chanEnableMask[2];
1831     instHandle->hwInfo.regs->RCERE3 = params->chanEnableMask[3];
1833     /* configure the MCR register                                             */
1834     switch (params->multiChanCtrl->multiChanMode)
1835     {
1836         case Mcbsp_McmMode_ALL_CHAN_ENABLED_UNMASKED:
1837         case Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED:
1838             break;
1839         default:
1840             status = MCBSP_ERR_BADARGS;
1841             break;
1842     }
1844     if (MCBSP_STATUS_COMPLETED == status)
1845     {
1846         instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RMCM_MASK);
1847         instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->multiChanMode
1848                                           << CSL_MCBSP_MCR_RMCM_SHIFT);
1849     }
1851     /* select the partition mode and the channel selection controls           */
1852     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RPABLK_MASK);
1853     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelA
1854                                           << CSL_MCBSP_MCR_RPABLK_SHIFT);
1856     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RPBBLK_MASK);
1857     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionSelB
1858                                           << CSL_MCBSP_MCR_RPBBLK_SHIFT);
1860     instHandle->hwInfo.regs->MCR &= (~CSL_MCBSP_MCR_RMCME_MASK);
1861     instHandle->hwInfo.regs->MCR |= (params->multiChanCtrl->partitionMode
1862                                           << CSL_MCBSP_MCR_RMCME_SHIFT);
1864     /* configure the clock polarity                                           */
1865     if (Mcbsp_ClkPol_RISING_EDGE == params->clkSetup->clkPolarity)
1866     {
1867         /* clock data sampled on rising edge                                  */
1868         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKRP_MASK);
1869     }
1870     else
1871     {
1872         /* clock data sampled on falling edge                                 */
1873         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKRP_MASK);
1874     }
1876     /* configure the frame sync polarity                                      */
1877     if (Mcbsp_FsPol_ACTIVE_HIGH == params->clkSetup->frmSyncPolarity)
1878     {
1879         /* frame sync polarity is active high                                 */
1880         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSRP_MASK);
1881     }
1882     else
1883     {
1884         /* frame sync polarity is active low                                  */
1885         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSRP_MASK);
1886     }
1889     /* check if the frame sync generator is to be enabled for this section    */
1890     if (Mcbsp_FsClkMode_INTERNAL == params->clkSetup->frmSyncMode)
1891     {
1892         /* set the frame sync generation mode                                 */
1893         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_FSRM_MASK);
1895         /* frame sync generator needs to be enabled                           */
1896         instHandle->rxFsgEnable = TRUE;
1897     }
1898     else
1899     {
1900         /* reset the frame sync generation mode                               */
1901         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_FSRM_MASK);
1903         /* frame sync generator needs to be disabled                          */
1904         instHandle->rxFsgEnable = FALSE;
1905     }
1907     /* configure the clock mode (external or internal)                        */
1908     if (Mcbsp_TxRxClkMode_EXTERNAL == params->clkSetup->clkMode)
1909     {
1910         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_CLKRM_MASK);
1912         if (TRUE == instHandle->rxFsgEnable)
1913         {
1914             /* frame sync generator is using the internal clock hence need to *
1915              * enable the sample rate generator                               */
1916             instHandle->rxSrgEnable = TRUE;
1917         }
1918         else
1919         {
1920             /* dont require to enable the sample rate generator               */
1921             instHandle->rxSrgEnable = FALSE;
1922         }
1923     }
1924     else
1925     {
1926         /* external mode clock                                                */
1927         instHandle->hwInfo.regs->PCR |= (CSL_MCBSP_PCR_CLKRM_MASK);
1929         /* sample rate generator is enabled                                   */
1930         instHandle->rxSrgEnable = TRUE;
1931     }
1932     return (status);
1935 /**
1936  * \brief     This function configures the sample rate generator and frame
1937  *            sync properties.
1938  *
1939  * \param     instHandle  [IN] pointer to the instance object.
1940  * \param     chanHandle  [IN] Handle to the channel.
1941  *
1942  * \return    MCBSP_ERR_BADARGS  if calculation fails.
1943  *            MCBSP_STATUS_COMPLETED if calculation is sucessful.
1944  */
1945 int32_t Mcbsp_localConfigureSrgr(Mcbsp_Object_Unpadded *instHandle,
1946                                Mcbsp_ChannelObj *chanHandle)
1948     Bool             srgrConfig  = FALSE;
1949     uint32_t         clkgDiv     = 0x00;
1950     uint32_t         noOfBits    = 0x00;
1951     uint32_t         framePeriod = 0x00;
1952     Bool             sclkme      = 0x00;
1953     Bool             clksm       = 0x00;
1954     int32_t          status      = MCBSP_STATUS_COMPLETED;
1955     void*            criticalSectionInfo;
1957     if ((NULL == instHandle) || (NULL == chanHandle))
1958     {
1959         return MCBSP_ERR_BADARGS;
1960     }
1962     /* check if the SRGR is not configured already                            */
1963     /* critical section starts                                                */
1964     criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
1966     if (FALSE == instHandle->srgConfigured)
1967     {
1968         /* set the status that SRGR is configured                             */
1969         instHandle->srgConfigured = TRUE;
1971         /* critical section ends                                              */
1972         Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1974         /* check if this channel requires the SRGR to be enabled              */
1975         if (MCBSP_MODE_INPUT == chanHandle->mode)
1976         {
1977             if (TRUE == instHandle->rxSrgEnable)
1978             {
1979                 /* Need to configure the SRGR                                 */
1980                 srgrConfig = TRUE;
1981             }
1982             else
1983             {
1984                         instHandle->srgConfigured = FALSE;   
1985             }
1986         }
1987         else
1988         {
1989             if (TRUE == instHandle->txSrgEnable)
1990             {
1991                 /* Need to configure the SRGR                                 */
1992                 srgrConfig = TRUE;
1993             }
1994             else
1995             {
1996                         instHandle->srgConfigured = FALSE;   
1997             }            
1998         }
1999     }
2000     else
2001     {
2002         /* critical section ends                                          */
2003         Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
2004     }
2006     if (TRUE == srgrConfig)
2007     {
2008         /* set the input clock selection for Sample rate generator            */
2009         switch (instHandle->srgrConfig.srgInputClkMode)
2010         {
2011             /* Input clock is CLKS                                            */
2012             case Mcbsp_SrgClk_CLKS:
2013                 sclkme = 0x00;
2014                 clksm = 0x00;
2016                 /* set the CLKS polarity (only if CLKS is used)               */
2017                 instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_CLKSP_MASK);
2018                 instHandle->hwInfo.regs->SRGR |=
2019                     (instHandle->srgrConfig.clksPolarity
2020                         << CSL_MCBSP_SRGR_CLKSP_SHIFT);
2022                 /* set the GSYNC option                                       */
2023                 instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_GSYNC_MASK);
2024                 instHandle->hwInfo.regs->SRGR |=
2025                     (instHandle->srgrConfig.gSync
2026                         << CSL_MCBSP_SRGR_GSYNC_SHIFT);
2027                 break;
2028             /* Input clock for SRG is from CPU clock                          */
2029             case Mcbsp_SrgClk_CLKCPU:
2030                 sclkme = 0x00;
2031                 clksm = 0x01u;
2032                 break;
2033             /* Input clock is from receive pin                                */
2034             case Mcbsp_SrgClk_CLKR:
2035                 sclkme = 0x01u;
2036                 clksm = 0x00;
2037                 break;
2038             /* Input clock is from transmit pin                               */
2039             case Mcbsp_SrgClk_CLKX:
2040                 sclkme = 0x01u;
2041                 clksm = 0x01u;
2042                 break;
2043             default:
2044                 status = MCBSP_ERR_BADARGS;
2045                 break;
2046         }
2048         instHandle->hwInfo.regs->PCR &= (~CSL_MCBSP_PCR_SCLKME_MASK);
2049         instHandle->hwInfo.regs->PCR |= (sclkme << CSL_MCBSP_PCR_SCLKME_SHIFT);
2051         instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_CLKSM_MASK);
2052         instHandle->hwInfo.regs->SRGR |= (clksm << CSL_MCBSP_SRGR_CLKSM_SHIFT);
2054         /* calculate and set the CLKG div values                              */
2055         if (Mcbsp_Phase_DUAL == chanHandle->chanConfig.phaseNum)
2056         {
2057             noOfBits = ((chanHandle->chanConfig.wrdLen1
2058                             * chanHandle->chanConfig.frmLen1)
2059                         + (chanHandle->chanConfig.wrdLen2
2060                             * chanHandle->chanConfig.frmLen2));
2061         }
2062         else
2063         {
2064             noOfBits  = (chanHandle->chanConfig.wrdLen1
2065                             * chanHandle->chanConfig.frmLen1);
2066         }
2068         clkgDiv = ((instHandle->srgrConfig.srgrInputFreq/
2069                     (chanHandle->clkSetup.samplingRate
2070                     * noOfBits)) - 1u);
2072         framePeriod = (noOfBits - 1u);
2074         if ((0xFF < clkgDiv) || (0xFFF < framePeriod) ||
2075             (MCBSP_STATUS_COMPLETED != status))
2076         {
2077             /* The CLKGDIV or frame period value has exceeded the limit       */
2078             status = MCBSP_ERR_BADARGS;
2079         }
2080         else
2081         {
2082             /* set the value of the CLKGDIV                                   */
2083             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_CLKGDV_MASK);
2084             instHandle->hwInfo.regs->SRGR |= clkgDiv;
2086             /* set the value of the frame period                              */
2087             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_FPER_MASK);
2088             instHandle->hwInfo.regs->SRGR |=
2089                 (framePeriod << CSL_MCBSP_SRGR_FPER_SHIFT);
2091             /* set the frame width                                            */
2092             instHandle->hwInfo.regs->SRGR &= (~CSL_MCBSP_SRGR_FWID_MASK);
2093             instHandle->hwInfo.regs->SRGR |=
2094                 (instHandle->srgrConfig.srgFrmPulseWidth <<
2095                     CSL_MCBSP_SRGR_FWID_SHIFT);
2096         }
2097     }
2099     return (status);
2102 /**
2103  * \brief   Abort the queued up requests.
2104  *
2105  *          This commands aborts all the pending IO requests and returns them
2106  *          to the application. The current state of the IO request will be set
2107  *          to ABORTED.
2108  *
2109  * \param   chanHandle   [IN]   Handle to the channel whose requests are to be
2110  *                              aborted
2111  *
2112  * \return  None
2113  */
2114 void Mcbsp_localAbortReset(Mcbsp_ChannelObj *chanHandle)
2116     Mcbsp_Object_Unpadded *instHandle   = NULL;
2117     Mcbsp_IOBuf      *ioBuf        = NULL;
2118     void*             criticalSectionInfo;
2119     uint32_t          timeoutCount = 0x00;
2121     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
2123     /* initialize the retry count value                                       */
2124     timeoutCount = instHandle->retryCount;
2126     /* critical section starts                                        */
2127     criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
2129     if (Mcbsp_DevMode_McBSP == instHandle->mode)
2130     {
2131         /* Disable the EDMA transfer for the current transfer channel         */
2132         EDMA3_DRV_disableTransfer(
2133             chanHandle->edmaHandle,
2134             chanHandle->xferChan,
2135             EDMA3_DRV_TRIG_MODE_EVENT);
2137         if (MCBSP_MODE_OUTPUT == chanHandle->mode)
2138         {
2139             /* Wait for the TX to be empty                                    */
2140             while ((CSL_MCBSP_SPCR_XEMPTY_MASK ==
2141                 (CSL_MCBSP_SPCR_XEMPTY_MASK & instHandle->hwInfo.regs->SPCR)) &&
2142                 (0 != timeoutCount))
2143             {
2144                 timeoutCount--;
2145             }
2146         }
2148         /* Stop the McBSP instance                                            */
2149         if (MCBSP_MODE_INPUT == chanHandle->mode)
2150         {
2151             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_DISABLE);
2152         }
2153         else
2154         {
2155             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_DISABLE);
2156         }
2158         /* Empty the floating queue. Aborted request is currently enqueued    *
2159          * in the floating queue. Dequeue the floating request in EDMA        *
2160          * param table and return the actual transfer element count           */
2161         while (TRUE !=  Mcbsp_osalQueueEmpty(chanHandle->ptrQFloatList))
2162         {
2163             ioBuf = Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
2165             if (NULL != ioBuf)
2166             {
2167                 /* if FLUSH cmd called for INPUT channel then status is equal *
2168                  * to FLUSHED otherwise status is equal to ABORTED            */
2169                 if ((TRUE == chanHandle->flush) &&
2170                     (MCBSP_MODE_INPUT == chanHandle->mode))
2171                 {
2172                     ioBuf->status = MCBSP_STATUS_FLUSHED;
2173                 }
2174                 else
2175                 {
2176                     ioBuf->status = MCBSP_STATUS_ABORTED;
2177                 }
2179                 if ((NULL !=  chanHandle->cbFxn) && (NULL != chanHandle->cbArg))
2180                 {
2181                     /*  Application callback                                  */
2182                     (*chanHandle->cbFxn)((void*)chanHandle->cbArg,ioBuf);
2183                 }
2184                 /* Decrement the submit count                                 */
2185                 chanHandle->submitCount--;
2186             }
2187         }
2189         /* Empty the pending queue                                            */
2190         while (TRUE != Mcbsp_osalQueueEmpty(chanHandle->ptrQPendList))
2191         {
2192             ioBuf = Mcbsp_osalQueueGet(chanHandle->ptrQPendList);
2194             if (NULL != ioBuf)
2195             {
2196                 /* if FLUSH cmd called for INPUT channel then status is equal *
2197                  * to MCBSP_STATUS_FLUSHED otherwise status is equal to MCBSP_STATUS_ABORTED    */
2198                 if ((TRUE == chanHandle->flush) &&
2199                     (MCBSP_MODE_INPUT == chanHandle->mode))
2200                 {
2201                     ioBuf->status = MCBSP_STATUS_FLUSHED;
2202                 }
2203                 else
2204                 {
2205                     ioBuf->status = MCBSP_STATUS_ABORTED;
2206                 }
2208                 if ((NULL != chanHandle->cbFxn) && (NULL != chanHandle->cbArg))
2209                 {
2210                     /*  Application callback                                  */
2211                     (*chanHandle->cbFxn)((void*)chanHandle->cbArg,ioBuf);
2212                 }
2213                 
2214                 /* Decrement the submit count                                 */
2215                 chanHandle->submitCount--;
2216             }
2217         }
2219         /* As EDMA is disabled it might have thrown an error and set error bit*
2220          * Clear the error bit to enable the transfer again                   */
2221         EDMA3_DRV_clearErrorBits(chanHandle->edmaHandle,chanHandle->xferChan);
2223         /* Configure the EDMA channel and EDMA param tables with              *
2224          * intialization configuration as they are configured at the          *
2225          * create time.                                                       */
2226         Mcbsp_localEdmaChanPaRAMsetup(chanHandle);
2228 #ifdef MCBSP_LOOPJOB_ENABLE
2230                 /* configure the FIFO for the specific channel                        */
2231         if (TRUE == chanHandle->enableHwFifo)
2232         {
2233             /* Disable and enable the FIFO so that the events are             *
2234              * generated to the Mcbsp for the first time                      */
2235             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,FALSE);
2236             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,TRUE);
2237         }
2239         /* Enable the EDMA transfer to start the Loop job running             */
2240         EDMA3_DRV_enableTransfer(
2241             chanHandle->edmaHandle,
2242             chanHandle->xferChan,
2243             EDMA3_DRV_TRIG_MODE_EVENT);
2245         chanHandle->loopjobUpdatedinParamset = TRUE;
2246         chanHandle->nextLinkParamSetToBeUpdated = 0;
2247         
2248         /* start the Mcbsp channel                                             */
2249         if (MCBSP_MODE_INPUT == chanHandle->mode)
2250         {
2251             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_ENABLE);
2252         }
2253         else
2254         {
2255                         Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
2256                 }
2257 #endif
2258     }
2259     /* critical section ends                                          */
2260     Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
2262 /**
2263  *
2264  * \brief   This function configures the Hardware FIFO
2265  *
2266  * \param   hMcbsp       [IN] pointer to the Mcbsp Hardware information struct
2267  * \param   chanHandle   [IN] handle to the channel
2268  * \param   enableHwFifo [IN] option to Enable or disbale the FIFO
2269  *
2270  * \return  None
2271  *
2272  * \enter   hMcbsp      is a valid non null pointer
2273  *          chanHandle  is a valid non null pointer
2274  *
2275  * \leave   Not implemented
2276  *
2277  */
2278 void mcbspConfigureFifo(Mcbsp_HwInfo_Unpadded *hMcbsp,
2279                         Mcbsp_ChannelObj    *chanHandle,
2280                         Bool                 enableHwFifo)
2282     /* check if the HW FIFO usage is requested by the user for this channel   */
2283     if (TRUE == enableHwFifo)
2284     {
2285         if (MCBSP_MODE_INPUT == chanHandle->mode)
2286         {
2287             /* configure the receive channel                                  */
2288             /* Step 1 : configure the "WNUMDMA" and "WNUMEVT" bits before     *
2289              * enabling the FIFO                                              */
2290             hMcbsp->fifoRegs->RFIFOCTL =
2291                 (1 << CSL_BFIFO_RFIFOCTL_RNUMEVT_SHIFT);
2293             hMcbsp->fifoRegs->RFIFOCTL |=
2294                 (CSL_BFIFO_RFIFOCTL_RNUMDMA_1WORDS
2295                     << CSL_BFIFO_RFIFOCTL_RNUMDMA_SHIFT);
2297             /* enable the FIFO now by setting the "WENA" bit                  */
2298             hMcbsp->fifoRegs->RFIFOCTL |=
2299                 (CSL_BFIFO_RFIFOCTL_RENA_ENABLED
2300                     << CSL_BFIFO_RFIFOCTL_RENA_SHIFT);
2301         }
2302         else
2303         {
2304             /* configure the transmit channel                                 */
2305             /* Step 1 : configure the "WNUMDMA" and "WNUMEVT" bits before     *
2306              * enabling the FIFO                                              */
2307             hMcbsp->fifoRegs->WFIFOCTL =
2308                 (1 << CSL_BFIFO_WFIFOCTL_WNUMEVT_SHIFT);
2310             hMcbsp->fifoRegs->WFIFOCTL |=
2311                 (CSL_BFIFO_WFIFOCTL_WNUMDMA_1WORDS
2312                     << CSL_BFIFO_WFIFOCTL_WNUMDMA_SHIFT);
2314             /* enable the FIFO now by setting the "WENA" bit                  */
2315             hMcbsp->fifoRegs->WFIFOCTL |=
2316                 (CSL_BFIFO_WFIFOCTL_WENA_ENABLED
2317                     << CSL_BFIFO_WFIFOCTL_WENA_SHIFT);
2318         }
2319     }
2320     else
2321     {
2322         /* FIFO needs to be disabled                                          */
2323         if (MCBSP_MODE_INPUT == chanHandle->mode)
2324         {
2325             /* disable the FIFO now by resetting the "WENA" bit               */
2326             hMcbsp->fifoRegs->RFIFOCTL =
2327                 (CSL_BFIFO_RFIFOCTL_RENA_DISABLED
2328                     << CSL_BFIFO_RFIFOCTL_RENA_SHIFT);
2329         }
2330         else
2331         {
2332             /* disable the FIFO now by resetting the "WENA" bit               */
2333             hMcbsp->fifoRegs->WFIFOCTL =
2334                 (CSL_BFIFO_WFIFOCTL_WENA_DISABLED
2335                     << CSL_BFIFO_WFIFOCTL_WENA_SHIFT);
2336         }
2337     }
2340 /**
2341  * \brief   This is going to complete the current request and abort
2342  *          all other reqest.
2343  *
2344  * \param   chanHandle   [IN]   Channel handle
2345  *
2346  * \return  None
2347  *
2348  * \enter   chanHandle  is a valid non null pointer
2349  *
2350  * \leave   Not implemented
2351  */
2352 void Mcbsp_localCancelAndAbortAllIo(Mcbsp_ChannelObj *chanHandle)
2354     chanHandle->submitCount--;
2355     chanHandle->tempIOBuf->status = MCBSP_STATUS_ABORTED;
2357     Mcbsp_localCompleteCurrentIo(chanHandle);
2359     Mcbsp_localAbortReset(chanHandle);
2362 #ifndef MCBSP_LOOPJOB_ENABLE
2363 /**
2364  *  \brief  This function waits for the FIFO to be emptied(if enabled) and the
2365  *          TX empty bit to be set so that the TX section could be disabled when
2366  *          there is no data present.
2367  *
2368  *  \param  arg0   [IN]  Handle to the TX channel
2369  *  \param  arg1   [IN]  unused
2370  *
2371  *  \return None
2372  *
2373  *  \enter  arg0 is a valid non null pointer
2374  *
2375  *  \leave  Not implemented
2376  */
2377 void Mcbsp_TxFifo(int32_t arg0, int32_t arg1)
2379     Mcbsp_ChannelObj  *chanHandle = NULL;
2380     Mcbsp_Object *hInst = NULL;
2381     Mcbsp_Object_Unpadded *instHandle = NULL;
2382     uint32_t           timeOut    = 0x00;
2383     void*              criticalSectionInfo;
2385     chanHandle = (Mcbsp_ChannelObj *)arg0;
2386     hInst = (Mcbsp_Object *)arg1;
2387     instHandle = (Mcbsp_Object_Unpadded *)&(hInst->obj);
2389     /* critical section starts                                                */
2390     criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
2392     /* update the timeout value from the instance handle                      */
2393     timeOut = instHandle->retryCount;
2395     /* we have come here means that the Mcbsp has got an callback but it      *
2396      * did have any more buffer to load Hence here we will wait for the       *
2397      * FIFO to become empty (if FIFO is enabled) else wait for the TX to      *
2398      * become empty.then we will disable the TX section                       */
2399     if (TRUE == chanHandle->enableHwFifo)
2400     {
2401         while ((0 != (instHandle->hwInfo.fifoRegs->WFIFOSTS &
2402                        CSL_BFIFO_WFIFOSTS_WLVL_MASK))
2403                 && (0 != timeOut))
2404         {
2405             /* reduce the timeout count and check if the FIFO is empty    */
2406             timeOut--;
2407         }
2408     }
2410     /* reinitialize the retry count                                       */
2411     timeOut = instHandle->retryCount;
2413     while ((CSL_MCBSP_SPCR_XEMPTY_MASK ==
2414             (instHandle->hwInfo.regs->SPCR & CSL_MCBSP_SPCR_XEMPTY_MASK))
2415            && (0 != timeOut))
2416     {
2417         /* reduce the retry count and check if the TX has completed           *
2418          * transmitting all the bytes                                         */
2419         timeOut--;
2420     }
2422     /* we need to stop the frame sycn generator now.But also need to check    *
2423      * if  1.The frame sycn generator is actually started By TX.              *
2424      *     2.The RX is  not feeding of the sample rate generator              */
2425     if ((TRUE == instHandle->txFsgEnable) &&
2426         ((TRUE != instHandle->rxFsgEnable)
2427             || (TRUE == instHandle->stopSmFsRcv)))
2428     {
2429         /* Now we can disable the frame sync generator                        */
2430         Mcbsp_localResetCtrl(
2431             (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj),
2432             Mcbsp_SpcrCtrl_FSYNC_DISABLE);
2433         instHandle->fsgEnabled = FALSE;
2434     }
2436     /* Stop the TX section                                                    */
2437     Mcbsp_localResetCtrl(
2438         (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj),
2439         Mcbsp_SpcrCtrl_TX_DISABLE);
2441     /* Transmit state machine is stopped                                      */
2442     instHandle->stopSmFsXmt = TRUE;
2444     /* clear the error bits in the EDMA(as this is the last buffer)           */
2445     EDMA3_DRV_clearErrorBits(
2446         chanHandle->edmaHandle,
2447         chanHandle->xferChan);
2449     /* complete the IOP now and call the callback to the stream               */
2450     chanHandle->tempIOBuf = Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
2452     /* Decrement the submit count for the IO buffers                          */
2453     chanHandle->submitCount--;
2455     chanHandle->isTempIOBufValid = TRUE;
2456     chanHandle->tempIOBuf->status = chanHandle->currentError;
2457     Mcbsp_localCompleteCurrentIo(chanHandle);
2459     /* critical section ends                                                  */
2460     Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
2464 #endif /* #ifndef MCBSP_LOOPJOB_ENABLE */
2467 /**
2468  * \brief  This function toggles the index of the edma params
2469  *
2470  * \param  index [IN]  pointer to current index
2471  *
2472  * \return None
2473  *
2474  * \enter  index is a valid non null pointer
2475  *
2476  * \leave  Not implemented
2477  */
2478 void Mcbsp_localGetNextIndex(uint32_t *index)
2480     *index = (((*index) + 1u) & 0x01u);
2483 /**
2484  *  \brief  This function loads the buffers to the actual EDMA paramset.
2485  *
2486  *  \param  chanHandle [IN]  Handle to channel.
2487  *  \param  ioBuf      [IN]  pointer to the ioBuf
2488  *
2489  *  \return None
2490  *
2491  *  \enter  Not implemented
2492  *
2493  *  \leave  Not implemented
2494  */
2495 void Mcbsp_localLoadPktToEdma(Mcbsp_ChannelObj *chanHandle,Mcbsp_IOBuf *ioBuf)
2497 #ifndef MCBSP_LOOPJOB_ENABLE
2498     Mcbsp_Object_Unpadded *instHandle  = NULL;
2499 #endif
2500     int32_t             status      = MCBSP_STATUS_COMPLETED;
2502 #ifndef MCBSP_LOOPJOB_ENABLE
2503     instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
2504 #endif
2506     chanHandle->currentDataSize = (uint16_t)ioBuf->size;
2507     chanHandle->userDataBufferSize = (uint32_t)ioBuf->size;
2508     
2509 #ifdef MCBSP_LOOPJOB_ENABLE
2510     if (Mcbsp_MAXLINKCNT == chanHandle->submitCount)
2511     {
2512 #else
2513     /* The second and the third buffer will go the link paramsets             */
2514     if (Mcbsp_MAXLINKCNT <= chanHandle->submitCount)
2515     {
2516 #endif
2517         /* Though we have to post to param set directly from here,            *
2518          * there will be differene between first such buffer and              *
2519          * second buffer. As we have control here we are second buffer        *
2520          * and first buffer has not yet returned (or corresponding            *
2521          * edma callback has not been called.For second buffer, we            *
2522          * will be updating the second param set, which is currently          *
2523          * hosting loopjob parameter. Hence increment the index to            *
2524          * point second paramset and since we are moving out loopjob          *
2525          * from both param sets, the loopjobUpdatedinParamset is reset        */
2526         chanHandle->loopjobUpdatedinParamset = FALSE;
2527         Mcbsp_localGetNextIndex(
2528             &chanHandle->nextLinkParamSetToBeUpdated);
2529     }
2530     
2531     /* Now update the data buffer to the link params. The paramset to         *
2532      * be updated is decidec by the "nextLinkParamSetToBeUpdated"             */
2533     if (MCBSP_STATUS_COMPLETED != Mcbsp_localUpdtDtPktToLnkPrms(chanHandle,ioBuf))
2534     {
2535         status = MCBSP_ERR_BADIO;
2536     }
2537     
2538     if ((1u == chanHandle->submitCount) && (MCBSP_STATUS_COMPLETED == status))
2539     {
2540 #ifdef MCBSP_LOOPJOB_ENABLE
2541         /* if at all this is the very first buffer, then one param set        *
2542          * has loop job loaded , self linked and active with the main         *
2543          * xfer channel param. other param set is ready loaded (just          *
2544          * now)and has link param set as the one having loopjob (this         *
2545          * is to ensure that if at all we are not getting any more            *
2546          * buffers loopjob be will taken over). Now we have to link           *
2547          * the floating / newly loaded param set to xfer channel.             */
2548         if (MCBSP_STATUS_COMPLETED != EDMA3_DRV_linkChannel(
2549                                  chanHandle->edmaHandle,
2550                                  chanHandle->xferChan,
2551                                  chanHandle->pramTbl[chanHandle->nextLinkParamSetToBeUpdated]))
2552         {
2553             status = MCBSP_ERR_BADIO;
2554         }
2555 #else
2556         /* configure the FIFO for the specific channel                        */
2557         if (TRUE == chanHandle->enableHwFifo)
2558         {
2559             /* Disable and enable the FIFO so that the events are             *
2560              * generated to the Mcbsp for the first time                      */
2561             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,FALSE);
2562             mcbspConfigureFifo(&instHandle->hwInfo,chanHandle,TRUE);
2563         }
2565         /* enable the EDMA transfer for the channel so that it is             *
2566          * ready to transfer the data as soon as the state machine is         *
2567          * enabled                                                            */
2568         EDMA3_DRV_enableTransfer(
2569             chanHandle->edmaHandle,
2570             chanHandle->xferChan,
2571             EDMA3_DRV_TRIG_MODE_EVENT);
2573         /* Start the McBSP hardware                                           */
2574         if (MCBSP_MODE_INPUT == chanHandle->mode)
2575         {
2576             instHandle->stopSmFsRcv = FALSE;
2577             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_RX_ENABLE);
2578         }
2579         else
2580         {
2581             instHandle->stopSmFsXmt = FALSE;
2582             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_TX_ENABLE);
2583         }
2585         if (((MCBSP_MODE_INPUT == chanHandle->mode) && 
2586             (TRUE == instHandle->rxFsgEnable)) ||
2587             ((MCBSP_MODE_OUTPUT == chanHandle->mode) &&
2588              (TRUE == instHandle->txFsgEnable)))
2589         {
2590             /* enable the sample rate generator                               */
2591             Mcbsp_localResetCtrl(
2592                 instHandle,
2593                 Mcbsp_SpcrCtrl_FSYNC_ENABLE);
2594         }
2595 #endif /* MCBSP_LOOPJOB_ENABLE */
2596     }
2599 /**
2600  * \brief   Function to modify the sample rate generator configuration
2601  *
2602  * \param   chanHandle  [IN]  Handle to the channel
2603  * \param   arg         [IN]  pointer to the srg config setup
2604  *
2605  * \return  None
2606  */
2607 int32_t Mcbsp_localModifySampleRate(Mcbsp_ChannelObj *chanHandle,void* arg)
2609     Mcbsp_Object_Unpadded *instHandle = NULL;
2610     Mcbsp_ClkSetup  *clkConfig  = NULL;
2611     int32_t            status     = MCBSP_STATUS_COMPLETED;
2613     if ((NULL == arg) || (NULL == chanHandle))
2614     {
2615         return MCBSP_ERR_BADARGS;
2616     }
2618     instHandle = &(chanHandle->devHandle->obj);
2619     if (NULL == instHandle)
2620     {
2621         return MCBSP_ERR_BADARGS;
2622     }
2624     clkConfig = (Mcbsp_ClkSetup *)arg;
2626     /* check if the Frame sync clock is generated by the module               */
2627     if (TRUE == instHandle->srgConfigured)
2628     {
2629         /* Configure the McBSP with user supplied parameters                  */
2630         chanHandle->clkSetup = *(clkConfig);
2631         instHandle->srgConfigured = FALSE;
2633         /* stop the sample rate generator                             */
2634         if (TRUE == instHandle->srgEnabled)
2635         {
2636             Mcbsp_localResetCtrl(instHandle,Mcbsp_SpcrCtrl_SRG_DISABLE);
2637         
2638             status = Mcbsp_localConfigureSrgr(instHandle,chanHandle);
2639         
2640             if (MCBSP_STATUS_COMPLETED == status)
2641             {
2642                 /* enable the sample rate generator                   */
2643                 Mcbsp_localResetCtrl(
2644                     instHandle,
2645                     Mcbsp_SpcrCtrl_SRG_ENABLE);
2646         
2647                 /* wait for the 2CLKG clock cycles                    */
2648                 Mcbsp_osalWaitNBitClocks(2u);
2649             }
2650         
2651             /* clear the XSYNCERR (to be done only if TX is used)     */
2652             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
2653             {
2654                 /* Enable the TX section                              */
2655                 Mcbsp_localResetCtrl(
2656                     instHandle,
2657                     Mcbsp_SpcrCtrl_TX_ENABLE);
2658         
2659                 /* wait for 2 CLKR or CLX cycles                      */
2660                 Mcbsp_osalWaitNBitClocks(2u);
2661         
2662                 /* Disable the TX section to clear any XYNCERR        */
2663                 Mcbsp_localResetCtrl(
2664                     instHandle,
2665                     Mcbsp_SpcrCtrl_TX_DISABLE);
2666             }
2667         }
2668     }
2669     else
2670     {
2671         status = MCBSP_ERR_BADMODE;
2672         
2673         if (MCBSP_MODE_INPUT == chanHandle->mode)
2674         {
2675             if (TRUE != instHandle->rxSrgEnable)
2676             {
2677                     /* Since this mode does not use the sample rate generator, so
2678                      * there is no point in changing the sample rate. So return 
2679                      * with success*/
2680                                 status  = MCBSP_STATUS_COMPLETED;
2681             }
2682         }
2683         else
2684         {
2685             if (TRUE != instHandle->txSrgEnable)
2686             {
2687                     /* Since this mode does not use the sample rate generator, so
2688                      * there is no point in changing the sample rate. So return 
2689                      * with success*/
2690                     status      = MCBSP_STATUS_COMPLETED;
2691             }
2692         }
2693     }
2694     return (status);
2697 /* ========================================================================== */
2698 /*                             END OF FILE                                    */
2699 /* ========================================================================== */