PRSDK-3513 Modified xs file to build.
[keystone-rtos/mcbsp-lld.git] / src / mcbsp_edma.c
1 /*
2  * mcbsp_edma.c
3  *
4  * This file contains local functions for MCBSP driver which contain implemen-
5  * tation for EDMA operation specifc calls like starting an EDMA transfer for
6  * for McBSP peripheral, EDMA completion and/or error callbacks etc.
7  *
8  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
9  *
10  *
11  *  Redistribution and use in source and binary forms, with or without
12  *  modification, are permitted provided that the following conditions
13  *  are met:
14  *
15  *    Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  *
18  *    Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the
21  *    distribution.
22  *
23  *    Neither the name of Texas Instruments Incorporated nor the names of
24  *    its contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39 */
41 /*============================================================================*/
42 /*                              INCLUDE FILES                                 */
43 /*============================================================================*/
45 /* CSL-RLs required for MCBSP LLD */
46 #include <ti/csl/cslr_tpcc.h> // Freon only has cslr directory
48 /* MCBSP Types includes */
49 #include <mcbsp_types.h>
51 /* MCBSP LLD includes */
52 #include <ti/drv/mcbsp/mcbsp_drv.h>
53 #include <ti/drv/mcbsp/include/mcbsp_pvt.h>
55 /* MCBSP OSAL layer */
56 #include <mcbsp_osal.h>
60 /*============================================================================*/
61 /*                            IMPORTED VARIABLES                              */
62 /*============================================================================*/
64 extern far Mcbsp_TempBuffer Mcbsp_muteBuf[CSL_MCBSP_PER_CNT];
66 /*============================================================================*/
67 /*                          LOCAL FUNCTION PROTOTYPES                         */
68 /*============================================================================*/
70 int32_t mcbspIsValidIOBuf(Mcbsp_ChannelObj *chanHandle);
72 /*============================================================================*/
73 /*                             LOCAL VARIABLES                                */
74 /*============================================================================*/
76 #ifndef MCBSP_LOOPJOB_ENABLE
77 uint32_t Mcbsp_edmaChanNum;
78 uint32_t Mcbsp_dummyParamSetAddr;
80 /* Edma dummy function*/
81 void doNothing(uint32_t tcc, EDMA3_RM_TccStatus edmaStatus, void* appData)
82 {
83 /* DO NOTHING (This is a callback for the dummy transfer)                     */
84 }
85 #endif
86 /* ========================================================================== */
87 /*                          FUNCTION DEFINITIONS                              */
88 /* ========================================================================== */
90 /**
91  * \brief   Function to intialize and set up the edma for transfer.
92  *
93  *          This function does the following
94  *          1) Requests the EDMA channel from the edma driver.
95  *          2) Requests the link channels for linking (exclusive for tx & rx)
96  *          3) set up the param set of main xfer channel (for loopjob transfers)
97  *          4) set up the param sets of all link channel (for loopjob transfers)
98  *          5) link the last link channel to itself (this channel will be linked
99  *             to main xfer channel later and to supply the loopjob xfer
100  *             information infinely this is done so;
101  *          other link channels are setup here just for completion sake
102  *
103  * \param   chanHandle   [IN] Handle to the channel for which the edma is setup
104  *
105  * \return  status       MCBSP_STATUS_COMPLETED if is sucess
106  *                       error id in case of failure
107  *
108  */
109 int32_t Mcbsp_localSetupEdmaDuringOpen(Mcbsp_ChannelObj *chanHandle)
111     uint32_t              reqTcc      = EDMA3_DRV_TCC_ANY;
112     Bool                falsewhile  = TRUE;
113     uint32_t              linkCnt     = 0;
114     uint32_t              edmaChanNum = 0;
115     uint32_t              count       = 0;
116     int32_t               status      = MCBSP_STATUS_COMPLETED;
117 #ifndef MCBSP_LOOPJOB_ENABLE
118     EDMA3_RM_EventQueue queueNum    = 0;
119 #endif    
120     
122     do
123     {
124         falsewhile  = FALSE;
125         if (NULL == chanHandle)
126         {
127             return MCBSP_ERR_BADARGS;
128         }
130         /* request the transfer channel from the EDMA driver                  */
131         status = EDMA3_DRV_requestChannel(
132                      chanHandle->edmaHandle,
133                      &chanHandle->xferChan,
134                      &chanHandle->tcc,
135                      chanHandle->edmaEventQue,
136                      (chanHandle->edmaCallback),
137                      chanHandle);
139         if (MCBSP_STATUS_COMPLETED != status)
140         {
141             status = MCBSP_ERR_BADARGS;
142             break;
143         }
145         /* if there are any errors set in the EDMA clear them here            */
146         EDMA3_DRV_clearErrorBits(
147             chanHandle->edmaHandle,
148             chanHandle->xferChan);
150         /* Acquire the  PaRAM entries used for EDMA transfers linking         */
151         for (count = 0; count < Mcbsp_MAXLINKCNT; count++)
152         {
153             /* For requesting for a PaRam set                                 */
154             edmaChanNum = EDMA3_DRV_LINK_CHANNEL;
155             reqTcc = EDMA3_DRV_TCC_ANY;
157             status = EDMA3_DRV_requestChannel(
158                         chanHandle->edmaHandle,
159                         &edmaChanNum,
160                         &reqTcc,
161                         chanHandle->edmaEventQue,
162                         (chanHandle->edmaCallback),
163                         NULL);
165             if (MCBSP_STATUS_COMPLETED == status)
166             {
167                 chanHandle->pramTbl[count] = edmaChanNum;
169                 status = EDMA3_DRV_getPaRAMPhyAddr(
170                             chanHandle->edmaHandle,
171                             chanHandle->pramTbl[count],
172                             &(chanHandle->pramTblAddr[count]));
173             }
175             if (MCBSP_STATUS_COMPLETED != status )
176             {
177                 /* free the Synchonized EDMA channel                          */
178                 EDMA3_DRV_freeChannel(
179                     chanHandle->edmaHandle,
180                     chanHandle->xferChan);
182                 /* free the already allocated PaRAM entries                   */
183                 for (linkCnt = 0; linkCnt < count; linkCnt++)
184                 {
185                     EDMA3_DRV_freeChannel(
186                         chanHandle->edmaHandle,
187                         chanHandle->pramTbl[linkCnt]);
188                 }
190                 status = MCBSP_ERR_BADARGS;
191                 break;
192             }
193         }
194         
195 #ifndef MCBSP_LOOPJOB_ENABLE
196                 /* Configure for dummy PaRAM set*/
197         Mcbsp_edmaChanNum = EDMA3_DRV_LINK_CHANNEL;
198         reqTcc                    = EDMA3_DRV_TCC_ANY;
200         status = EDMA3_DRV_requestChannel(
201                     chanHandle->edmaHandle,
202                     &Mcbsp_edmaChanNum,
203                     &reqTcc,
204                     queueNum,
205                     &doNothing,
206                     NULL);
208         if (MCBSP_STATUS_COMPLETED == status)
209         {
210             status = EDMA3_DRV_getPaRAMPhyAddr(
211                         chanHandle->edmaHandle,
212                         Mcbsp_edmaChanNum,
213                         &Mcbsp_dummyParamSetAddr);
214         }
215 #endif        
217         /* Configure EDMA channels                                            */
218         if (MCBSP_STATUS_COMPLETED == status)
219         {
220             status = Mcbsp_localEdmaChanPaRAMsetup(chanHandle);
221         }
222     }while(falsewhile);
223     return status;
225 #ifdef MCBSP_LOOPJOB_ENABLE
226 /**
227  *  \brief   This calls the registered application callback for the current
228  *           receive request and processes the next request in queue.
229  *           This is a mcbsp edma callback function called in edma context
230  *
231  *  \param   tcc        [IN]  tcc number of EDMA
232  *  \param   edmaStatus [IN]  status of EDMA transaction
233  *  \param   data       [IN]  paramaters sent to EDMA ISR (chan handler)
234  *
235  *  \return  Nothing
236  *
237  *  \entry   tcc         should be a valid value
238  *           status      should be a valid value
239  *           data        should be a non NULL and valid pointer
240  *
241  *  \leave   Not implemented
242  */
243 void Mcbsp_localEdmaCallback(uint32_t tcc, EDMA3_RM_TccStatus edmaStatus, void* data)
245     Mcbsp_ChannelObj      *chanHandle = NULL;
246     EDMA3_DRV_PaRAMRegs    pramTbl    = {0};
247     int32_t                status     = MCBSP_STATUS_COMPLETED;
248     Mcbsp_IOBuf           *ioBuf      = NULL;
249     void*                  criticalSectionInfo;
251     chanHandle = (Mcbsp_ChannelObj *)data;
252     /* to remove the compiler warning                                         */
253     tcc= tcc;
255     /* critical section starts                                                */
256     criticalSectionInfo = Mcbsp_osalEnterMultipleCoreCriticalSection();
257     
258     if (TRUE != Mcbsp_osalQueueEmpty(chanHandle->ptrQFloatList))
259     {
260         /* should always have a buffer present because this callback is       *
261          * due to that buffer                                                 */
263         /* Get the buffer from the top of the queue (atommic operation)       */
264         chanHandle->tempIOBuf = Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
266         /* get the param table information of transfer channel                */
267         EDMA3_DRV_getPaRAM(chanHandle->edmaHandle,chanHandle->xferChan,&pramTbl);
269         /* Handle the I/O buffers appropriately in case of an breakpoint      *
270          * in case of an breakpoint.either of the buffers (2 link param Pkts) *
271          * could have caused a callback as both of them as linkedto each other*
272          * Hence we will handle that condition here                           */
273         if (chanHandle->mode == MCBSP_MODE_INPUT)
274         {
275             /* Check if destination address falls into the range of 1st req   *
276              * in the floating queue.                                         */
277             if (((pramTbl.destAddr >= (uint32_t)chanHandle->tempIOBuf->addr)
278                 && (pramTbl.destAddr < (uint32_t)chanHandle->tempIOBuf->addr
279                         + chanHandle->tempIOBuf->size)) &&
280                                         (FALSE == Mcbsp_osalQueueEmpty(chanHandle->ptrQFloatList)))                        
281             {
282                 /* Since we have already dequeue the 1st request, dequeue     *
283                  * 2nd io request from floating queue                         */
284                 ioBuf = (Mcbsp_IOBuf *)Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
286                 /* Queue the tempIOBuf (i.e. 1st io request) as this pkt     *
287                  * should be first in a queue                                 */
288                 Mcbsp_osalQueuePut(
289                     chanHandle->ptrQFloatList,
290                     (void*)chanHandle->tempIOBuf);
292                 /* Queue the ioBuf i.e. 2nd request in floating queue      */
293                 Mcbsp_osalQueuePut(chanHandle->ptrQFloatList,(void*)ioBuf);
294             }
295         }
296         else
297         {
298             /* Check if destination address falls into the range of1st request*
299              * in the floating queue.                                         */
300             if (((pramTbl.srcAddr >= (uint32_t)chanHandle->tempIOBuf->addr)&& 
301                 (pramTbl.srcAddr < (uint32_t)chanHandle->tempIOBuf->addr + chanHandle->tempIOBuf->size)) && 
302                         (FALSE == Mcbsp_osalQueueEmpty(chanHandle->ptrQFloatList)))
303             {
304                 /* Since we have already dequeue the 1st request, dequeue     *
305                  * io request from floating queue                             */
306                 ioBuf = (Mcbsp_IOBuf *)Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
308                 /* Queue the tempIOBuf (i.e. 1st io request) as this         *
309                  * buffer should be first in a queue                         */
310                 Mcbsp_osalQueuePut(
311                     chanHandle->ptrQFloatList,
312                     (void*)chanHandle->tempIOBuf);
314                 /* Queue the ioBuf i.e. 2nd request in floating queue      */
315                 Mcbsp_osalQueuePut(chanHandle->ptrQFloatList,(void*)ioBuf);
316                 status = MCBSP_ERR_NOIOBUFFERS;
317             }
318         }
320         if (MCBSP_STATUS_COMPLETED == status)
321         {
322             if (EDMA3_RM_XFER_COMPLETE != edmaStatus)
323             {
324                 /* update the status of the IOP as error                      */
325                 chanHandle->tempIOBuf->status = MCBSP_ERR_ABORT;
327                 /* There is a data transfer error in EDMA transfer. clear the *
328                  * Error bits and return                                      */
329                 EDMA3_DRV_clearErrorBits(
330                     chanHandle->edmaHandle,
331                     chanHandle->xferChan);
332             }
333             else
334             {
335                 chanHandle->tempIOBuf->status  = MCBSP_STATUS_COMPLETED;
336             }
338             chanHandle->submitCount--;
339         }
340 #ifdef MCBSP_LOOP_PING_PONG
341         if(MCBSP_STATUS_COMPLETED == status)
342         {
343                 /* Put back the buffer in the queue */
344             chanHandle->submitCount++;
345                 /* Queue the tempIOBuf                         */
346                 Mcbsp_osalQueuePut(
347                     chanHandle->ptrQFloatList,
348                     (void*)chanHandle->tempIOBuf);
349         }
350 #endif
352         if (MCBSP_STATUS_COMPLETED == status)
353         {
354 #ifndef MCBSP_LOOP_PING_PONG
355             /* if the channel is not in a pause mode                          */
356             if (FALSE == chanHandle->paused)
357             {
358                 /* Now that we have done with the last data buffer - we check *
359                  * if next buffer is available for transmission. Even if we   *
360                  * are not having a valid buffer - previous programming of    *
361                  * linkchannels (designed in such a way) to send out null     *
362                  * buffer Also note that Mcbsp_localIsValidIOBuf function     *
363                  * will set the chanHandle->dataIOBuf with next (current now) *
364                  * data buffer from queue                                     */
365                 if ((Mcbsp_STATUS_VALID == (mcbspIsValidIOBuf(chanHandle))))
366                 {
367                     /* This is a valid data request. Call function to process *
368                      * it. If DMA cannot be programmed properly with request  *
369                      * contents, abort all queued up requests and put state   *
370                      * M/C into reset.                                        */
371                     status = Mcbsp_localEdmaProcessPkt(
372                                  chanHandle,
373                                  chanHandle->dataIOBuf);
375                     if (MCBSP_STATUS_COMPLETED != status)
376                     {
377                         Mcbsp_localCancelAndAbortAllIo(chanHandle);
378                     }
379                 }
380                 else
381                 {
383                     Mcbsp_localGetNextIndex(
384                         &chanHandle->nextLinkParamSetToBeUpdated);
386                    /* The following function will assign loopjob buffer to    *
387                     * free param set Also the control will come here two times*
388                     * for last buffer and last but one buffer (obviously for  *
389                     * more than one buffer xfer) For last but buffer callback *
390                     * itself we will come to know that there is no more buffer *
391                     * pending and hence we load loopjob info into next param  *
392                     * set and for the last buffer callback will not do it     *
393                     * again (for only one buffer scenario the following flag  *
394                     * will take care not to update the loopjob second time)   */
395                     if (FALSE  == chanHandle->loopjobUpdatedinParamset)
396                     {
397                         chanHandle->loopjobUpdatedinParamset = TRUE;
399                         Mcbsp_localUpdtDtPktToLnkPrms(chanHandle,NULL);
400                     }
401                 }
402             }
403             else
404 #else
405             if (TRUE == chanHandle->paused)
406 #endif
407             {
408                 /* Control will come over here when either of receive or      *
409                  * transmit state  machine stop command is issued for receive *
410                  * or transmit channel. If the nextFlag is already set        *
411                  * indicates that its time to reset the state machines and    *
412                  * disable the edma transfer                                  */
413                 if (TRUE == chanHandle->nextFlag)
414                 {
415                     chanHandle->nextFlag = FALSE;
416                 }
417                 else
418                 {
419                     /* For the first time when the stop port command is issued*
420                      * we will have one more buffer linked with the transfer  *
421                      * channel. So we will not stop at this time. We link the *
422                      * buffer with NULL loopjob buffer and set a nextFlag to  *
423                      * TRUE. We will wait for another callback(indicating the *
424                      * io request is complete) to disable EDMA transfer and   *
425                      * reset state  machines                                  */
426                     chanHandle->nextFlag = TRUE;
428                     Mcbsp_localGetNextIndex(&chanHandle->nextLinkParamSetToBeUpdated);
430                     Mcbsp_localUpdtDtPktToLnkPrms(chanHandle, NULL);
431                 }
432             }
433             if (MCBSP_STATUS_COMPLETED == status)
434             {
435                 chanHandle->isTempIOBufValid = TRUE;
436                 Mcbsp_localCompleteCurrentIo(chanHandle);
437             }
438         }
439         else if (MCBSP_ERR_NOIOBUFFERS == status)
440         {
441             /* Handle Underflow condition */
442             chanHandle->isTempIOBufValid = TRUE;
443             chanHandle->tempIOBuf = NULL;
444             Mcbsp_localCompleteCurrentIo(chanHandle);
445         }
446     }
447     /* critical section ends                                          */
448     Mcbsp_osalExitMultipleCoreCriticalSection(criticalSectionInfo);
452 /*!
453  *  \brief  This function updates the link param set accordingly with data or
454  *          loopjobbuffer. This uses properly maintained index to identify to
455  *          what param set the info has to be updated.
456  *
457  *  \param  chanHandle  [IN]  Handle to the mcbsp channel
458  *  \param  ioBuf       [IN]  Pointer to I/O buffer
459  *
460  *  \return MCBSP_STATUS_COMPLETED in case of sucess
461  *          else Error code in case of failure
462  *
463  *  \entry  chanHandle  should be non NULL and valid pointer
464  *          ioBuf       should be non NULL and valid pointer
465  *
466  *  \leave  Not implemented
467  */
468 int32_t Mcbsp_localUpdtDtPktToLnkPrms(Mcbsp_ChannelObj *chanHandle,
469                                     Mcbsp_IOBuf *const ioBuf)
471     Mcbsp_Object_Unpadded *instHandle  = NULL;
472     EDMA3_DRV_PaRAMRegs    pramPtr     = {0};
473     Bool                   falsewhile  = TRUE;
474     int32_t                status      = MCBSP_STATUS_COMPLETED;
475     EDMA3_DRV_SyncType     syncType;
477     do
478     {
479         falsewhile = FALSE;
480         if ((NULL == chanHandle) || (NULL == chanHandle->devHandle))
481         {
482             return MCBSP_ERR_BADARGS;
483         }
485         instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
486         if (NULL == instHandle)
487         {
488             return MCBSP_ERR_BADARGS;
489         }
491         /* if at all this is the first buffer we will update the main params  *
492          * else we will update the link params                                */
493         status = EDMA3_DRV_getPaRAM(
494                     chanHandle->edmaHandle,
495                     chanHandle->pramTbl[chanHandle->nextLinkParamSetToBeUpdated],
496                     &pramPtr);
497         if (MCBSP_STATUS_COMPLETED != status )
498         {
499             status = MCBSP_ERR_BADARGS;
500             break;
501         }
503     /* Following the explanation behind the EDMA configuration                *
504      * 1) We will have n arrays of data (now it is data buffer each of length *
505      *    databuffersize bytes)                                               *
506      * 2) for each sync event we have to fetch the data from each array and   *
507      *    write to each slot                                                  *
508      * 3) and the no. bytes transferred in this case from each array will be  *
509      *    roundedwordwidth/4                                                  *
510      * 4) as the loopjob buffer is contigous, we configure the counts as      *
511      *    follows                                                             *
512      *    a) consider there are arrays of length roundedwordwidth/4 (aCnt)    *
513      *    b) these arrays are located apart databuffersize size  (bindex)     *
514      *    c) there are 'no.of.slots' no. of such arrays   (bCnt)              *
515      *    d) (a) and (b) constitute one frame of EDMA transfer and it happens *
516      *       for one sync event in AB sync mode.                              *
517      *    e) such frames have to be sent till we have buffer - ie             *
518      *       databuffersize / (roundedwordwidth/8 ) and this constitutes  cCnt*
519      *    f) address of buffer (rather offset from start of previous frame)   *
520      *       is roundedwordwidth/8  and this forms cIndex                     *
521      *                                                                        *
522      *  Please take some time to visualise the setup mentioned above to check *
523      *  with EDMA configuration                                               *
524      *  Also we change only specific parameters because others will not have  *
525      *  change from what we programed  intially                               */
527     /* control will reach this function is two contexts                       *
528      * 1) From submitreq function for first time buffers                      *
529      * 2) From EDMA callback for further handling of buffers in Queue         *
530      *    - we are from EDMA callback becuase we have completed some user     *
531      *   data buffer just now                                                 */
533         if (NULL != ioBuf)
534         {
535             /* 1) when control comes to this function from submitreq control  *
536              *    will surely comeinto the block                              *
537              * 2) When control comes to this function from EDMA callback,     *
538              *    control will some only if there is fuirther more buffers to *
539              *     handle                                                     */
540             if (MCBSP_MODE_INPUT == chanHandle->mode)
541             {
542                 pramPtr.destAddr = (uint32_t)ioBuf->addr;
543                 Mcbsp_localGetIndicesSyncType(
544                     chanHandle,
545                     &(pramPtr.destBIdx),
546                     &(pramPtr.destCIdx),
547                     &(pramPtr.aCnt),
548                     &(pramPtr.bCnt),
549                     &(pramPtr.cCnt),
550                     &syncType,
551                     FALSE);
552             }
553             else
554             {
555                 if (TRUE == chanHandle->bMuteON)
556                 {
557                     /* Mute is set hence we need to switch to the mute buffer */
558                     pramPtr.srcAddr =
559                         (uint32_t)&Mcbsp_muteBuf[instHandle->instNum].scratchBuffer;
560                     Mcbsp_localGetIndicesSyncType(
561                         chanHandle,
562                         &(pramPtr.srcBIdx),
563                         &(pramPtr.srcCIdx),
564                         &(pramPtr.aCnt),
565                         &(pramPtr.bCnt),
566                         &(pramPtr.cCnt),
567                         &syncType,
568                         TRUE);
569                 }
570                 else
571                 {
572                     pramPtr.srcAddr = (uint32_t)ioBuf->addr;
573                     Mcbsp_localGetIndicesSyncType(
574                         chanHandle,
575                         &(pramPtr.srcBIdx),
576                         &(pramPtr.srcCIdx),
577                         &(pramPtr.aCnt),
578                         &(pramPtr.bCnt),
579                         &(pramPtr.cCnt),
580                         &syncType,
581                         FALSE);
582                 }
583             }
585             /* Here we are enabling the interrupt for this param set info     *
586              * we do it here in this way because using int enable API after   *
587              * calling EDMA3_DRV_setPaRAM, may fail our intention. This is    *
588              * because immediately after the set param the paramset might be  *
589              * copied to linked param and will make the consecutive int enable*
590              * (set opt field) api useless for our purpose                    */
591             pramPtr.opt |= (0x01u<<20u);
593             /* we are loading data request in the param set. As per our design*
594              * when we load the data,  we should link this param set with next*
595              * one most probably                                              *
596              *  a) That may have loopjob loaded                               *
597              *  b) it may be the currently loaded set, which will be updated  *
598              *     in next edma callback.                                     *
599              * hence in both cases to be run next to this data request        */
600             pramPtr.linkAddr =
601               (uint16_t)(chanHandle->pramTblAddr[ \
602               ((chanHandle->nextLinkParamSetToBeUpdated+1) & 0x01)] & 0x0000FFFF);
603         }
604         else
605         {
606             /* we have reached here becuase we dont have any more buffer to  *
607              * submit for Xfer assign loop job to params- no change in linking*
608              * IMP: The following assignment will be skipped if already both  *
609              * params are having  loopjob buffer                              */
610             if (MCBSP_MODE_INPUT == chanHandle->mode)
611             {
612                 pramPtr.destAddr = (uint32_t)chanHandle->loopJobBuffer;
613                 Mcbsp_localGetIndicesSyncType(
614                     chanHandle,
615                     &(pramPtr.destBIdx),
616                     &(pramPtr.destCIdx),
617                     &(pramPtr.aCnt),
618                     &(pramPtr.bCnt),
619                     &(pramPtr.cCnt),
620                     &syncType,
621                     TRUE);
622             }
623             else
624             {
625                 pramPtr.srcAddr = (uint32_t)chanHandle->loopJobBuffer;
626                 Mcbsp_localGetIndicesSyncType(
627                     chanHandle,
628                     &(pramPtr.srcBIdx),
629                     &(pramPtr.srcCIdx),
630                     &(pramPtr.aCnt),
631                     &(pramPtr.bCnt),
632                     &(pramPtr.cCnt),
633                     &syncType,
634                     TRUE);
635             }
637             /* we are loading loopjob into this param.  That means we have    *
638              * reached the end of buffers inpending and floating queues. So   *
639              * this loopjob had to be  linked to itself. Also we need to point*
640              * the index to other param set in order to load data request     *
641              * directly from submit call                                      */
642             pramPtr.linkAddr =
643                 (uint16_t)(chanHandle->pramTblAddr[    \
644                 chanHandle->nextLinkParamSetToBeUpdated] & 0x0000FFFF);
646             pramPtr.opt &= (~(0x01<<20));
647         }
649         /* Update the changed param set info into the appropriate paramset    */
650         status = EDMA3_DRV_setPaRAM(
651                     chanHandle->edmaHandle,
652                     chanHandle->pramTbl[chanHandle->nextLinkParamSetToBeUpdated],
653                     &pramPtr);
654         if (MCBSP_STATUS_COMPLETED != status)
655         {
656             status = MCBSP_ERR_BADARGS;
657             break;
658         }
660         if (NULL == ioBuf)
661         {
662             /* we are loading loopjob into this param. we need to point the   *
663              * index to other param set in order to load data request directly*
664              * from submit call                                               */
665             Mcbsp_localGetNextIndex(&chanHandle->nextLinkParamSetToBeUpdated);
666         }
667     }while(falsewhile);
669     return status;
672 /**
673  * \brief   setup the EDMA channel for the specific channel requested.
674  *
675  *          This function configures the McBSP synchonized EDMA channel PaRAM
676  *          entries it also configures the various other parameters like
677  *          source and destination address / modes
678  *
679  * \param   chanHandle   [IN]   Channel handle
680  *
681  * \return  MCBSP_STATUS_COMPLETED  if setup successful
682  *          Appropriate MCBSP driver error code if configuration has any error
683  */
684 int32_t Mcbsp_localEdmaChanPaRAMsetup(Mcbsp_ChannelObj *chanHandle)
686     uint32_t               linkCnt    = 0;
687     Mcbsp_Object_Unpadded *instHandle = NULL;
688     EDMA3_DRV_PaRAMRegs  paramSet   = {0,0,0,0,0,0,0,0,0,0,0,0};
689     int32_t              status     = MCBSP_STATUS_COMPLETED;
690     EDMA3_DRV_SyncType   tempSyncType;
692     if ((NULL == chanHandle) || (NULL == chanHandle->devHandle))
693     {
694         return MCBSP_ERR_BADARGS;
695     }
697     instHandle = &(chanHandle->devHandle->obj);
698     if (NULL == instHandle)
699     {
700         return MCBSP_ERR_BADARGS;
701     }
703     /* Configure the McBSP synchonized EDMA channel PaRAM entries             *
704      * Configure source and destination address / modes                       *
705      * first - main xfer channel                                              */
707     /* following is the explanation behind the EDMA configuration             *
708      *
709      *  1) We will have n arrays of data (now it is loopjob buffer each of    *
710      *     length x bytes)                                                    *
711      *  2) for each sync event we have to fetch the data from each array      *
712      *     and write to each serilaiser                                       *
713      *  3) and the no. bytes transferred in this case from each array will    *
714      *     be roundedwordwidth/4                                              *
715      *  4) as the loopjob buffer is continous, we configure the counts as     *
716      *     follows                                                            *
717      *     a) consider there are arrays of length roundedwordwidth/8(aCnt)    *
718      *     b) these arrays are located apart lengthofloopjob size (bindex)    *
719      *     c) there are 'no.of.slots' no. of such arrays  (bCnt)              *
720      *     d) (a) and (b) constitute one frame of EDMA transfer and it        *
721      *        happens for one sync event in AB sync mode                      *
722      *     e) such frames have to be sent till we have buffer - ie            *
723      *        lengthofloopjob / (roundedwordwidth/8 )  and this               *
724      *        constitutes  cCnt                                               *
725      *     f) address of buffer (rather offset from start of previous         *
726      *         frame) is roundedwordwidth/8 and this forms cIndex             *
727      *  Please take some time to visualise the setup mentioned above to       *
728      *  check with EDMA configuration The same kind of setup will be used     *
729      *  for data transfers also and the change will be buffer pointer         *
730      *  and length of data buffer.                                            */
732     /* Get the PaRAM set for default parameters                               */
733     EDMA3_DRV_getPaRAM(chanHandle->edmaHandle,chanHandle->xferChan,&paramSet);
735     if (MCBSP_MODE_INPUT == chanHandle->mode)
736     {
737         /* Configuring Source and Dest addresses                              */
738         if (TRUE == chanHandle->enableHwFifo)
739         {
740             paramSet.srcAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
741         }
742         else
743         {
744             paramSet.srcAddr = (uint32_t)&(instHandle->hwInfo.regs->DRR);
745         }
746 #ifdef _BIG_ENDIAN
747         paramSet.srcAddr += (4 - chanHandle->roundedWordWidth);
748 #endif
749         paramSet.destAddr = (unsigned int)(chanHandle->loopJobBuffer);
751         /* Configuring Src and Dest B&C Indexes                               */
752         paramSet.srcBIdx  = 0;
753         paramSet.srcCIdx  = 0;
755         if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
756                                  chanHandle,
757                                  &paramSet.destBIdx,
758                                  &paramSet.destCIdx,
759                                  &paramSet.aCnt,
760                                  &paramSet.bCnt,
761                                  &paramSet.cCnt,
762                                  &tempSyncType,
763                                  TRUE))
764         {
765             status = MCBSP_ERR_BADARGS;
766         }
767     }
768     else
769     {
770         /* Configuring Source and Dest addresses                              */
771         paramSet.srcAddr  = (unsigned int)(chanHandle->loopJobBuffer);
773         if (TRUE == chanHandle->enableHwFifo)
774         {
775             paramSet.destAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
776         }
777         else
778         {
779             paramSet.destAddr = (uint32_t)&(instHandle->hwInfo.regs->DXR);
780         }
781 #ifdef _BIG_ENDIAN
782         paramSet.destAddr += (4 - chanHandle->roundedWordWidth);
783 #endif
784         /* Configuring Src and Dest B&C Indexes                               */
785         paramSet.destBIdx = 0;
786         paramSet.destCIdx = 0;
788         if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
789                                  chanHandle,
790                                  &paramSet.srcBIdx,
791                                  &paramSet.srcCIdx,
792                                  &paramSet.aCnt,
793                                  &paramSet.bCnt,
794                                  &paramSet.cCnt,
795                                  &tempSyncType,
796                                  TRUE))
797         {
798             status = MCBSP_ERR_BADARGS;
799         }
800     }
803     /* Configuring bCntReload                                                 */
804     paramSet.bCntReload = paramSet.bCnt;
806     /* Src & Dest are in INCR modes                                           */
807     paramSet.opt &= 0xFFFFFFFCu;
809     /* FIFO width is 8 bit                                                    */
810     paramSet.opt &= 0xFFFFF8FFu;
812     /* Set EDMA3_DRV_OPT_FIELD_TCINTEN to FALSE                               */
813     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_ITCINTEN_MASK));
815     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_TCINTEN_MASK));
816     paramSet.opt |= (CSL_TPCC_PARAM_OPT_TCINTEN_DISABLE
817                         << CSL_TPCC_PARAM_OPT_TCINTEN_SHIFT);
819     /* Program the TCC                                                        */
820     paramSet.opt |= ((chanHandle->tcc << CSL_TPCC_PARAM_OPT_TCC_SHIFT)
821                       & CSL_TPCC_PARAM_OPT_TCC_MASK);
823     /* EDMA3_DRV_SYNC_AB                                                      */
824     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_SYNCDIM_MASK));
825     paramSet.opt |= (tempSyncType << CSL_TPCC_PARAM_OPT_SYNCDIM_SHIFT);
827     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_TCCMOD_MASK));
828     paramSet.opt |= (1 << CSL_TPCC_PARAM_OPT_TCCMOD_SHIFT);
830     /* Now, write the PaRAM Set.                                              */
831     status = EDMA3_DRV_setPaRAM(
832                   chanHandle->edmaHandle,
833                   chanHandle->xferChan,
834                   &paramSet);
836     if (MCBSP_STATUS_COMPLETED == status)
837     {
838         /* Configure the link PaRAMs with the appropriate parameters Though   *
839          * we configure all the link paramsets, we will be using only one of  *
840          * them to link with main xfer channel                                */
841         for (linkCnt = 0; linkCnt < Mcbsp_MAXLINKCNT; linkCnt++)
842         {
843             /* Get the PaRAM set for default parameters                       */
844             EDMA3_DRV_getPaRAM (chanHandle->edmaHandle,
845                                 chanHandle->pramTbl[linkCnt],
846                                 &paramSet);
848             if (MCBSP_MODE_INPUT == chanHandle->mode)
849             {
850                 /* Configuring Source and Dest addresses                      */
851                 if (TRUE == chanHandle->enableHwFifo)
852                 {
853                     paramSet.srcAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
854                 }
855                 else
856                 {
857                     paramSet.srcAddr = (uint32_t)&(instHandle->hwInfo.regs->DRR);
858                 }
859 #ifdef _BIG_ENDIAN
860                 paramSet.srcAddr += (4 - chanHandle->roundedWordWidth);
861 #endif
862                 paramSet.destAddr = (uint32_t)(chanHandle->loopJobBuffer);
864                 /* Configuring Src and Dest B&C Indexes                       */
865                 paramSet.srcBIdx  = 0;
866                 paramSet.srcCIdx  = 0;
868                 if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
869                                          chanHandle,
870                                          &paramSet.destBIdx,
871                                          &paramSet.destCIdx,
872                                          &paramSet.aCnt,
873                                          &paramSet.bCnt,
874                                          &paramSet.cCnt,
875                                          &tempSyncType,
876                                          TRUE))
877                 {
878                     status = MCBSP_ERR_BADARGS;
879                 }
880             }
881             else
882             {
883                 /* Configuring Source and Dest addresses                      */
884                 paramSet.srcAddr  = (uint32_t)(chanHandle->loopJobBuffer);
886                 if (TRUE == chanHandle->enableHwFifo)
887                 {
888                     paramSet.destAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
889                 }
890                 else
891                 {
892                     paramSet.destAddr = (uint32_t)&(instHandle->hwInfo.regs->DXR);
893                 }
895 #ifdef _BIG_ENDIAN
896                 paramSet.destAddr += (4 - chanHandle->roundedWordWidth);
897 #endif
899                 paramSet.destBIdx  = 0;
900                 paramSet.destCIdx  = 0;
902                 if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
903                                          chanHandle,
904                                          &paramSet.srcBIdx,
905                                          &paramSet.srcCIdx,
906                                          &paramSet.aCnt,
907                                          &paramSet.bCnt,
908                                          &paramSet.cCnt,
909                                          &tempSyncType,
910                                          TRUE))
911                 {
912                     status = MCBSP_ERR_BADARGS;
913                 }
914             }
916             /* Configuring bCntReload                                         */
917             paramSet.bCntReload = paramSet.bCnt;
919             /* Src & Dest are in INCR modes                                   */
920             paramSet.opt &= 0xFFFFFFFCu;
922             /* FIFO width is 8 bit                                            */
923             paramSet.opt &= 0xFFFFF8FFu;
925             /* EDMA3_DRV_SYNC_AB                                              */
926             paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_SYNCDIM_MASK));
927             paramSet.opt |= (tempSyncType << CSL_TPCC_PARAM_OPT_SYNCDIM_SHIFT);
929             /* Set EDMA3_DRV_OPT_FIELD_TCINTEN to FALSE                       */
930             paramSet.opt |= (CSL_TPCC_PARAM_OPT_TCINTEN_DISABLE
931                                 << CSL_TPCC_PARAM_OPT_TCINTEN_SHIFT);
933             /* Program the TCC                                                */
934             paramSet.opt |= ((chanHandle->tcc << CSL_TPCC_PARAM_OPT_TCC_SHIFT)
935                               & CSL_TPCC_PARAM_OPT_TCC_MASK);
937             /* early completion interrupt                                     */
938             paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_TCCMOD_MASK));
939             paramSet.opt |= (1 << CSL_TPCC_PARAM_OPT_TCCMOD_SHIFT);
941             paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_TCINTEN_MASK));
943             if (MCBSP_STATUS_COMPLETED == status)
944             {
945                 /* Now, write the PaRAM Set.                                  */
946                 status = EDMA3_DRV_setPaRAM(chanHandle->edmaHandle,
947                                             chanHandle->pramTbl[linkCnt],
948                                             &paramSet);
949                 if (MCBSP_STATUS_COMPLETED != status)
950                 {
951                       status = MCBSP_ERR_BADARGS;
952                       break;
953                 }
954             }
956             if (Mcbsp_MAXLINKCNT - 1 > linkCnt )
957             {
958                 /* link with next paramset both param sets are  linked to each*
959                  * other to enable continous xfer - either user audio data or *
960                  * loopjob buffer MAXLINKCNT must be 2                        */
961                 status = EDMA3_DRV_linkChannel(
962                              chanHandle->edmaHandle,
963                              chanHandle->xferChan,
964                              chanHandle->pramTbl[linkCnt]);
966                  if (MCBSP_STATUS_COMPLETED != status)
967                  {
968                      status = MCBSP_ERR_BADARGS;
969                      break;
970                  }
972                  status = EDMA3_DRV_linkChannel(
973                              chanHandle->edmaHandle,
974                              chanHandle->pramTbl[linkCnt] ,
975                              chanHandle->pramTbl[linkCnt]);
977                  if (MCBSP_STATUS_COMPLETED != status)
978                  {
979                      status = MCBSP_ERR_BADARGS;
980                      break;
981                  }
983                  status = EDMA3_DRV_linkChannel(
984                              chanHandle->edmaHandle,
985                              chanHandle->pramTbl[linkCnt+1] ,
986                              chanHandle->pramTbl[linkCnt+1]);
988                  if (MCBSP_STATUS_COMPLETED != status)
989                  {
990                      status = MCBSP_ERR_BADARGS;
991                      break;
992                  }
994                  chanHandle->nextLinkParamSetToBeUpdated = 0;
996                  chanHandle->loopjobUpdatedinParamset  = TRUE;
997             }
998         }/*for loop for linkcount*/
999     }
1000     return (status);
1003 #else
1004 /**
1005  *  \brief   This calls the registered application callback for the current
1006  *           receive request and processes the next request in queue.
1007  *           This is a mcbsp edma callback function called in edma context
1008  *
1009  *  \param   tcc        [IN]  tcc number of EDMA
1010  *  \param   edmaStatus [IN]  status of EDMA transaction
1011  *  \param   data       [IN]  paramaters sent to EDMA ISR (chan handler)
1012  *
1013  *  \return  Nothing
1014  *
1015  *  \entry   tcc         should be a valid value
1016  *           status      should be a valid value
1017  *           data        should be a non NULL and valid pointer
1018  *
1019  *  \leave   Not implemented
1020  */
1021 void Mcbsp_localEdmaCallback(uint32_t tcc, EDMA3_RM_TccStatus edmaStatus, void* data)
1023     Mcbsp_Object_Unpadded *instHandle = NULL;
1024     Mcbsp_ChannelObj      *chanHandle = NULL;
1025     int32_t                status     = MCBSP_STATUS_COMPLETED;
1026     Bool                   falseWhile = TRUE;
1027     void*                  criticalSectionInfo;
1029     /* critical section starts                                        */
1030     criticalSectionInfo = Mcbsp_osalEnterSingleCoreCriticalSection();
1031     
1032     do
1033     {
1034         falseWhile = FALSE;
1036         chanHandle = (Mcbsp_ChannelObj *)data;
1038         if (1u == chanHandle->submitCount)
1039         {
1040             /* This is the last buffer available with the driver.Hence we will*
1041              * stop the EDMA and then proceed to process the buffer           */
1042             EDMA3_DRV_disableTransfer(
1043                 chanHandle->edmaHandle,
1044                 chanHandle->xferChan,
1045                 EDMA3_DRV_TRIG_MODE_EVENT);
1047             instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1049             /* close the IOP now                                              */
1050             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
1051             {
1052                 /* update the status of the IOP                               */
1053                 if (EDMA3_RM_XFER_COMPLETE != edmaStatus)
1054                 {
1055                     /* update the status of the IOP as error                  */
1056                     chanHandle->currentError = MCBSP_ERR_ABORT;
1057                 }
1058                 else
1059                 {
1060                     chanHandle->currentError = MCBSP_STATUS_COMPLETED;
1061                 }
1063                 Mcbsp_TxFifo((int32_t)&instHandle->xmtObj, (int32_t)instHandle);
1064                 
1065                 /* critical section ends                                      */
1066                 Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1067                             
1068                 break;
1069             }
1071             /* Stop the McBSP hardware.                                       *
1072              * 1. check if the RX has enabled the  FSG and also it is running *
1073              * 2. Also check that the TX state machine is not running off FSG */
1074             if (TRUE == instHandle->rxFsgEnable)
1075             {
1076                 if ((TRUE != instHandle->txFsgEnable) ||
1077                     (TRUE == instHandle->stopSmFsXmt))
1078                 {
1079                     Mcbsp_localResetCtrl(
1080                         (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj),
1081                             Mcbsp_SpcrCtrl_FSYNC_DISABLE);
1083                     instHandle->fsgEnabled = FALSE;
1084                 }
1085             }
1087             Mcbsp_localResetCtrl(
1088                 (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj),
1089                  Mcbsp_SpcrCtrl_RX_DISABLE);
1091             /* receive state machine is stopped                               */
1092             instHandle->stopSmFsRcv = TRUE;
1094             /* clear the error bits that have been set                        */
1095             EDMA3_DRV_clearErrorBits(
1096                 chanHandle->edmaHandle,
1097                 chanHandle->xferChan);            
1098         }
1099         else
1100         {
1101             /* critical section ends                                          */
1102             Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1103         }
1105         /* To remove the compiler warning                                     */
1106         tcc = tcc;
1108         if (EDMA3_RM_XFER_COMPLETE != edmaStatus)
1109         {
1110             /* clear the error bits that have been set                        */
1111             EDMA3_DRV_clearErrorBits(
1112                 chanHandle->edmaHandle,
1113                 chanHandle->xferChan);
1115             /* update the status of the IOP as error                          */
1116             chanHandle->currentError = MCBSP_ERR_ABORT;
1117             break;
1118         }
1119         else
1120         {
1121             chanHandle->currentError = MCBSP_STATUS_COMPLETED;
1123             /* reduce the submit count as the buffer callback is completed    */
1124             chanHandle->submitCount--;
1125         }
1128         if (TRUE == Mcbsp_osalQueueEmpty(chanHandle->ptrQFloatList))
1129         {
1130             /* This cannot happen, if it happens then it is a sprurios one    */
1131             /* critical section ends                                          */
1132             Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1133             break;
1134         }
1136         /* Get the buffer from the top of the queue (atomic operation)        */
1137         chanHandle->tempIOBuf = Mcbsp_osalQueueGet(chanHandle->ptrQFloatList);
1140         instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1142         /* check if the STOP command is issued for the channel. if the stop   *
1143          * command is issued we will not load the next buffer so that the     *
1144          * state machine is stopped                                           */
1145         if (((MCBSP_MODE_INPUT == chanHandle->mode) && (FALSE == instHandle->stopSmFsRcv)) ||
1146             ((MCBSP_MODE_OUTPUT == chanHandle->mode) && (FALSE == instHandle->stopSmFsXmt)))
1147         {
1148             /* now check if any other buffer is available and load that   */
1149             if ((Mcbsp_STATUS_VALID == (mcbspIsValidIOBuf(chanHandle))))
1150             {
1151                 /* Valid buffer is found,load the buffer in to link params*/
1152                 status = Mcbsp_localEdmaProcessPkt(
1153                              chanHandle,
1154                              chanHandle->dataIOBuf);
1156                 if (MCBSP_STATUS_COMPLETED != status)
1157                 {
1158                     Mcbsp_localCancelAndAbortAllIo(chanHandle);
1159                 }
1160             }
1161         }
1163         /* complete the IO pkt processing by calling the callback function    */
1164         chanHandle->isTempIOBufValid = TRUE;
1165         Mcbsp_localCompleteCurrentIo(chanHandle);
1167         /* critical section ends                                              */
1168         Mcbsp_osalExitSingleCoreCriticalSection(criticalSectionInfo);
1169     }while (falseWhile);
1170     
1173 /**
1174  *  \brief  This function updates the link param set accordingly with data or
1175  *          loopjobbuffer. This uses properly maintained index to identify to
1176  *          what param set the info has to be updated.
1177  *
1178  *  \param  chanHandle  [IN]  Handle to the mcbsp channel
1179  *  \param  ioBuf       [IN]  Pointer to I/O buffer
1180  *
1181  *  \return MCBSP_STATUS_COMPLETED in case of sucess
1182  *          else Error code in case of failure
1183  *
1184  *  \entry  chanHandle  should be non NULL and valid pointer
1185  *          ioBuf       should be non NULL and valid pointer
1186  *
1187  *  \leave  Not implemented
1188  */
1189 int32_t Mcbsp_localUpdtDtPktToLnkPrms(Mcbsp_ChannelObj *chanHandle,
1190                                     Mcbsp_IOBuf       *const ioBuf)
1192     Mcbsp_Object_Unpadded *instHandle  = NULL;
1193     EDMA3_DRV_PaRAMRegs   pramPtr     = {0};
1194     Bool                  falsewhile  = TRUE;
1195     int32_t                 status      = MCBSP_STATUS_COMPLETED;
1196     EDMA3_DRV_SyncType    syncType;
1197     EDMA3_DRV_PaRAMRegs   paramSet    = {0,0,0,0,0,0,0,0,0,0,0,0};    
1199     do
1200     {
1201         falsewhile = FALSE;
1202         if ((NULL == chanHandle) || (NULL == chanHandle->devHandle))
1203         {
1204             return MCBSP_ERR_BADARGS;
1205         }
1207         instHandle = (Mcbsp_Object_Unpadded *)&(chanHandle->devHandle->obj);
1208         if (NULL == instHandle)
1209         {
1210             return MCBSP_ERR_BADARGS;
1211         }
1213         /* if at all this is the first buffer we will update the main params  *
1214          * else we will update the link params                                */
1215         if (1u == chanHandle->submitCount)
1216         {
1217             status = EDMA3_DRV_getPaRAM(
1218                          chanHandle->edmaHandle,
1219                          chanHandle->xferChan,
1220                          &pramPtr);
1221         }
1222         else
1223         {
1224             status = EDMA3_DRV_getPaRAM(
1225                          chanHandle->edmaHandle,
1226                          chanHandle->pramTbl[chanHandle->nextLinkParamSetToBeUpdated],
1227                          &pramPtr);
1228         }
1230         if (MCBSP_STATUS_COMPLETED != status )
1231         {
1232             status = MCBSP_ERR_BADARGS;
1233             break;
1234         }
1236         if (NULL != ioBuf)
1237         {
1238             if (MCBSP_MODE_INPUT == chanHandle->mode)
1239             {
1240                 if (TRUE == chanHandle->enableHwFifo)
1241                 {
1242                     pramPtr.srcAddr  = (uint32_t)(instHandle->hwInfo.dataAddress);
1243                 }
1244                 else
1245                 {
1246                     pramPtr.srcAddr = (uint32_t)&(instHandle->hwInfo.regs->DRR);
1247                 }
1248 #ifdef _BIG_ENDIAN
1249                 pramPtr.srcAddr += (4 - chanHandle->roundedWordWidth);
1250 #endif
1251                 pramPtr.destAddr = (uint32_t)ioBuf->addr;
1252                 Mcbsp_localGetIndicesSyncType(
1253                     chanHandle,
1254                     &(pramPtr.destBIdx),
1255                     &(pramPtr.destCIdx),
1256                     &(pramPtr.aCnt),
1257                     &(pramPtr.bCnt),
1258                     &(pramPtr.cCnt),
1259                     &syncType,
1260                     FALSE);
1261             }
1262             else
1263             {
1264                 if (TRUE == chanHandle->enableHwFifo)
1265                 {
1266                     pramPtr.destAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
1267                 }
1268                 else
1269                 {
1270                     pramPtr.destAddr = (uint32_t)&(instHandle->hwInfo.regs->DXR);
1271                 }
1272 #ifdef _BIG_ENDIAN
1273                 pramPtr.destAddr += (4 - chanHandle->roundedWordWidth);
1274 #endif
1275                 if (TRUE == chanHandle->bMuteON)
1276                 {
1277                     /* Mute is set hence we need to switch to the mute buffer */
1278                     pramPtr.srcAddr =
1279                         (uint32_t)&Mcbsp_muteBuf[instHandle->instNum].scratchBuffer;
1280                     Mcbsp_localGetIndicesSyncType(
1281                         chanHandle,
1282                         &(pramPtr.srcBIdx),
1283                         &(pramPtr.srcCIdx),
1284                         &(pramPtr.aCnt),
1285                         &(pramPtr.bCnt),
1286                         &(pramPtr.cCnt),
1287                         &syncType,
1288                         TRUE);
1289                 }
1290                 else
1291                 {
1292                     pramPtr.srcAddr = (uint32_t)ioBuf->addr;
1293                     Mcbsp_localGetIndicesSyncType(
1294                         chanHandle,
1295                         &(pramPtr.srcBIdx),
1296                         &(pramPtr.srcCIdx),
1297                         &(pramPtr.aCnt),
1298                         &(pramPtr.bCnt),
1299                         &(pramPtr.cCnt),
1300                         &syncType,
1301                         FALSE);
1302                 }
1303             }
1305             /* Here we are enabling the interrupt for this param set info     *
1306              * we do it here in this way because using int enable API after   *
1307              * calling EDMA3_DRV_setPaRAM, may fail our intention. This is    *
1308              * because immediately after the set param the paramset might be  *
1309              * copied to linked param and will make the consecutive int enable*
1310              * (set opt field) api useless for our purpose                    */
1311             pramPtr.opt |= (0x01u<<20u);
1313             /* early completion interrupt is enabled                          */
1314             pramPtr.opt &= (~(CSL_TPCC_PARAM_OPT_TCCMOD_MASK));
1315             pramPtr.opt |= (1 << CSL_TPCC_PARAM_OPT_TCCMOD_SHIFT);
1317             /* set the link address as 0xFFFF                                 */
1318             pramPtr.linkAddr = 0xFFFFu;
1320              if (MCBSP_MODE_OUTPUT == chanHandle->mode)
1321                         {
1322                                 status = EDMA3_DRV_getPaRAM (chanHandle->edmaHandle,
1323                                                                  Mcbsp_edmaChanNum,
1324                                                                  &paramSet);
1326                         paramSet.aCnt     = 1u;
1327                         paramSet.linkAddr = 0xFFFF;
1328                         paramSet.opt      &= ~(0x01 << 3);
1330                         if (MCBSP_STATUS_COMPLETED == status)
1331                         {
1332                                     /* Now, write the dummy PaRAM Set.                                    */
1333                                     status = EDMA3_DRV_setPaRAM(chanHandle->edmaHandle,
1334                                                                 Mcbsp_edmaChanNum,
1335                                                                 &paramSet);
1336                                 }
1337                         }
1338         }
1339         else
1340         {
1341             status = MCBSP_ERR_BADARGS;
1342             break;
1343         }
1345         if (1u == chanHandle->submitCount)
1346         {
1347             /* Configuring bCntReload                                         */
1348             pramPtr.bCntReload = pramPtr.bCnt;
1350             /* Src & Dest are in INCR modes                                   */
1351             pramPtr.opt &= 0xFFFFFFFCu;
1353             /* FIFO width is 8 bit                                            */
1354             pramPtr.opt &= 0xFFFFF8FFu;
1356             /* Set EDMA3_DRV_OPT_FIELD_TCINTEN to TRUE                        */
1357             pramPtr.opt |= (CSL_TPCC_PARAM_OPT_TCINTEN_ENABLE
1358                             << CSL_TPCC_PARAM_OPT_TCINTEN_SHIFT);
1360             /* Program the TCC                                                */
1361             pramPtr.opt |= ((chanHandle->tcc << CSL_TPCC_PARAM_OPT_TCC_SHIFT)
1362                               & CSL_TPCC_PARAM_OPT_TCC_MASK);
1364             /* EDMA3_DRV_SYNC_AB                                              */
1365             pramPtr.opt &= (~(CSL_TPCC_PARAM_OPT_SYNCDIM_MASK));
1366             pramPtr.opt |= (syncType << CSL_TPCC_PARAM_OPT_SYNCDIM_SHIFT);
1368             /* set the link address as dummy address for Tx and 0xFFFF for Rx */
1369             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
1370                         {
1371                                 pramPtr.linkAddr = 
1372                                                                  (uint16_t)(Mcbsp_dummyParamSetAddr & 0x0000FFFF);
1373                         }
1374                         else
1375                         {
1376                                 pramPtr.linkAddr = 0xFFFFu;
1377                         }
1379             /* early completion interrupt is enabled                          */
1380             pramPtr.opt &= (~(CSL_TPCC_PARAM_OPT_TCCMOD_MASK));
1381             pramPtr.opt |= (1 << CSL_TPCC_PARAM_OPT_TCCMOD_SHIFT);
1383             status = EDMA3_DRV_setPaRAM(
1384                         chanHandle->edmaHandle,
1385                         chanHandle->xferChan,
1386                         &pramPtr);
1387                         
1388         }
1389         else
1390         {
1391             status = EDMA3_DRV_setPaRAM(
1392                          chanHandle->edmaHandle,
1393                          chanHandle->pramTbl[chanHandle->
1394                              nextLinkParamSetToBeUpdated],
1395                          &pramPtr);
1396         }
1398         if (2u == chanHandle->submitCount)
1399         {
1400             /* link this paramset with the main channel                       */
1401             status = EDMA3_DRV_linkChannel(
1402                         chanHandle->edmaHandle,
1403                         chanHandle->xferChan,
1404                         chanHandle->pramTbl \
1405                         [chanHandle->nextLinkParamSetToBeUpdated]);
1407             if (MCBSP_STATUS_COMPLETED != status)
1408             {
1409                 status = MCBSP_ERR_BADIO;
1410                 break;
1411             }
1412             
1413             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
1414             {         
1415                         /* link the dummy transfer at the end of the link PaRAM           */
1416                         status = EDMA3_DRV_linkChannel(
1417                                     chanHandle->edmaHandle,
1418                                     chanHandle->pramTbl \
1419                                     [chanHandle->nextLinkParamSetToBeUpdated],
1420                                     Mcbsp_edmaChanNum);
1421                 
1422                         if (MCBSP_STATUS_COMPLETED != status)
1423                         {
1424                             status = MCBSP_ERR_BADIO;
1425                             break;
1426                         }            
1427                 }
1428         }
1430         /* link this paramset with the other paramset                         */
1431         if (3u == chanHandle->submitCount)
1432         {
1433             status = EDMA3_DRV_linkChannel(
1434                         chanHandle->edmaHandle,
1435                         chanHandle->pramTbl[
1436                             (chanHandle->nextLinkParamSetToBeUpdated + 1u) & 0x01u],
1437                         chanHandle->pramTbl \
1438                         [chanHandle->nextLinkParamSetToBeUpdated]);
1440             if (MCBSP_STATUS_COMPLETED != status)
1441             {
1442                 status = MCBSP_ERR_BADIO;
1443                 break;
1444             }
1445             
1446             if (MCBSP_MODE_OUTPUT == chanHandle->mode)
1447             {            
1448                     /* link the dummy transfer at the end of the link PaRAM           */
1449                     status = EDMA3_DRV_linkChannel(
1450                                 chanHandle->edmaHandle,
1451                                 chanHandle->pramTbl \
1452                                 [chanHandle->nextLinkParamSetToBeUpdated],
1453                                 Mcbsp_edmaChanNum);
1454         
1455                     if (MCBSP_STATUS_COMPLETED != status)
1456                     {
1457                         status = MCBSP_ERR_BADIO;
1458                         break;
1459                     }
1460             }
1461             
1462         }
1464         if (MCBSP_STATUS_COMPLETED != status)
1465         {
1466             status = MCBSP_ERR_BADARGS;
1467             break;
1468         }
1469     }while(falsewhile);
1470     return status;
1473 /**
1474  * \brief   setup the EDMA channel for the specific channel requested.
1475  *
1476  *          This function configures the McBSP synchonized EDMA channel PaRAM
1477  *          entries it also configures the various other parameters like
1478  *          source and destination address / modes
1479  *
1480  * \param   chanHandle   [IN]   Channel handle
1481  *
1482  * \return  MCBSP_STATUS_COMPLETED  if setup successful
1483  *          Appropriate MCBSP driver error code if configuration has any error
1484  */
1485 int32_t Mcbsp_localEdmaChanPaRAMsetup(Mcbsp_ChannelObj *chanHandle)
1487     uint32_t               linkCnt    = 0;
1488     Mcbsp_Object_Unpadded *instHandle = NULL;
1489     EDMA3_DRV_PaRAMRegs  paramSet   = {0,0,0,0,0,0,0,0,0,0,0,0};
1490     int32_t                status     = MCBSP_STATUS_COMPLETED;
1491     EDMA3_DRV_SyncType   tempSyncType;
1493     if ((NULL == chanHandle) || (NULL == chanHandle->devHandle))
1494     {
1495         return MCBSP_ERR_BADARGS;
1496     }
1498     instHandle = &(chanHandle->devHandle->obj);
1499     if (NULL == instHandle)
1500     {
1501         return MCBSP_ERR_BADARGS;
1502     }
1504     /* Configure the McBSP synchonized EDMA channel PaRAM entries             *
1505      * Configure source and destination address / modes                       *
1506      * first - main xfer channel                                              */
1508     /* following is the explanation behind the EDMA configuration             *
1509      *
1510      *  1) We will have n arrays of data (now it is loopjob buffer each of    *
1511      *     length x bytes)                                                    *
1512      *  2) for each sync event we have to fetch the data from each array      *
1513      *     and write to each serilaiser                                       *
1514      *  3) and the no. bytes transferred in this case from each array will    *
1515      *     be roundedwordwidth/4                                              *
1516      *  4) as the loopjob buffer is continous, we configure the counts as     *
1517      *     follows                                                            *
1518      *     a) consider there are arrays of length roundedwordwidth/8(aCnt)    *
1519      *     b) these arrays are located apart lengthofloopjob size (bindex)    *
1520      *     c) there are 'no.of.slots' no. of such arrays  (bCnt)              *
1521      *     d) (a) and (b) constitute one frame of EDMA transfer and it        *
1522      *        happens for one sync event in AB sync mode                      *
1523      *     e) such frames have to be sent till we have buffer - ie            *
1524      *        lengthofloopjob / (roundedwordwidth/8 )  and this               *
1525      *        constitutes  cCnt                                               *
1526      *     f) address of buffer (rather offset from start of previous         *
1527      *         frame) is roundedwordwidth/8 and this forms cIndex             *
1528      *  Please take some time to visualise the setup mentioned above to       *
1529      *  check with EDMA configuration The same kind of setup will be used     *
1530      *  for data transfers also and the change will be buffer pointer         *
1531      *  and length of data buffer.                                            */
1533     /* Get the PaRAM set for default parameters                               */
1534     EDMA3_DRV_getPaRAM(chanHandle->edmaHandle,chanHandle->xferChan,&paramSet);
1536     if (MCBSP_MODE_INPUT == chanHandle->mode)
1537     {
1538         /* Configuring Source and Dest addresses                              */
1539         if (TRUE == chanHandle->enableHwFifo)
1540         {
1541             paramSet.srcAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
1542         }
1543         else
1544         {
1545             paramSet.srcAddr = (uint32_t)&(instHandle->hwInfo.regs->DRR);
1546         }
1548 #ifdef _BIG_ENDIAN
1549         paramSet.srcAddr += (4 - chanHandle->roundedWordWidth);
1550 #endif
1551         /* Configuring Src and Dest B&C Indexes                               */
1552         paramSet.srcBIdx  = 0;
1553         paramSet.srcCIdx  = 0;
1555         if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
1556                                  chanHandle,
1557                                  &paramSet.destBIdx,
1558                                  &paramSet.destCIdx,
1559                                  &paramSet.aCnt,
1560                                  &paramSet.bCnt,
1561                                  &paramSet.cCnt,
1562                                  &tempSyncType,
1563                                  TRUE))
1564         {
1565             status = MCBSP_ERR_BADARGS;
1566         }
1567     }
1568     else
1569     {
1570         /* Configuring Source and Dest addresses                              */
1571         if (TRUE == chanHandle->enableHwFifo)
1572         {
1573             paramSet.destAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
1574         }
1575         else
1576         {
1577             paramSet.destAddr = (uint32_t)&(instHandle->hwInfo.regs->DXR);
1578         }
1579 #ifdef _BIG_ENDIAN
1580         paramSet.destAddr += (4 - chanHandle->roundedWordWidth);
1581 #endif
1582         /* Configuring Src and Dest B&C Indexes                               */
1583         paramSet.destBIdx = 0;
1584         paramSet.destCIdx = 0;
1586         if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
1587                                  chanHandle,
1588                                  &paramSet.srcBIdx,
1589                                  &paramSet.srcCIdx,
1590                                  &paramSet.aCnt,
1591                                  &paramSet.bCnt,
1592                                  &paramSet.cCnt,
1593                                  &tempSyncType,
1594                                  TRUE))
1595         {
1596             status = MCBSP_ERR_BADARGS;
1597         }
1598     }
1600     /* Configuring bCntReload                                                 */
1601     paramSet.bCntReload = paramSet.bCnt;
1603     /* Src & Dest are in INCR modes                                           */
1604     paramSet.opt &= 0xFFFFFFFCu;
1606     /* FIFO width is 8 bit                                                    */
1607     paramSet.opt &= 0xFFFFF8FFu;
1609     /* Set EDMA3_DRV_OPT_FIELD_TCINTEN to FALSE                               */
1610     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_ITCINTEN_MASK));
1612     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_TCINTEN_MASK));
1613     paramSet.opt |= (CSL_TPCC_PARAM_OPT_TCINTEN_DISABLE
1614                         << CSL_TPCC_PARAM_OPT_TCINTEN_SHIFT);
1616     /* Program the TCC                                                        */
1617     paramSet.opt |= ((chanHandle->tcc << CSL_TPCC_PARAM_OPT_TCC_SHIFT)
1618                       & CSL_TPCC_PARAM_OPT_TCC_MASK);
1620     /* EDMA3_DRV_SYNC_AB                                                      */
1621     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_SYNCDIM_MASK));
1622     paramSet.opt |= (tempSyncType << CSL_TPCC_PARAM_OPT_SYNCDIM_SHIFT);
1624     /* early completion interrupt is enabled                                  */
1625     paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_TCCMOD_MASK));
1626     paramSet.opt |= (1 << CSL_TPCC_PARAM_OPT_TCCMOD_SHIFT);
1628     /* Now, write the PaRAM Set.                                              */
1629     status = EDMA3_DRV_setPaRAM(
1630                   chanHandle->edmaHandle,
1631                   chanHandle->xferChan,
1632                   &paramSet);
1634     if (MCBSP_STATUS_COMPLETED == status)
1635     {
1636         /* Configure the link PaRAMs with the appropriate parameters Though   *
1637          * we configure all the link paramsets, we will be using only one of  *
1638          * them to link with main xfer channel                                */
1639         for (linkCnt = 0; linkCnt < Mcbsp_MAXLINKCNT; linkCnt++)
1640         {
1641             /* Get the PaRAM set for default parameters                       */
1642             EDMA3_DRV_getPaRAM (chanHandle->edmaHandle,
1643                                 chanHandle->pramTbl[linkCnt],
1644                                 &paramSet);
1646             if (MCBSP_MODE_INPUT == chanHandle->mode)
1647             {
1648                 /* Configuring Source and Dest addresses                      */
1649                 if (TRUE == chanHandle->enableHwFifo)
1650                 {
1651                     paramSet.srcAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
1652                 }
1653                 else
1654                 {
1655                     paramSet.srcAddr = (uint32_t)&(instHandle->hwInfo.regs->DRR);
1656                 }
1657 #ifdef _BIG_ENDIAN
1658                 paramSet.srcAddr += (4 - chanHandle->roundedWordWidth);
1659 #endif
1660                 /* Configuring Src and Dest B&C Indexes                       */
1661                 paramSet.srcBIdx  = 0;
1662                 paramSet.srcCIdx  = 0;
1664                 if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
1665                                          chanHandle,
1666                                          &paramSet.destBIdx,
1667                                          &paramSet.destCIdx,
1668                                          &paramSet.aCnt,
1669                                          &paramSet.bCnt,
1670                                          &paramSet.cCnt,
1671                                          &tempSyncType,
1672                                          TRUE))
1673                 {
1674                     status = MCBSP_ERR_BADARGS;
1675                 }
1676             }
1677             else
1678             {
1679                 /* Configuring Source and Dest addresses                      */
1680                 if (TRUE == chanHandle->enableHwFifo)
1681                 {
1682                     paramSet.destAddr = (uint32_t)(instHandle->hwInfo.dataAddress);
1683                 }
1684                 else
1685                 {
1686                     paramSet.destAddr = (uint32_t)&(instHandle->hwInfo.regs->DXR);
1687                 }
1688 #ifdef _BIG_ENDIAN
1689                 paramSet.destAddr += (4 - chanHandle->roundedWordWidth);
1690 #endif
1691                 paramSet.destBIdx  = 0;
1692                 paramSet.destCIdx  = 0;
1694                 if (MCBSP_STATUS_COMPLETED != Mcbsp_localGetIndicesSyncType(
1695                                          chanHandle,
1696                                          &paramSet.srcBIdx,
1697                                          &paramSet.srcCIdx,
1698                                          &paramSet.aCnt,
1699                                          &paramSet.bCnt,
1700                                          &paramSet.cCnt,
1701                                          &tempSyncType,
1702                                          TRUE))
1703                 {
1704                     status = MCBSP_ERR_BADARGS;
1705                 }
1706             }
1708             /* Configuring bCntReload                                         */
1709             paramSet.bCntReload = paramSet.bCnt;
1711             /* Src & Dest are in INCR modes                                   */
1712             paramSet.opt &= 0xFFFFFFFCu;
1714             /* FIFO width is 8 bit                                            */
1715             paramSet.opt &= 0xFFFFF8FFu;
1717             /* EDMA3_DRV_SYNC_AB                                              */
1718             paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_SYNCDIM_MASK));
1719             paramSet.opt |= (tempSyncType << CSL_TPCC_PARAM_OPT_SYNCDIM_SHIFT);
1721             /* Set EDMA3_DRV_OPT_FIELD_TCINTEN to FALSE                       */
1722             paramSet.opt |= (CSL_TPCC_PARAM_OPT_TCINTEN_DISABLE
1723                                 << CSL_TPCC_PARAM_OPT_TCINTEN_SHIFT);
1725             /* Program the TCC                                                */
1726             paramSet.opt |= ((chanHandle->tcc << CSL_TPCC_PARAM_OPT_TCC_SHIFT)
1727                               & CSL_TPCC_PARAM_OPT_TCC_MASK);
1729             /* early completion interrupt                                     */
1730             paramSet.opt &= (~(CSL_TPCC_PARAM_OPT_TCCMOD_MASK));
1731             paramSet.opt |= (1 << CSL_TPCC_PARAM_OPT_TCCMOD_SHIFT);
1733             if (MCBSP_STATUS_COMPLETED == status)
1734             {
1735                 /* Now, write the PaRAM Set.                                  */
1736                 status = EDMA3_DRV_setPaRAM(chanHandle->edmaHandle,
1737                                             chanHandle->pramTbl[linkCnt],
1738                                             &paramSet);
1739             }
1740         }/*for loop for linkcount*/
1741     }
1742     return (status);
1744 #endif /* #ifdef MCBSP_LOOPJOB_ENABLE */
1746 /**
1747  * \brief  This checks is the next request in queue is data request. If this is
1748  *         an abort request, it calls the appropriate function to deal
1749  *         with it.
1750  *
1751  * \param  chanHandle   [IN]  Handle to the Mcbsp Channel
1752  *
1753  * \return Mcbsp_STATUS_INVALID,if no outstanding requests
1754  *         Mcbsp_STATUS_VALID, if pending buffer is there
1755  *
1756  */
1757 int32_t mcbspIsValidIOBuf(Mcbsp_ChannelObj *chanHandle)
1759     int32_t          status     = Mcbsp_STATUS_INVALID;
1761     if ((NULL == chanHandle) || (NULL == chanHandle->devHandle))
1762     {
1763         return MCBSP_ERR_BADARGS;
1764     }
1766     /* check if the queue has any request to be processed                     */
1767     if (FALSE == Mcbsp_osalQueueEmpty(chanHandle->ptrQPendList))
1768     {
1769         chanHandle->dataIOBuf = Mcbsp_osalQueueGet(chanHandle->ptrQPendList);
1771         if (NULL != chanHandle->dataIOBuf)
1772         {
1773             /* we have a valid buffer to process next                         */
1774             chanHandle->currentDataSize =
1775                 (uint16_t)(chanHandle->dataIOBuf->size);
1776             chanHandle->userDataBufferSize =
1777                 (uint32_t)(chanHandle->dataIOBuf->size);
1779             /* Additional to assigning the important parameters as above      *
1780              * for DMA mode , we will have max 2 buffers floating and hence   *
1781              * we use a activequue to manage this                             */
1782             Mcbsp_osalQueuePut(chanHandle->ptrQFloatList, (void*)chanHandle->dataIOBuf);
1784             /* Set the status as valid                                        */
1785             status = Mcbsp_STATUS_VALID;
1786         }
1787     }
1788     else
1789     {
1790         /* we dont have any buffer in queue stop xmt/rcv SM before giving     *
1791          * error                                                              */
1792         chanHandle->dataIOBuf = NULL;
1794         /* Set the status as invalid to program the loopjob buffer            */
1795         status = Mcbsp_STATUS_INVALID;
1796     }
1797     return status;
1800 /**
1801  * \brief   Process the buffer and update the EDMA paramset
1802  *
1803  *          For the transmit operation, the eDMA channel's destination
1804  *          port is tied to the MCBSP DAT port. In case of receive, the eDMA
1805  *          channel's source port is tied to the MCBSP DAT port. The source
1806  *          address for transmit eDMA channel and the destination address for
1807  *          the receive eDMA channel are set here.
1808  *
1809  * \param  chanHandle [IN]    Pointer to channel
1810  * \param  ioBuf      [IN]    Pointer to request to be processed
1811  *
1812  * \return  MCBSP_STATUS_COMPLETED, if the address is set correctly
1813  *          MCBSP_ERR_BADIO otherwise
1814  */
1815 int32_t Mcbsp_localEdmaProcessPkt(Mcbsp_ChannelObj *chanHandle,
1816                                 Mcbsp_IOBuf       *ioBuf)
1818     int32_t   status = MCBSP_STATUS_COMPLETED;
1820     if ((NULL == chanHandle) || (NULL == ioBuf))
1821     {
1822         return MCBSP_ERR_BADARGS;
1823     }
1825     /* we are going to update the paramset from EDMA callback context. That   *
1826      * means the one of the param sets are having audio data just completed   *
1827      * data request and one having currently loaded (active) data request     *
1828      * Current index is pointing only latest paramset (that is active)  so    *
1829      * move the index                                                         */
1830     Mcbsp_localGetNextIndex(&chanHandle->nextLinkParamSetToBeUpdated);
1832     /* update the edma paramset with the buffer details                       */
1833     status = Mcbsp_localUpdtDtPktToLnkPrms(chanHandle, ioBuf);
1835     return (status);
1838 /**
1839  *  \brief  Mcbsp_localGetIndicesSyncType
1840  *
1841  *  This function computes the parameters requied to configure EDMA 3 based
1842  *  on the buffer format seleted while creating the driver.
1843  *
1844  *  Entry Criteria : This function expects channel variables such as no of slots
1845  *                   length of buffers is updated.
1846  *
1847  *  \param    chanHandle       [IN]    Pointer to channel handle
1848  *  \param    bIndex           [IN]    Pointer to stores computed bIndex
1849  *  \param    cIndex           [IN]    Pointer to stores computed cIndex
1850  *  \param    aCnt             [IN]    Pointer to stores computed aCnt
1851  *  \param    bCnt             [IN]    Pointer to stores computed bCnt
1852  *  \param    cCnt             [IN]    Pointer to stores computed cCnt
1853  *  \param    syncType         [IN]    Pointer to stores computed mode of EDMA
1854  *  \param    forLoopJobBuf    [IN]    To calucalate above for loopJob or data
1855  *
1856  *  CAUTION:  This function could be called with pointer pointing to EDMA 3
1857  *            paramset pointer (avoiding couple of variables). Care should be
1858  *            take to ensure that data types used in EDMA 3 paramset is
1859  *            consistent with EDMA 3 defined data types.
1860  *
1861  *  \return   MCBSP_ERR_BADARGS on invalid buffer format, else MCBSP_STATUS_COMPLETED
1862  */
1863 int32_t Mcbsp_localGetIndicesSyncType(Mcbsp_ChannelObj   *chanHandle,
1864                                     volatile int16_t     *bIndex,
1865                                     volatile int16_t     *cIndex,
1866                                     volatile uint16_t    *aCnt,
1867                                     volatile uint16_t    *bCnt,
1868                                     volatile uint16_t    *cCnt,
1869                                     EDMA3_DRV_SyncType *syncType,
1870                                     Bool                forLoopJobBuf)
1872     uint32_t  tempSize  = 0x0;
1873     int32_t   status    = MCBSP_STATUS_COMPLETED;
1875     if(((NULL == chanHandle) || (NULL == bIndex) || (NULL == cIndex)
1876                     || (NULL == aCnt) || (NULL == bCnt) || (NULL == cCnt)
1877                     || (NULL == syncType)))
1878     {
1879         return MCBSP_ERR_BADARGS;
1880     }
1882     /* Get the size of the buffer to be used. In case of mute command and     *
1883      * normal IOP we will use the actual size of the buffer. For the loop job *
1884      * case 1. if internal loop job then the minimum loop job length will be  *
1885      *         used.                                                          *
1886      * case 2. user supplied loop job buffer then the user loop job length    *
1887      *         will be used.                                                  */
1888     if ((TRUE == forLoopJobBuf) && (FALSE == chanHandle->bMuteON))
1889     {
1890         if (TRUE == chanHandle->userLoopJob)
1891         {
1892             /* use the user supplied buffer length for the EDMA params        */
1893             tempSize = chanHandle->userLoopJobLength;
1894         }
1895         else
1896         {
1897             tempSize = chanHandle->loopJobLength;
1898         }
1899     }
1900     else
1901     {
1902         tempSize = chanHandle->userDataBufferSize;
1903     }
1905     /* Get the indices                                                        */
1906     switch (chanHandle->dataFormat)
1907     {
1908         case Mcbsp_BufferFormat_1SLOT:
1909         case Mcbsp_BufferFormat_MULTISLOT_INTERLEAVED:
1910             *aCnt = chanHandle->roundedWordWidth;
1911             *bCnt = 1u;
1912             *cCnt = (uint16_t)(tempSize/(*aCnt));
1913             *bIndex = (int16_t)tempSize;
1914             *cIndex = (int16_t)(*aCnt);
1915             *syncType = EDMA3_DRV_SYNC_AB;
1916             break;
1917         case Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED:
1918             *aCnt = chanHandle->roundedWordWidth;
1919             *bCnt = (uint16_t)(chanHandle->numEnabledChannels);
1921             /* temp Size is always a multiple of the acnt hence the division  *
1922              * result will always be an integer                               */
1923             *cCnt = (uint16_t)(tempSize /((*aCnt) * (*bCnt)));
1924             /* temp Size is always a multiple of the bcnt when using the      *
1925              * multiple slots hence the result will be always an integer      */
1926             *bIndex = (int16_t)(tempSize/(*bCnt));
1927             *cIndex = (int16_t)((*aCnt) - (((*bCnt)- 1u) * (tempSize/(*bCnt))));
1928             *syncType = EDMA3_DRV_SYNC_A;
1929             break;
1930         default:
1931             status = MCBSP_ERR_BADARGS;
1932                break;
1933     }
1935     /* if the loop job buffer being used is the driver internal loop job      *
1936      * buffer, dont increment the index for it.Same is the case if mute is ON */
1937     if (TRUE == forLoopJobBuf)
1938     {
1939         if ((TRUE == chanHandle->bMuteON) ||
1940             (FALSE == chanHandle->userLoopJob))
1941         {
1942             *bIndex = 0;
1943             *cIndex = 0;
1944         }
1945     }
1946     return status;
1949 /* ========================================================================== */
1950 /*                              END OF FILE                                   */
1951 /* ========================================================================== */