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